Fuzz
Skill robzilla1738/roberts-skills/plugins/bughunt-suite/skills/fuzz
Provider-agnostic agent skills and plugins for AI coding assistants. By Robert Courson.
npx -y skills add robzilla1738/roberts-skills --skill fuzzAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
6.6 KB, as published. Nobody here has run it
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...));atherisfor coverage-guided fuzzing. - JS/TS —
fast-check(fc.assert(fc.property(...)));jazzer.js/jsfuzzfor fuzzing. - Go — native
testing/quickandfunc FuzzXxx(f *testing.F)withgo test -fuzz. - Rust —
proptest/quickcheck;cargo-fuzz(libFuzzer) forfuzz_target!. - C/C++ — libFuzzer (
LLVMFuzzerTestOneInput) or AFL++; run under ASan/UBSan. - Swift —
SwiftCheckfor properties; libFuzzer via-sanitize=fuzzerfor C-interop surfaces. - JVM —
jqwikfor properties;Jazzerfor 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.