registry  /  peaks-loop  /  3.0.1

peaks-loop@3.0.1

Loop Engineering CLI — workflow primitive / loop guards / evaluators / slice orchestration

AI Security Review

scanned 21h ago · by lpm-firewall-ai

Install-time lifecycle mutates AI-agent control surfaces by linking/copying package-supplied skills, output styles, and agent prompts into user IDE/agent directories. This occurs automatically on npm install unless environment opt-outs are set.

Static reason
High-risk behavior combination matched malicious policy.; source matched previously finalized malicious package; routed for review
Trigger
npm install/postinstall
Impact
Package-supplied instructions can be loaded by AI coding agents after installation, changing agent behavior outside the installed package directory.
Mechanism
unconsented AI-agent skill and sub-agent prompt installation
Attack narrative
On install, the package runs scripts/install-skills.mjs. That script fans out across multiple AI IDE/agent profiles and places package-controlled skill directories, output styles, and Claude sub-agent prompts into user-global loader locations, plus writes Peaks config and may invoke a project upgrade command. Even without network exfiltration, this is an install-time mutation of AI-agent control surfaces outside the package.
Rationale
The confirmed postinstall behavior crosses the firewall boundary: it automatically writes package-supplied AI-agent instructions into user-global agent loader directories. That is concrete unconsented lifecycle control-surface mutation, so the package should be blocked despite package-aligned intent and absence of exfiltration. Product guard normalized a concrete AI-agent control hijack publish_block to the blockable dangerous-capability shape.
Evidence
package.jsonscripts/install-skills.mjsagents/karpathy-reviewer.mdskills/peaks-solo/SKILL.mddist/src/services/upgrade/upgrade-service.js~/.claude/skills/*~/.claude/output-styles/*~/.claude/agents/*.md~/.codex/skills/*~/.codex/output-styles/*~/.cursor/skills/*~/.cursor/output-styles/*~/.trae/skills/*~/.trae/output-styles/*~/.qoder/skills/*~/.qoder/output-styles/*~/.hermes/skills/*~/.hermes/output-styles/*~/.openclaw/skills/*~/.openclaw/output-styles/*~/.peaks/config.json

Decision evidence

public snapshot
AI called this Malicious at 95.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for block
  • package.json defines postinstall: node ./scripts/install-skills.mjs
  • scripts/install-skills.mjs postinstall symlinks bundled skills into ~/.claude, ~/.codex, ~/.cursor, ~/.trae, ~/.qoder, ~/.hermes, ~/.openclaw paths
  • scripts/install-skills.mjs copies bundled agents/*.md into ~/.claude/agents with .peaks-managed markers
  • scripts/install-skills.mjs creates/updates ~/.peaks/config.json during install
  • scripts/install-skills.mjs can spawnSync('peaks', ['upgrade', ...]) during postinstall when 1.x project state is detected
  • agents/karpathy-reviewer.md is a package-supplied sub-agent prompt installed into Claude's agent loader directory
Evidence against
  • No remote exfiltration endpoint or credential harvesting found in inspected hot paths
  • Writes use marker/hash checks and skip user-authored files in several cases
  • Most child_process use is package-aligned CLI orchestration, not arbitrary shell input
  • Network strings found were repository/docs/local proxy references, not active install-time exfiltration
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 441 file(s), 2.88 MB of source, external domains: api.anthropic.com, api.example.com, api.openai.com, github.com, gitlab.com, reactbits.dev, www.google.com, www.pulsemcp.com

Source & flagged code

11 flagged · loading source
package.jsonView file
scripts.postinstall = node ./scripts/install-skills.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
dist/src/shared/process.jsView file
1import { execFile } from 'node:child_process'; L2: export async function execCommand(command, args, options) {
High
Child Process

Package source references child process execution.

dist/src/shared/process.jsView on unpkg · L1
dist/src/services/upgrade/upgrade-service.jsView file
151// npm install postinstall creates `peaks` → `peaks.sh` on L152: // Windows). cmd.exe (the default Windows shell) cannot run L153: // `.sh` scripts directly, so the shim fails with "unknown
High
Shell

Package source references shell execution.

dist/src/services/upgrade/upgrade-service.jsView on unpkg · L151
dist/src/cli/commands/loop-eval-commands.jsView file
478// eslint-disable-next-line @typescript-eslint/no-var-requires L479: const fs = require('node:fs'); L480: let entries;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/src/cli/commands/loop-eval-commands.jsView on unpkg · L478
scripts/install-skills.mjsView file
1Install-time AI-agent control hijack evidence: L1: #!/usr/bin/env node L2: import { closeSync, constants, existsSync, fchmodSync, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, readlinkSync, realpathSync, readdirSync, renameSync, symlinkSync, un... L3: import { spawnSync } from 'node:child_process'; ... L291: fchmodSync(fd, 0o600); L292: writeFileSync(fd, content, 'utf8'); L293: const writeFd = fd; ... L320: fchmodSync(fd, 0o600); L321: writeFileSync(fd, content, 'utf8'); L322: const writeFd = fd; ... L372: * cannot import the TS service at runtime. The dispatch: L373: * - Look for `.claude`, `.trae`, `.codex`, `.cursor`, `.qoder`, L374: * `.tongyi-lingma` in the project root in that insertion order Payload evidence from schemas/mcp-install-spec.schema.json: L1: { L2: "$schema": "https://json-schema.org/draft/2020-12/schema", L3: "title": "Peaks MCP Install Spec", ... L25: "items": { "type": "string" }, L26: "description": "Required env var names. Values are sourced from process.env at runtime and written as ${VAR} placeholders into settings.json." L27: }
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/install-skills.mjsView on unpkg · L1
dist/src/cli/commands/playwright-commands.jsView file
27* The CLI does NOT bundle `playwright-mcp`; it shells out to L28: * `npx playwright-mcp@latest` (G22 / NG3). peaks-loop is the lifecycle L29: * orchestrator, not the install medium. ... L31: import { createHash } from 'node:crypto'; L32: import { spawn } from 'node:child_process'; L33: import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, unlinkSync } from 'node:fs';
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

dist/src/cli/commands/playwright-commands.jsView on unpkg · L27
matchType = normalized_sha256 matchedPackage = peaks-loop@3.0.3 matchedPath = [redacted]-commands.js matchedIdentity = npm:cGVha3MtbG9vcA:3.0.3 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

dist/src/cli/commands/playwright-commands.jsView on unpkg
dist/src/services/code-review/ocr-service.jsView file
matchType = normalized_sha256 matchedPackage = peaks-loop@3.0.3 matchedPath = dist/src/services/code-review/ocr-service.js matchedIdentity = npm:cGVha3MtbG9vcA:3.0.3 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

dist/src/services/code-review/ocr-service.jsView on unpkg
dist/src/services/artifacts/artifact-service.jsView file
matchType = normalized_sha256 matchedPackage = peaks-loop@3.0.3 matchedPath = [redacted]-service.js matchedIdentity = npm:cGVha3MtbG9vcA:3.0.3 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

dist/src/services/artifacts/artifact-service.jsView on unpkg
dist/src/services/workspace/migrate-service.jsView file
matchType = normalized_sha256 matchedPackage = peaks-loop@3.0.3 matchedPath = [redacted]-service.js matchedIdentity = npm:cGVha3MtbG9vcA:3.0.3 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

dist/src/services/workspace/migrate-service.jsView on unpkg
dist/src/cli/commands/test-commands.jsView file
matchType = normalized_sha256 matchedPackage = peaks-loop@3.0.3 matchedPath = dist/src/cli/commands/test-commands.js matchedIdentity = npm:cGVha3MtbG9vcA:3.0.3 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

dist/src/cli/commands/test-commands.jsView on unpkg

Findings

1 Critical9 High3 Medium5 Low
CriticalAi Agent Control Hijackscripts/install-skills.mjs
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processdist/src/shared/process.js
HighShelldist/src/services/upgrade/upgrade-service.js
HighRuntime Package Installdist/src/cli/commands/playwright-commands.js
HighKnown Malware Source Similaritydist/src/cli/commands/playwright-commands.js
HighKnown Malware Source Similaritydist/src/services/code-review/ocr-service.js
HighKnown Malware Source Similaritydist/src/services/artifacts/artifact-service.js
HighKnown Malware Source Similaritydist/src/services/workspace/migrate-service.js
HighKnown Malware Source Similaritydist/src/cli/commands/test-commands.js
MediumDynamic Requiredist/src/cli/commands/loop-eval-commands.js
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings