Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Source code vulnerability hunting (SAST). Decomposes analysis into specialized passes: map entry points, map dangerous ops, trace flows, find gaps, adversarial validation, exploit. Usage: /sast <repo_path> [--lang c|cpp|rust|java|python|go|php] [--min-score 4] [--max-files 30] [--skip-static] [--best-of N]
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-25 | ✗→✓ | ▲ Improved | — | — |
| case-22 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-08 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✓ | ▲ Improved | — | — |
Source code hunt on: $ARGUMENTS
ALL agents dispatched by this command MUST use model: "inherit" in the Agent tool call, EXCEPT sast-flow-tracer and sast-gap-analyzer which MUST use model: "opus" (these require cross-file reasoning that benefits from maximum reasoning depth regardless of what the orchestrator inherits).
Read rules/hunting.md FIRST. Rules 0, 2, 9, 14 apply to SAST. Read skills/sast-methodology/SKILL.md for reference.
A single agent asked to "find vulnerabilities" will hallucinate plausible-looking bugs. This pipeline decomposes the task into focused steps:
The synthesis happens through the PIPELINE, not inside one agent's head.
<repo_path>, --lang (auto-detect), --min-score (default 4), --max-files (default 30), --skip-static (skip CodeQL/Semgrep), --best-of N (run N independent hunters on top files, default 1)ls <repo_path>/bash find <repo_path> \( -name '*.c' -o -name '*.cpp' -o -name '*.h' -o -name '*.rs' -o -name '*.java' -o -name '*.py' -o -name '*.go' -o -name '*.php' -o -name '*.phtml' -o -name '*.inc' \) | head -20
ls <repo_path>/{Makefile,CMakeLists.txt,Cargo.toml,pom.xml,go.mod,composer.json} 2>/dev/nulluv run python3 $CLAUDE_PROJECT_DIR/tools/brain.py brief sast-<repo_name>mkdir -p findings/sast poc/sast/exploits sast-work/bashcd <repo_path> export CC="gcc" CFLAGS="-fsanitize=address,undefined -g -O1 -fno-omit-frame-pointer" export CXX="g++" CXXFLAGS="$CFLAGS"
If build fails → log and continue. Code review still works.
Skip 1a for PHP/Python/Java — no native sanitizers. For PHP, ensure php --version works and, if composer.json exists, run composer install --no-dev best-effort for autoload/deps.
Run available tools and collect warnings:
bash# C/C++ cppcheck --enable=all --xml <repo_path> 2> sast-work/cppcheck.xml # Universal semgrep --config auto <repo_path> -o sast-work/semgrep.json --json # PHP (run these when --lang php or .php files detected) semgrep --config p/php --config p/security-audit <repo_path> -o sast-work/semgrep-php.json --json psalm --taint-analysis --output-format=json <repo_path> > sast-work/psalm.json 2>/dev/null || true phpstan analyse --level=max --error-format=json <repo_path> > sast-work/phpstan.json 2>/dev/null || true
Parse into sast-work/static-warnings.json. These feed into Phase 3d as additional candidates.
Dispatch sast-file-ranker agent (model: inherit):
sast-rankings.jsonFor each file scoring >= --min-score, starting from highest:
Dispatch sast-entry-mapper agent (model: inherit):
sast-work/<file_hash>-entries.jsonDispatch sast-danger-mapper agent (model: inherit):
sast-work/<file_hash>-dangers.jsonDispatch sast-flow-tracer agent (model: opus):
sast-work/<file_hash>-flows.jsonDispatch sast-gap-analyzer agent (model: opus):
sast-work/<file_hash>-candidates.jsonuv run python3 $CLAUDE_PROJECT_DIR/tools/brain.py record sast-<repo_name> analyzed "<file>" "entries: N, dangers: N, flows: N, candidates: N"
For each candidate: Dispatch sast-devils-advocate agent (model: inherit):
For each survivor: Dispatch sast-hunter agent (model: inherit) in focused mode:
For score-5 files, run N independent instances. Finding in 2+ runs = real. Finding in 1 run = flag for review.
Dispatch sast-exploit-builder agent (model: inherit):
poc/sast/exploits/Record to brain, write to findings/sast/, print summary.
SAST HUNT: <repo_name> (decomposed pipeline)
══════════════════════════════════════════════
Static warnings: N | Files ranked: N (huntable: N)
Entry points: N | Dangerous ops: N | Reachable flows: N | Candidates: N
Devil's advocate: N survived / N killed
ASan confirmed: N | Exploit tiers: ...
CONFIRMED:
1. [CRITICAL] <title> — <file>:<line>
Flow: <entry> → <gap> → <dangerous op>
HALLUCINATIONS CAUGHT (saved by devil's advocate):
- <candidate> — killed: <reason>
Cost: $X.XX | Agents: N4-6 agents per file, two using Opus. Budget ~$0.50-2.00/file. 30 files ≈ $15-60. Adjust --min-score and --max-files accordingly.
Make source review adversarial and evidence-bound.
exec, eval, or deserializer references.--min-score rather than spending Opus on glue code.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-25 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-24 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted, and 24 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +68 percentage points is the difference between those two pass rates over the 24 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.