Check the targeting before the analysis.
Three open repositories, used in this order. They ship rules and schemas, never program data: your ledger stays private.
rejection-taxonomy
97 logged bug-bounty rejections, classified by triage outcome and by the earliest gate that could have caught each one. Closed vocabulary, no target dimension.
python scripts/query.py --prehunt viability-gate
Scores a draft finding against 22 rejection anti-patterns and 7 pre-hunt gates before you write the PoC. Offline, deterministic, no network code at all.
cargo install --git https://github.com/KhomDev/viability-gate bounty-economics
Read a program's terms before you hunt: payout tier shapes, exclusion-clause classes and prior-audit surfaces, plus a schema for your own private ledger.
python scripts/validate.py --taxonomy Where each tool sits.
The expensive failure is a real, PoC-backed bug that the program cannot pay for. Each tool closes one route to it.
- Before you pick a program bounty-economics
Classify the reward table into one of 5 tier shapes and transcribe every exclusion into one of 14 clause classes. A Medium-class idea on a Critical-only program has an expected value of zero, however correct it is.
- Before you write the PoC viability-gate
Run the draft through 22 anti-patterns and 7 pre-hunt gates. It tells you to stop, and shows the exact sentence that triggered it.
- After every rejection rejection-taxonomy
Log it in a closed vocabulary: triage outcome, earliest catchable gate, where the duplicate signal lived. 97 rows taught me that 73.2% were catchable before reading code.
What a kill looks like.
A draft that is only exploitable by an admin, against a program that excludes privileged roles. The tool stops it and says why.
cargo install --git https://github.com/KhomDev/viability-gate vg check finding.mdviability-gate 0.2.0 — finding.md OUTCOME KILL A hard blocker fired. Do not submit as written. SCORE 60 / 100 (uncalibrated heuristic; not a probability; threshold 50) HARD P2 Privileged-role-gated against a program exclusion ↳ matched: admin can ↳ in sentence: An admin can set the pause flag to zero, which causes every vault operation to → Check whether an unprivileged attacker can trigger the bug without role → compromise. If not: hold. The one escape is UNKNOWING admin harm - a → reasonable admin action with a non-obvious destructive second-order → effect. (docs/rules/P2.md; evidence: in-sample; origin rows: 3) PASS P1, P6, P12, P13, P3, P5, P11, P20, P7, P16, P18, P21, P22, P15, P4, P9, P8, P10, P14, P17, P19 SKIP G1 (no ledger supplied) G2 (no ledger supplied) G3 (no scope tree supplied) G4 (no prior-audit surface supplied) G5 (no test suite supplied) G6 (fork status unknown) G7 (no own-history log supplied) D1 (D1 is a corpus match) Gates: G1 ? G2 ? G3 ? G4 ? G5 ? G6 ? G7 ? D1 ? ──────────────────────────────────────────────────────────── Advisory, never authoritative. This tool produces an outcome with reasons; it does not decide, and it cannot read your target's live rules. Over-filtering is its own failure mode - the catalog is a prioritiser, not a kill-switch. A triage rejection is not a final verdict. CLEAR means only that no known blocker was found by this tool.
Real output from the viability-gate README. It is generated by running the binary, and CI fails if the two drift.
What it cannot do.
It cannot find a duplicate: that is a fact about an external corpus, not about your prose. I tested a fix for that and it failed. Its false-positive rate has never been measured, because my log contains no paid findings.
Read the calibration59 rejections matched to their original finding text, scored on whether the tool flagged the gate the program closed it on. In-sample, so closer to a ceiling than an estimate. It is good at telling you to stop and bad at telling you why. Method and caveats ↗