registry  /  cladding  /  0.8.1

cladding@0.8.1

Reference implementation of the Ironclad standard — multi-agent dev harness for Claude Code.

AI Security Review

scanned 8d ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. The package exposes a first-party AI host integration setup command that can install hooks, skills, symlinks, and MCP config entries. This is package-aligned and explicit, but it changes AI-agent control surfaces when run.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs `clad setup` or `clad update`; Claude hook execution triggers after plugin activation.
Impact
AI host config and hooks may run cladding commands during host lifecycle events; no install-time hijack or exfiltration confirmed.
Mechanism
explicit first-party agent extension wiring
Rationale
Source inspection shows real agent-extension lifecycle risk from explicit host setup, but no unconsented install-time mutation, stealth persistence, destructive behavior, credential harvesting, or remote payload execution. Under the stated policy this should warn rather than block.
Evidence
package.jsonbin/claddist/src/init/host-setup.jsdist/src/cli/clad.jsdist/src/cli/hook.jsplugins/claude-code/hooks/hooks.jsondist/src/cli/scan/dispatcher.jsdist/src/adapters/sdk/anthropic.js~/.claude/plugins/cladding~/.gemini/extensions/cladding~/.agents/skills/cladding-*~/.codex/config.toml~/.cursor/mcp.json~/.cladding/setup-status.json
Network endpoints3
api.openai.com/v1/chat/completionsgenerativelanguage.googleapis.com/v1beta/models/<model>:generateContentgithub.com/qwerfunch/cladding

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/src/init/host-setup.js explicit `clad setup` wires Claude/Gemini/Codex/Cursor host integrations under user home.
  • dist/src/init/host-setup.js can write ~/.codex/config.toml and ~/.cursor/mcp.json and symlink ~/.claude/plugins/cladding and ~/.agents/skills/cladding-* when invoked.
  • plugins/claude-code/hooks/hooks.json registers Claude lifecycle hooks that execute `node ${CLAUDE_PLUGIN_ROOT}/dist/clad.js hook ...`.
  • dist/src/init/host-setup.js attempts non-interactive `claude plugin ...` and `gemini extensions link ...` activation after explicit setup.
Evidence against
  • package.json has no preinstall/install/postinstall; prepare only builds if dist/clad.js is absent.
  • bin/clad only imports bundled dist/clad.js, falling back to `npx tsx` for development when dist is missing.
  • Host config mutation is behind explicit `clad setup`/`clad update`, not npm install-time execution.
  • dist/src/cli/scan/dispatcher.js and dist/src/adapters/sdk/anthropic.js use user-provided AI API keys for opt-in model dispatch, not harvesting/exfiltration.
  • Scanner eval/secret/child_process hits are mostly tests, toolchain gates, git probes, or bundled dependencies.
  • No hidden payload URL, credential collection loop, destructive action, or remote code loader confirmed in inspected source.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareUrlStrings
ManifestNo manifest risk signals triggered.
scanned 397 file(s), 6.02 MB of source, external domains: api.anthropic.com, api.openai.com, doc.rust-lang.org, docs.anthropic.com, docs.expo.dev, example.com, generativelanguage.googleapis.com, github.com, go.dev, google.github.io, jcgt.org, json-schema.org, json.schemastore.org, kotlinlang.org, peps.python.org, platform.claude.com, raw.githubusercontent.com, rubystyle.guide, www.w3.org

Source & flagged code

13 flagged · loading source
dist/tests/stages/util.test.jsView file
88patternName = aws_access_key severity = critical line = 88 matchedText = const ou...ed);
Critical
Critical Secret

Package contains a critical-looking secret pattern.

dist/tests/stages/util.test.jsView on unpkg · L88
88patternName = aws_access_key severity = critical line = 88 matchedText = const ou...ed);
Critical
Secret Pattern

AWS access key ID in dist/tests/stages/util.test.js

dist/tests/stages/util.test.jsView on unpkg · L88
dist/tests/core/checkpoint.test.jsView file
16// that need a no-git path run inside a tmpdir. L17: import { execFileSync } from 'node:child_process'; L18: import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
High
Child Process

Package source references child process execution.

dist/tests/core/checkpoint.test.jsView on unpkg · L16
dist/src/stages/type.jsView file
11import process from 'node:process'; L12: import { execaSync } from 'execa'; L13: import { resolveStageCommand } from './toolchain/scoped-command.js';
High
Shell

Package source references shell execution.

