| name | diagnose |
| description | Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression.
|
Diagnose 🔬
A discipline for hard bugs. Skip phases only when explicitly justified.
Phase 1 — Build a feedback loop
This is the skill. Everything else is mechanical. If you have a fast, deterministic, agent-runnable pass/fail signal for the bug, you will find the cause.
Spend disproportionate effort here. Be aggressive. Be creative. Refuse to give up.
Ways to construct one — try in roughly this order
- Failing test at whatever seam reaches the bug — unit, integration, e2e.
- Curl / HTTP script against a running dev server.
- CLI invocation with a fixture input, diffing stdout against a known-good snapshot.
- Headless browser script (Playwright / Puppeteer) — drives the UI, asserts on DOM/console/network.
- Replay a captured trace. Save a real network request / payload / event log to disk; replay it through the code path in isolation.
- Throwaway harness. Spin up a minimal subset of the system (one service, mocked deps) that exercises the bug code path with a single function call.
- Property / fuzz loop. If the bug is "sometimes wrong output", run 1000 random inputs and look for the failure mode.
- Bisection harness. If the bug appeared between two known states (commit, dataset, version), automate "boot at state X, check, repeat" so you can
git bisect run it.
- Differential loop. Run the same input through old-version vs new-version (or two configs) and diff outputs.
- HITL bash script. Last resort. If a human must click, drive them with a structured script so the loop is still structured.
Iterate on the loop itself
- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.)
- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".)
- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.)
Non-deterministic bugs
Goal is not a clean repro but a higher reproduction rate. Loop the trigger 100×, parallelise, add stress, narrow timing windows, inject sleeps.
When you genuinely cannot build a loop
Stop and say so explicitly. List what you tried. Ask the user for:
- Access to whatever environment reproduces it
- A captured artifact (HAR file, log dump, core dump, screen recording with timestamps)
- Permission to add temporary production instrumentation
Do not proceed to Phase 2 until you have a loop you believe in.
Phase 2 — Reproduce
Run the loop. Watch the bug appear.
Confirm:
Do not proceed until you reproduce the bug.
Phase 3 — Hypothesise
Generate 3–5 ranked hypotheses before testing any of them. Single-hypothesis generation anchors on the first plausible idea.
Each hypothesis must be falsifiable: state the prediction it makes.
Format: "If is the cause, then will make the bug disappear / will make it worse."
Show the ranked list to the user before testing. They often have domain knowledge that re-ranks instantly.
Phase 4 — Instrument
Each probe must map to a specific prediction from Phase 3. Change one variable at a time.
Tool preference:
- Debugger / REPL inspection if the env supports it
- Targeted logs at the boundaries that distinguish hypotheses
- Never "log everything and grep"
Tag every debug log with a unique prefix, e.g. [DEBUG-a4f2]. Cleanup at the end becomes a single grep.
Phase 5 — Fix + regression test
Write the regression test before the fix — but only if there is a correct seam for it.
If a correct seam exists:
- Turn the minimised repro into a failing test at that seam.
- Watch it fail.
- Apply the fix.
- Watch it pass.
- Re-run the Phase 1 feedback loop against the original scenario.
If no correct seam exists, that itself is the finding. Note it. The codebase architecture is preventing the bug from being locked down.
Phase 6 — Cleanup + post-mortem
Required before declaring done:
Then ask: what would have prevented this bug?
If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the improve-codebase-architecture skill with the specifics.