| name | fuzz |
| description | 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.
|
| disable-model-invocation | true |
| version | 2026-06-06.2 |
| platforms | ["language-agnostic"] |
| primary_use_cases | ["Harden a parser, encoder, state machine, or pure function against unexpected inputs","Turn a Probable static finding into a Confirmed one with an executable repro","Generate property-based tests around an invariant","Build a differential oracle between two implementations or old/new versions"] |
Fuzz & Property Harness
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.
The loop
| 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. |
When there's no test infrastructure
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.
Pick the technique
| 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)) |
Choosing the oracle (the hard part)
The bug-finding power is in the property, not the input generator. Good oracles:
- Round-trip:
decode(encode(x)) == x; parse(render(x)) == x.
- Invariants: output always sorted; balance never negative; size within bounds.
- Idempotence / commutativity:
f(f(x)) == f(x); order independence.
- Never-crash / never-hang: no panics, no unhandled exceptions, terminates under a timeout.
- Agreement: matches a slow reference impl or the previous version (differential).
- Conservation: counts/sums preserved across a transform.
Seed the generator with the boundary values the numeric/boundaries lens cares about:
empty, single, max, negative, zero, NaN, huge, unicode, nested, duplicate.
Per-ecosystem harness sketches
These are starting points — match the project's existing test runner and conventions.
- Python —
hypothesis (@given(strategies...)); atheris for coverage-guided fuzzing.
- JS/TS —
fast-check (fc.assert(fc.property(...))); jazzer.js/jsfuzz for fuzzing.
- Go — native
testing/quick and func FuzzXxx(f *testing.F) with go test -fuzz.
- Rust —
proptest/quickcheck; cargo-fuzz (libFuzzer) for fuzz_target!.
- C/C++ — libFuzzer (
LLVMFuzzerTestOneInput) or AFL++; run under ASan/UBSan.
- Swift —
SwiftCheck for properties; libFuzzer via -sanitize=fuzzer for C-interop surfaces.
- JVM —
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.
From crash to regression test
- Reproduce — capture the exact failing input.
- Shrink — let the framework minimize it (or minimize by hand) to the smallest input
that still fails. Most property frameworks shrink automatically.
- Pin it — preserve the minimized case as a normal, named regression test so it can
never come back silently. Note the invariant it violated.
- Report — hand the proven case back to triage to record as
Confirmed, with the failing test as the repro.
Report-only by default
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.
Related skills
- bughunt — orchestrator; calls fuzz to confirm Probable findings
- triage — records the proven crash as a Confirmed finding
- the autoreview skill (
/review) — the fix/quality gate once the bug is proven