A prompt-based pipeline for finding, validating, and proving vulnerabilities using LLM sub-agents — structured to resist false positives.
Authors: Gadi Evron (@gadievron) and Michal Kamensky (@kamenskymic)
Note: This system has since been enhanced and turned into a skill by John Cartwright (@grokjc), where he combined it with his binary exploitation module for raptor.
And if you like what I do, check out my startup Knostic where we protect coding agents/MCP/extensions/skills, etc.
Takes a codebase, searches for vulnerabilities (e.g., command injection), validates findings aren't hallucinated, known, or by-design, and — where the environment allows executing a harmless PoC — proves real ones. A finding verified only by static dataflow is reported as confirmed; exploitable requires an observed effect (see the execution model in shared.md).
This pipeline is packaged as a skill — SKILL.md is the operational entry point and the source of truth for the stage table. The copies below are a human-readable mirror; if they ever diverge, SKILL.md wins.
| Stage | Purpose | Output |
|---|---|---|
| 0: Inventory | Build ground truth checklist of all files/functions | checklist.json |
| A: One-Shot | Quick exploitability check + PoC attempt (a success does not skip B/C) | findings.json |
| B: Process | Systematic analysis with attack trees, hypotheses, multiple paths | findings.json + working docs |
| C: Sanity | Validate LLM didn't hallucinate — mechanical fact-check only (files exist, code matches, flow is real) | validated findings.json |
| C-bis: Semantic | Is it actually a vuln? Rule out algorithm tautologies, spec-required behavior, documented design | findings.json |
| N: Novelty | Is it new? Cross-reference known CVEs / advisories / fixes (GATE-1 suspended) | findings.json |
| D: Ruling | Synthesize evidence; rule out preconditions, privilege tautologies, hedging, no-impact | findings.json |
| E: Review | Self-review: catch misclassifications, weak evidence, inconsistencies | final findings.json |
┌─────────────────────────────────────────────────────────────┐
│ STAGE 0: Inventory │
│ Build ground truth checklist (files, functions) │
│ Exclude test/mock files (record reasons) │
│ OUTPUT: checklist.json │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ STAGE A: One-Shot │
│ 1. Verify exploitability │
│ 2. Build harmless PoC (success = observed effect, GATE-8) │
│ OUTPUT: findings.json │
└─────────────────────┬───────────────────────────────────────┘
┌───────────┼───────────────┐
▼ ▼ ▼
PoC succeeds Not disproven Disproven
│ │ │
▼ ▼ ▼
┌───────────────────────┐ Done
│ STAGE B: Process │ (fill disproved_because)
│ Attack trees, │
│ hypotheses, paths, │ ◄── anti-bypass: a successful
│ PROXIMITY 0–10, │ one-shot PoC still passes
│ PoC attempts │ through B (fast-path [B-0])
│ OUTPUT: findings + │ and C — it never skips them
│ working docs │
└───────────┬───────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ STAGE C: Sanity Check (mechanical fact-check ONLY) │
│ file exists · path · code verbatim · flow real · reachable │
│ (does NOT change status/severity/vuln_type) │
│ OUTPUT: validated findings.json │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ STAGE C-bis: Semantic Validation — "is it a vuln?" │
│ CB-1 algorithm tautology · CB-2 spec-compliance · │
│ CB-3 documented design → fires ⇒ status: by_design │
│ OUTPUT: findings.json │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ STAGE N: Novelty — "is it new?" (GATE-1 suspended) │
│ N-1 CVE · N-2 advisory/fix · N-3 fork inheritance · │
│ N-4 duplicate / incomplete_fix / independent / no_match │
│ OUTPUT: findings.json │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ STAGE D: Ruling (synthesize evidence, then rule out) │
│ D-0 synthesis · D-0.1 sanity-fail⇒ruled_out(C-fail) · │
│ D-0.2 no evidence⇒stays not_disproven · D-1 code context · │
│ D-1.5 privilege tautology · D-2 preconditions/test-harness │
│ · D-3 hedging · D-4 no impact · D-6 known(duplicate)≠novel │
│ OUTPUT: findings.json │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ STAGE E: Self-Review │
│ misclassifications · missed instances · weak evidence · │
│ field consistency (GATE-7) · value-level evidence │
│ OUTPUT: final findings.json │
└─────────────────────────────────────────────────────────────┘
| Doc | Purpose |
|---|---|
| attack-tree.json | Knowledge graph. Source of truth. |
| hypotheses.json | Active hypotheses. Status: testing, confirmed, disproven. |
| disproven.json | Failed hypotheses. What was tried, why it failed. |
| attack-paths.json | Paths attempted. PoC results. PROXIMITY. Blockers. |
| attack-surface.json | Sources, sinks, trust boundaries. |
The gate rules live in shared.md [GATES] — the single source of truth. Each stage file's GATES APPLY: line is the authoritative per-stage map (co-located so it can't drift). For orientation only:
| Gate | Short name |
|---|---|
| 1 | Assume exploitable |
| 2 | Strict sequence |
| 3 | Checklist compliance |
| 4 | No hedging |
| 5 | Full coverage |
| 6 | Proof required |
| 7 | Consistency (fields match description + proof) |
| 8 | PoC-evidence ("ran without error" ≠ proof) |
| 9 | Novelty (known CVE ≠ 0-day; GATE-1 suspended in Stage N) |
Artifact schemas (checklist.json, findings.json, working docs) are documented in schemas.md.
| File | Purpose |
|---|---|
| SKILL.md | Skill entry + operational stage table (the operational source of truth) |
| shared.md | Configuration, execution rules, MUST-GATEs, [STYLE], reminders |
| schemas.md | JSON contracts for checklist.json, findings.json, and the working docs |
| stage-0-inventory.md | Inventory |
| stage-a-oneshot.md | One-shot verification |
| stage-b-process.md | Systematic process |
| stage-c-sanity.md | Sanity check (fact-check only) |
| stage-c-bis-semantic.md | Semantic validation (is it a vuln?) |
| stage-n-novelty.md | Novelty / known-CVE cross-reference |
| stage-d-ruling.md | Ruling |
| stage-e-review.md | Self-review |
Each stage runs as a sub-agent. Orchestrator:
- Runs stage with appropriate prompt
- Validates output files exist and the stage emitted its
[<id>] <stage>:done-line (a missing done-line means a skipped stage) - Routes to next stage based on outcome (a successful one-shot PoC in Stage A still passes through B and C)
- Passes file-based state between stages
Stage E emits the final findings.json plus a summary report that separates novel confirmed findings from known (duplicate) matches. See SKILL.md for the operator stage table.
Optional (off by default): Stage N can additionally scan the target repo's issue tracker and pull requests for prior reports — catching bugs that are already known/in-flight but have no CVE yet. It's disabled by default (default behavior unchanged); enable it by setting novelty.issue_pr_lookup: true in shared.md [CONFIG] (see Stage N [N-2b]).
This revision targets false positives, informed by a field report (#1) where the pipeline produced 42 findings and only 5 survived independent validation, and by the improvements @grokjc folded into raptor. Highlights:
- Stage C-bis (semantic validation) and Stage N (novelty / known-CVE) — new stages that ask "is it actually a vuln?" and "is it new?".
- Anti-bypass — a successful one-shot PoC no longer skips structured analysis.
- Evidence discipline — GATE-8 (PoC = observed effect), GATE-7 (fields must match proof), privilege-tautology / test-harness-precondition / no-impact rulings, and value-level evidence in review.
- Documented schemas —
checklist.json,findings.json, and the working docs now have contracts inschemas.md.
Binary/memory-corruption feasibility (checksec/ROP/SMT and similar) is intentionally out of scope here — it requires tooling a prompt-only pipeline cannot run; use raptor for that.
This version deliberately trades some of the original's simplicity for false-positive resistance. Worth knowing before you adopt it:
- Rigor over speed. The original let a successful one-shot PoC skip straight to sanity-check; now nothing bypasses structured analysis (anti-bypass). A working PoC still passes through Stage B (a lightweight
[B-0]fast-path) and C. - Coupled, not independent, stages. Stage D is an evidence consumer — it reads Stage C's
sanity_check, C-bis'ssemantic_check, and N'snovelty_status. The stages form a chain (0 → A → B → C → C-bis → N → D → E) and are best run in order, not standalone. - Assumes one capable agent for novelty. Stage N needs CVE knowledge / web access; its verdict is advisory and exempt from the determinism rule (see
shared.md[EXEC]). If you can't do novelty lookup, that stage degrades to best-effort. - Best confirmations still need execution. Without the ability to run a harmless PoC, real findings top out at
confirmed(static dataflow), notexploitable. - Semantic/crypto/logic blind spot. In the benchmark, the pipeline (and the Original and Raptor arms alike) was strong on injection-class dataflow but weak on semantically subtle vulnerabilities — crypto misuse (ECB, hardcoded/forgeable keys), timing side-channels, and business-logic/precondition flaws — where it tended to linger non-committally rather than confirm. This is a shared capability limit, not specific to this pipeline; extra staging did not fix it. Weight these classes accordingly.
- C-bis's FP-reduction is benchmark-validated. On a purpose-built corpus, the semantic stage cleanly reclassified genuinely-intended behavior (math tautology / spec-compliance / documented design) to
by_designwith no false-clear of a real vulnerability — i.e. it earns its place as an FP-reducer. Caveat: that corpus was small and built to exercise the stage, so this validates that it helps, not how often the triggering input occurs in a natural workload.
This skill is evaluated by a controlled, blinded benchmark in the sibling repo
../validate-benchmark/ — it measures this pipeline (as the "New" arm, pinned at
validate@437cd71) against the Original methodology and the Raptor tool, and verifies
which stages earn their keep. Headline results: the arms are equivalent in capability on
every fair test; Stage D-4 is the only causally load-bearing differentiator; and
fair-chance verification KEEPS C-bis (decisive) and N (advisory). Start at
../validate-benchmark/INDEX.md (map) and RESULTS-PROGRAM-summary.md (findings).
main/ tagv2.0-fp-reduction(default) — this FP-reduction pipeline. Adds Stage C-bis, Stage N, and the D-4 no-impact ruling for decisive false-positive resistance.- tag
v1.0-original(git checkout v1.0-original) — the leaner original pipeline. The benchmark found it equal in raw capability; it trades the FP-resistance above for simplicity. Use it if you want the minimal pipeline and can tolerate more false positives.
This analysis is performed for defensive purposes, in a lab environment. Full permission has been provided.
MIT