From Bughunt Suite
Flush out hidden bugs dynamically by generating property-based tests, fuzz targets, or differential oracles, RUNNING them against the project's own test runner, then shrinking failures into regression tests or ready-to-commit harnesses. Use when the user invokes /fuzz, wants to harden a function, or when bughunt needs to confirm a Probable finding at runtime.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bughunt-suite:fuzzThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Static hunting finds *suspicious* code. This skill **proves** it — or finds what static
Static hunting finds suspicious code. This skill proves it — or finds what static review missed — by executing the code against generated inputs and checking that invariants hold. It's the dynamic counterpart to the bughunt lenses.
Use it standalone to harden a function, or as the confirm step of a hunt: convert a
Probable finding into Confirmed with a failing test.
This skill runs code. The loop is: discover → pick technique → generate harness → execute → shrink → emit. It writes only test/harness code, never product fixes.
| Step | Do |
|---|---|
| 1 Discover | Find fuzzable targets. For a whole-module pass, run python3 ${CLAUDE_PLUGIN_ROOT}/skills/bughunt/scripts/bughunt.py census --functions — it shortlists pure-ish functions (no obvious side effects) with their params, the best fuzz candidates. For a Probable finding from a hunt, the target is the cited function. |
| 2 Pick technique | Choose property / fuzz / differential / metamorphic (table below) and design the oracle. |
| 3 Detect & generate | Detect the project's test runner and property/fuzz library (table below). Generate a harness in the project's own conventions. If the library isn't installed, ask before installing it — never add a dependency silently. |
| 4 Execute | Run it via the project's runner. A real run that fails is the proof; a green run is evidence the property holds for the explored space. |
| 5 Shrink | Let the framework minimize the failing input (most shrink automatically), or minimize by hand to the smallest case that still fails. |
| 6 Emit | Keep or present the shrunk case as a named regression test, and record a findings-JSON entry with verified: {by:"fuzz", method:"property-test", verdict:"upheld"} so triage/merge can fold it into the report as Confirmed. |
If the project has no test runner or the property library can't be installed (offline, user
declines), degrade gracefully: generate the harness and the concrete boundary inputs,
hand-trace the most suspicious case, and present the ready-to-run harness with a one-line
"install X and run Y to confirm" — clearly marked not executed. Never report a fuzz
finding as Confirmed unless you actually ran it.
| Technique | Use when | What you need |
|---|---|---|
| Property-based testing | A function has a stated property/invariant (round-trip, idempotence, ordering, bounds) | An oracle: a property that must always hold |
| Fuzzing | A surface parses/decodes untrusted or complex input and must never crash/hang | A target function + a "does not crash/leak/hang" oracle |
| Differential testing | Two implementations should agree (old vs new, fast vs reference, two libs) | Both impls + an equality oracle |
| Metamorphic testing | No oracle exists, but transformed inputs have predictable relations | A relation (e.g. sort(reverse(x)) == sort(x)) |
The bug-finding power is in the property, not the input generator. Good oracles:
decode(encode(x)) == x; parse(render(x)) == x.f(f(x)) == f(x); order independence.Seed the generator with the boundary values the numeric/boundaries lens cares about: empty, single, max, negative, zero, NaN, huge, unicode, nested, duplicate.
These are starting points — match the project's existing test runner and conventions.
hypothesis (@given(strategies...)); atheris for coverage-guided fuzzing.fast-check (fc.assert(fc.property(...))); jazzer.js/jsfuzz for fuzzing.testing/quick and func FuzzXxx(f *testing.F) with go test -fuzz.proptest/quickcheck; cargo-fuzz (libFuzzer) for fuzz_target!.LLVMFuzzerTestOneInput) or AFL++; run under ASan/UBSan.SwiftCheck for properties; libFuzzer via -sanitize=fuzzer for C-interop surfaces.jqwik for properties; Jazzer for coverage-guided fuzzing.Run fuzzers under sanitizers (ASan/UBSan/TSan) where available — they turn silent corruption into loud, locatable failures.
Confirmed, with the failing test as the repro.This skill writes test/harness code, not product fixes. It surfaces and proves defects;
fixing the underlying code is handed to the human or the autoreview skill (/review).
Don't leave throwaway fuzz scaffolding behind — keep the shrunk regression test, remove the
rest unless the user wants a permanent fuzz target.
npx claudepluginhub robzilla1738/roberts-skills --plugin bughunt-suiteGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.