dist/src/stages/type.jsView on unpkg · L11
dist/tests/stages/ai-hints-forbidden-pattern.test.jsView file
22writeMinimalSpec(dir); L23: writeSrc(dir, 'a.ts', 'export const x = eval("1+1");\n'); L24: expect(aiHintsForbiddenPattern.run({ cwd: dir })).toEqual([]);
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/tests/stages/ai-hints-forbidden-pattern.test.jsView on unpkg · L22
dist/tests/optimizer/infer-depends-on.test.jsView file
124describe('JS/TS extraction', () => { L125: test('import…from, side-effect import, and require() all resolve owned edges', () => { L126: const spec = makeSpec([
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/tests/optimizer/infer-depends-on.test.jsView on unpkg · L124
dist/clad.jsView file
710`)}function pCe(t,e){let r=[OY,"",`# ${e} \u2014 Project Context`,""];if(r.push("## 1. What this project is (observed)",""),t.readmeFirstParagraph?r.push(`> ${t.readmeFirstParagrap... L711: `)}$p();import{readFileSync as pFe}from"node:fs";import{join as mFe}from"node:path";var hFe="claude-sonnet-4-6",Pw=16384;function gFe(t,e="."){if(t)return t;try{let n=pFe(mFe(e,".c... L712: `)}function hm(t){let e=E7(t);return["# Cladding \xB7 Tier B \xB7 SSoT \u2014 editable, cross-validated \xB7 Refreshed by: clad init / clad clarify","# Greenfield seed \u2014 no im... ... L714: `)}var nN=At(sr(),1);Jr();var T7="<!-- Cladding \xB7 Tier B \xB7 SSoT \u2014 intent + Why/What/Purpose \xB7 Refreshed by: clad init / clad clarify -->\n<!-- Onboarding refined from... L715: <!-- LLM unavailable or response sentinel-miss; the body below quotes your intent verbatim. Re-run with a connected LLM dispatcher to capture inferred domain context. -->`;function... L716: `)}function R7(t){return{mode:hs(t,"ONBOARDING_MODE"),projectContext:hs(t,"PROJECT_CONTEXT_MD"),capabilities:hs(t,"CAPABILITIES_YAML"),architecture:hs(t,"ARCHITECTURE_YAML"),specSe...
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/clad.jsView on unpkg · L710
417L418: `)}p.write("payload.value = newResult;"),p.write("return payload;");let _=p.compile();return(S,x)=>_(f,S,x)},o,s=ac,a=!oc.jitless,l=a&&QN.value,u=e.catchall,d;t._zod.parse=(f,p)=>{... L419: L420: Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`)}for(let s of t.seen.entries()){let a=s[1];if(e===s[0]){o(s);continue}if(t.external){let l=t.exter... L421: ]))`;continue}else if(n[c]==="$"){i+=`($|(?=[\r ... L427: || (${s} === "string" && ${i} && ${i} == +${i} && !(${i} % 1))`).assign(a,(0,_e._)`+${i}`);return;case"boolean":n.elseIf((0,_e._)`${i} === "false" || ${i} === 0 || ${i} === null`).... L428: || ${s} === "boolean" || ${i} === null`).assign(a,(0,_e._)`[${i}]`)}}}function dBe({gen:t,parentData:e,parentDataProperty:r},n){t.if((0,_e._)`${e} !== undefined`,()=>t.assign((0,_e... L429: missingProperty: ${n}, L430: depsCount: ${e}, L431: deps: ${r}}`};var HGe={keyword:"dependencies",type:"object",schemaType:"object",error:Wi.error,code(t){let[e,r]=ZGe(t);Oae(t,e),Tae(t,r)}};function ZGe({schema:t}){let e={},r={};fo... L432: `);let n=r??t,i=AVe(n,e),o=Lce.get(i);if(o)return o;if(!zce(i))throw new Error(`agents/${n}.md not found at ${i}`);let s
High
Command Output Exfiltration

Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.

dist/clad.jsView on unpkg · L417
6globalThis.__CLADDING_BUNDLED = true; L7: var jle=Object.create;var TE=Object.defineProperty;var Mle=Object.getOwnPropertyDescriptor;var Fle=Object.getOwnPropertyNames;var Lle=Object.getPrototypeOf,zle=Object.prototype.has... L8: `)}displayWidth(e){return VU(e).length}styleTitle(e){return e}styleUsage(e){return e.split(" ").map(r=>r==="[options]"?this.styleOptionText(r):r==="[command]"?this.styleSubcommandT... ... L18: (Did you mean one of ${n.join(", ")}?)`:n.length===1?` L19: (Did you mean ${n[0]}?)`:""}KU.suggestSimilar=Wle});var eq=v(ZE=>{var Kle=Be("node:events").EventEmitter,UE=Be("node:child_process"),Qi=Be("node:path"),jg=Be("node:fs"),Ue=Be("node... L20: - specify the name in Command constructor or using .name()`);return r=r||{},r.isDefault&&(this._defaultCommandName=e._name),(r.noHelp||r.hidden)&&(e._hidden=!0),this._registerComma... ... L81: `;return`${m} L82: ${i}${p}`}else return`${f}${s}${d.join(" ")}${s}${p}`}function oy({indent:t,options:{commentString:e}},r,n,i){if(n&&i&&(n=n.replace(/^\n+/,"")),n){let o=iy.indentComment(e(n),t);r.... L83: `:" ")}return Wde.stringifyString({comment:t,type:e,value:a},n,i,o)}};f4.binary=Kde});var gy=v(hy=>{"use strict";var my=Pe(
High
Obfuscated Payload Loader

Source contains an obfuscator-style string-array loader that reconstructs and executes hidden code.

dist/clad.jsView on unpkg · L6
6Cross-file remote execution chain: dist/clad.js spawns dist/viewer/app.js; helper contains network access plus dynamic code execution. L6: globalThis.__CLADDING_BUNDLED = true; L7: var jle=Object.create;var TE=Object.defineProperty;var Mle=Object.getOwnPropertyDescriptor;var Fle=Object.getOwnPropertyNames;var Lle=Object.getPrototypeOf,zle=Object.prototype.has... L8: `)}displayWidth(e){return VU(e).length}styleTitle(e){return e}styleUsage(e){return e.split(" ").map(r=>r==="[options]"?this.styleOptionText(r):r==="[command]"?this.styleSubcommandT... ... L18: (Did you mean one of ${n.join(", ")}?)`:n.length===1?` L19: (Did you mean ${n[0]}?)`:""}KU.suggestSimilar=Wle});var eq=v(ZE=>{var Kle=Be("node:events").EventEmitter,UE=Be("node:child_process"),Qi=Be("node:path"),jg=Be("node:fs"),Ue=Be("node... L20: - specify the name in Command constructor or using .name()`);return r=r||{},r.isDefault&&(this._defaultCommandName=e._name),(r.noHelp||r.hidden)&&(e._hidden=!0),this._registerComma... ... L81: `;return`${m} L82: ${i}${p}`}else return`${f}${s}${d.join(" ")}${s}${p}`}function oy({indent:t,options:{commentString:e}},r,n,i){if(n&&i&&(n=n.replace(/^\n+/,"")),n){let o=iy.indentComment(e(n),t…
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist/clad.jsView on unpkg · L6
dist/tests/cli/graph-export-pipe.test.jsView file
19test('--format json over a pipe arrives complete and parseable', () => { L20: const out = execFileSync('npx', ['tsx', 'src/cli/clad.ts', 'graph', 'export', '--format', 'json'], { L21: cwd: REPO,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/tests/cli/graph-export-pipe.test.jsView on unpkg · L19
dist/src/cli/doctor-hosts.jsView file
matchType = previous_version_dangerous_delta matchedPackage = cladding@0.8.0 matchedIdentity = npm:Y2xhZGRpbmc:0.8.0 similarity = 0.667 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

dist/src/cli/doctor-hosts.jsView on unpkg
dist/conformance/runner.jsView file
252patternName = stripe_live_secret severity = critical line = 252 matchedText = writeFil...n');
Critical
Secret Pattern

Stripe live secret key in dist/conformance/runner.js

dist/conformance/runner.jsView on unpkg · L252

Findings

4 Critical7 High5 Medium7 Low
CriticalCritical Secretdist/tests/stages/util.test.js
CriticalPrevious Version Dangerous Deltadist/src/cli/doctor-hosts.js
CriticalSecret Patterndist/tests/stages/util.test.js
CriticalSecret Patterndist/conformance/runner.js
HighChild Processdist/tests/core/checkpoint.test.js
HighShelldist/src/stages/type.js
HighSame File Env Network Executiondist/clad.js
HighCommand Output Exfiltrationdist/clad.js
HighObfuscated Payload Loaderdist/clad.js
HighCross File Remote Execution Contextdist/clad.js
HighRuntime Package Installdist/tests/cli/graph-export-pipe.test.js
MediumDynamic Requiredist/tests/optimizer/infer-depends-on.test.js
MediumNetwork
MediumEnvironment Vars
MediumProtestware
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowEvaldist/tests/stages/ai-hints-forbidden-pattern.test.js
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings