# Fuzz

> 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: `robzilla1738/fuzz` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add robzilla1738/fuzz`
- Raw SKILL.md: https://api.skillmd.com/api/skills/robzilla1738/fuzz/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: robzilla1738 (https://skillmd.com/u/robzilla1738)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/robzilla1738/fuzz

---


# 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](../bughunt/SKILL.md) 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](../triage/SKILL.md)/`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

1. **Reproduce** — capture the exact failing input.
2. **Shrink** — let the framework minimize it (or minimize by hand) to the smallest input
   that still fails. Most property frameworks shrink automatically.
3. **Pin it** — preserve the minimized case as a normal, named regression test so it can
   never come back silently. Note the invariant it violated.
4. **Report** — hand the proven case back to [triage](../triage/SKILL.md) 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](../bughunt/SKILL.md) — orchestrator; calls fuzz to confirm Probable findings
- [triage](../triage/SKILL.md) — records the proven crash as a Confirmed finding
- the **autoreview** skill (`/review`) — the fix/quality gate once the bug is proven

