# Repro

> Turn a vague bug report into a minimal, runnable reproduction. Use when the report is "it crashes sometimes" / "it's broken on some inputs" and the fix needs the smallest script or test that reliably triggers the bug first.

- Skill: `tokyubevoxelverse/repro` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tokyubevoxelverse/repro`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tokyubevoxelverse/repro/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: tokyubevoxelverse (https://skillmd.com/u/tokyubevoxelverse)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tokyubevoxelverse/repro

---


# Repro

A bug you can't reproduce is a rumor. Your job is to turn the rumor into the smallest runnable artifact that makes the bug happen on demand — because that artifact is 80% of the fix, it's the regression test, and it's the difference between "closed: can't reproduce" and closed.

## Phase 1 — Interrogate the report (and the code)

Extract every concrete fact from the report: exact error text, the feature/action involved, timing ("sometimes", "after a while", "since the update"), environment hints. Then interrogate the codebase, which usually knows more than the reporter:

- Search for the error message → the throwing site → walk backwards to every path that can reach it.
- For each path, ask what *input or state* makes it fire. Each answer is a hypothesis.
- Mine the vague words: "sometimes" → concurrency, ordering, randomness, time; "on some inputs" → boundaries, encoding, size; "after a while" → accumulation, leaks, expiry, overflow; "since the update" → diff the update (and consider handing that part to a bisect).

Rank hypotheses by likelihood × ease of testing.

## Phase 2 — Hunt

Build a harness that invokes the suspected code path *directly* — not the whole app — and try hypotheses in ranked order. Escalate only as needed:

- Deterministic candidates first: boundary inputs, malformed data, empty/huge/unicode.
- Then stateful ones: specific sequences, repeated calls, accumulated state.
- Then nondeterministic ones: tight loops for races, controlled seeds for randomness, frozen/advanced clocks for time bugs. For intermittents, crank the trigger conditions (parallelism, iteration count) until failure is reliable, then record the exact recipe.
- Instrument when hypotheses run out: assertions and logging at the suspect path to catch the state at failure time, then work backwards from the caught state.

**First trigger is not the finish line** — a repro that fires 1-in-20 is a lead, not a deliverable. Keep tightening until it fires every run (or document the honest rate and the conditions that maximize it).

## Phase 3 — Minimize

Delta-debug the trigger down: remove every line, dependency, config flag, and data field that isn't needed for the bug to fire, re-running after each removal. The end state is the *smallest* input and *shortest* script that still reproduces — small enough to paste into an issue, obvious enough that the root cause is often visible in the repro itself.

## Phase 4 — Deliver

1. **The repro script** — runnable with one command, self-contained, seeded/deterministic wherever possible.
2. **`REPRO.md`** — exact trigger conditions, expected vs. actual, failure rate if not 100%, environment requirements, and the root-cause pointer if the minimization exposed it (it usually does).
3. **The regression test** — the repro converted into the project's test framework, currently failing, ready to flip green with the fix.

## If it won't reproduce

That's a report, not a failure: document every hypothesis tested and ruled out, the harnesses used, and what evidence from the reporter would discriminate between surviving hypotheses (exact version, the input file, a log with timestamps). Ruling out ten causes *is* progress, and the discriminating-evidence list turns "can't reproduce" into a specific, answerable ask.

