registry  /  substrate-ai  /  0.20.144

substrate-ai@0.20.144

Substrate — multi-agent orchestration daemon for AI coding agents

AI Security Review

scanned 2h ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs `substrate init`, `substrate factory run --backend direct`, `substrate run`, or `substrate upgrade`.
Impact
Remote provider-directed tool calls can read/write project files and execute shell commands within the configured project; init mutates agent guidance files.
Mechanism
explicit user-invoked AI agent orchestration and agent config scaffolding
Rationale
The dangerous primitives are real but user-invoked and package-aligned, with no lifecycle hook or covert payload. Warn for explicit agent control-surface mutation and remote agent tool capability, but do not publish-block as malicious.
Evidence
package.jsondist/run-CUcRdKFK.jsdist/cli/index.jsdist/cli/templates/agents-md-substrate-section.mddist/cli/templates/claude-md-substrate-section.mddist/upgrade-DB7KzD9c.jsAGENTS.mdCLAUDE.mdGEMINI.md.claude/settings.json.claude/statusline.sh.codex/prompts//.codex/skills/~/.codex/prompts/substrate-*~/.codex/skills/substrate-*.substrate/config.yaml.substrate/routing-policy.yaml.gitignore
Network endpoints3
api.anthropic.com/v1/messagesapi.openai.com/v1/responsesgenerativelanguage.googleapis.com

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/run-CUcRdKFK.js defines a direct LLM backend that sends prompts/tools to api.anthropic.com, api.openai.com, or generativelanguage.googleapis.com.
  • dist/run-CUcRdKFK.js exposes read_file/write_file/shell/grep/glob/edit/apply_patch tools to the configured remote model when direct backend is enabled.
  • dist/cli/index.js `substrate init` writes AGENTS.md, CLAUDE.md, GEMINI.md, .claude/settings.json, .codex prompts/skills; optional --install-user-scope writes ~/.codex substrate-* content.
  • dist/cli/templates/claude-md-substrate-section.md tells Claude to run substrate without exploring source, an agent steering surface mutation.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle hooks.
  • Agent/control-surface writes are under explicit `substrate init`, not npm install/import time.
  • Codex user-scope writes are namespaced substrate-* and require --install-user-scope; stale pruning is prefix-limited.
  • Network endpoints are major LLM provider APIs or npm registry update checks, aligned with an AI orchestration CLI.
  • No evidence of credential harvesting beyond reading configured provider API keys from env for intended API calls.
  • Upgrade `npm install substrate@version` is an explicit upgrade command with prompt/--yes, not hidden runtime install.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 30 file(s), 2.83 MB of source, external domains: ai.google.dev, api.anthropic.com, api.openai.com, claude.ai, docs.dolthub.com, generativelanguage.googleapis.com, git-scm.com, github.com, json-schema.org, json.schemastore.org, raw.githubusercontent.com, registry.npmjs.org

Source & flagged code

9 flagged · loading source
dist/run-CUcRdKFK.jsView file
matchType = previous_version_dangerous_delta matchedPackage = substrate-ai@0.20.148 matchedIdentity = npm:c3Vic3RyYXRlLWFp:0.20.148 similarity = 0.962 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/run-CUcRdKFK.jsView on unpkg
16import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs... L17: import { exec, execFile, execFileSync, execSync, spawn } from "node:child_process"; L18: import * as path$5 from "node:path";
High
Child Process

Package source references child process execution.

dist/run-CUcRdKFK.jsView on unpkg · L16
37761cwd, L37762: shell: true L37763: });
High
Shell

Package source references shell execution.

dist/run-CUcRdKFK.jsView on unpkg · L37761
16import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, unwatchFile, watchFile, writeFileSync } from "node:fs... L17: import { exec, execFile, execFileSync, execSync, spawn } from "node:child_process"; L18: import * as path$5 from "node:path"; ... L5782: if (existsSync(profilePath)) try { L5783: const raw = readFileSync(profilePath, "utf-8"); L5784: const parsed = yaml.load(raw); ... L35989: apiKey; L35990: baseUrl; L35991: anthropicVersion; ... L37397: "", L37398: "Available tools:", L37399: "- read_file: Read file contents with optional line range (offset/limit)",
High
Remote Agent Bridge

Source exposes local file and command tools to a remote model endpoint.

dist/run-CUcRdKFK.jsView on unpkg · L16
15901try { L15902: execSync(`npm install ${missingPkg}`, { L15903: cwd: resolvedRoot,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/run-CUcRdKFK.jsView on unpkg · L15901
31950try { L31951: var makeValidate = new Function("self", "RULES", "formats", "root", "refVal", "defaults", "customRules", "equal", "ucs2length", "ValidationError", sourceCode); L31952: validate$1 = makeValidate(self, RULES, formats$2, root, refVal, defaults$2, customRules, equal, ucs2length, ValidationError);
Low
Eval

Package source references a known benign dynamic code generation pattern.

dist/run-CUcRdKFK.jsView on unpkg · L31950
dist/cli/index.jsView file
1501try { L1502: const _require = createRequire(join(fromDir, "synthetic.js")); L1503: const pkgJsonPath = _require.resolve("bmad-method/package.json");
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/cli/index.jsView on unpkg · L1501
dist/dist-DiNK6QOD.jsView file
3package = substrate-ai; repositoryIdentity = substrate; dependency = js-yaml L3: import { EventEmitter } from "node:events"; L4: import yaml, { dump, load } from "js-yaml"; L5: import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
High
Copied Package Dependency Bridge

Package metadata claims a different repository identity while copied source loads a runtime dependency bridge.

dist/dist-DiNK6QOD.jsView on unpkg · L3
dist/cli/templates/statusline.shView file
path = dist/cli/templates/statusline.sh kind = build_helper sizeBytes = 565 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

dist/cli/templates/statusline.shView on unpkg

Findings

1 Critical5 High5 Medium5 Low
CriticalPrevious Version Dangerous Deltadist/run-CUcRdKFK.js
HighChild Processdist/run-CUcRdKFK.js
HighShelldist/run-CUcRdKFK.js
HighRemote Agent Bridgedist/run-CUcRdKFK.js
HighCopied Package Dependency Bridgedist/dist-DiNK6QOD.js
HighRuntime Package Installdist/run-CUcRdKFK.js
MediumDynamic Requiredist/cli/index.js
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperdist/cli/templates/statusline.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowEvaldist/run-CUcRdKFK.js
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings