Subagent split + 45-skill description audit#18
Conversation
…45 skill descriptions ## Subagent split Move the per-stage prompts out of `.claude/skills/security-review/SKILL.md` and into `.claude/agents/`: - `threat-modeling.md` — Stage 0 - `hotspot-mapping.md` — Stage 1 (now carries the skill catalog) - `design-review.md` — Stage 1b - `vulnerability-audit.md` — Stage 2 - `attack-chain-analysis.md` — Stage 3 Each agent file has its full system prompt, finding-style rules, worked examples, and anti-injection guard. The orchestrator skill drops from 619 words of compressed stage prompts to 387 words of coordination logic, plus a pipeline-progress checklist users can copy as they run the workflow. Naming follows the noun-phrase form (activity, not actor) per Claude's skill-authoring best practices. ## Description audit (all 45 skills) Per the Anthropic best-practices doc, every description must include both *what the skill does* and *when to use it*, in third person. The existing Soundcheck descriptions covered "when" exhaustively but skipped "what". Prepend a one-sentence third-person summary to each: - `csrf`: "Detects forms and state-changing endpoints missing CSRF protection. Use when writing HTML forms..." - `injection`: "Detects SQL, command, and template injection caused by user input reaching an interpreter without parameterization. Use when writing code that constructs..." …and 43 more in the same shape. Auto-invocation discrimination improves when many skills are loaded; existing "Use when..." triggers unchanged. ## CLAUDE.md - Bump skill count 39 → 45. - Document the orchestrator/subagent split and the reload caveat (agent files require a session restart, not just `/reload-plugins`). - Update the description-authoring section to require the what+when format with examples. Validator: 45/45 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Security ReviewFindings
Attack ChainsChain 1 — Critical (F1 → F2: Threat-model poisoning → complete audit suppression)An attacker places a crafted Chain 2 — Critical (F3 → F5 → F6/F7: Subagent poisoning → unsanitized PR comment injection)An attacker embeds instruction-like text in a source file comment or docstring of a repo under review — text that tells the vulnerability-audit agent to emit a finding whose 7 findings across 5 files (4 High, 2 Medium, 1 Medium), 2 critical attack chains. Run Generated by Soundcheck |
…ipts The agents were at `.claude/agents/` — a project-level location that worked for in-repo dev but isn't discoverable when the plugin is installed or loaded via `--plugin-dir`, per the docs: > Plugin agents/ directories are also scanned recursively. (https://code.claude.com/docs/en/sub-agents) Moves them to `agents/` at the plugin root so they're picked up by: - the installed plugin in interactive `/security-review`, - `--plugin-dir <soundcheck>` in test scripts, - and the same path on the action when it clones soundcheck. End-to-end verified: ran security-review-action.py against a fixture with a known SQL injection on haiku — orchestrator dispatched all 5 stages (threat-modeling → hotspot-mapping → design-review + vulnerability-audit → attack-chain-analysis) by bare name (plugin skills resolve their own sibling agents without the namespace prefix when loaded via --plugin-dir), produced findings table with the new severity legend, attack chain narrative, and Critical SQLi catch. ## Script changes - `_claude_cli.run_claude`: new `plugin_dir` kwarg → `--plugin-dir`. - `security-review-action.py`: derives `plugin_dir` from the `--skill-path` so the action also picks up agents when run against third-party repos. Skill-path is now `.../plugin/.claude/skills/ security-review/SKILL.md`; plugin root is four parents up. - `benchmark-eval.py`: passes `plugin_dir=ROOT` (the soundcheck repo) for the `security-review` test only; the other two skills are still inline analysis and don't dispatch subagents. - `smoke-test-skills.py`: skips `security-review` in `find_all_skills()` — it's an orchestrator, not a per-skill detector, and the smoke test arm runs with `disable_tools=True`. End-to-end coverage comes from benchmark-eval and the GitHub Action self-test. ## CLAUDE.md - Updates path references `.claude/agents/` → `agents/` throughout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After the subagent split, /security-review fans out into 5+ Claude
sessions (threat-modeling, hotspot-mapping, design-review,
vulnerability-audit × N, attack-chain-analysis). All of them bill
against the same --max-budget-usd envelope on the parent invocation,
so the $1 default from run_claude got the orchestrator killed
mid-pipeline on every repo:
calcom x security-review: ERROR claude exited with code 1:
Error: Exceeded USD budget (1)
And the 1200s (20 min) timeout was already tight pre-refactor; with
the new architecture's sequential stages it timed out on redash and
gitea before producing output.
For security-review specifically, raise the budget to $10 and the
timeout to 40 min. hotspots and threat-model remain inline reviews
and keep the $1 / 20 min defaults — they don't dispatch subagents.
Caught by re-running the benchmark; previously masked by the
inline-everything orchestrator architecture.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Security ReviewFindings
Attack ChainsChain 1 — CriticalAn attacker submits a pull request whose source files cause the hotspot-mapping subagent to emit a crafted Chain 2 — HighA malicious PR introduces a file whose path survives the Chain 3 — HighWhen the soundcheck action is invoked on a repository that contains an attacker-modified Chain 4 — MediumA repository under review contains strings or code that cause the LLM reviewer to emit GitHub Actions workflow command syntax (e.g. Chain 5 — MediumThe temporary file holding serialized findings is created without restrictive permissions, leaving it world-readable on a misconfigured or multi-tenant CI runner; a co-resident process can read the findings JSON to learn vulnerability details about the scanned repository, or — if it has write access to Summary: 16 findings across Run Generated by Soundcheck |
Summary
Splits `/security-review` into a thin orchestrator skill + 5 named subagents and brings every skill description into line with the official Skill authoring best practices.
Subagent split (`.claude/agents/`)
Per the subagent docs, the stage prompts that were squeezed into the 600-word skill body now live as full agent files:
Each agent file has its full system prompt, finding-style rules for non-security developers, worked examples, and an anti-injection guard. The orchestrator drops from 619 → 387 words of pure coordination logic plus a pipeline-progress checklist users can copy as they go.
Naming follows the noun-phrase (activity) form per the docs. `tools: Read, Glob, Grep` on all of them (read-only).
Description audit — all 45 skills
The Anthropic best-practices doc requires descriptions to include both what the skill does and when to use it, in third person. Soundcheck's existing descriptions covered "when" exhaustively but skipped "what". Each description now leads with a third-person summary:
…and 43 more in the same shape. Existing "Use when..." triggers unchanged — this just prepends the missing "what" sentence.
CLAUDE.md
What I didn't do
Test plan
Reviewer cheat sheet
🤖 Generated with Claude Code