| 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 or throwing or failing, describes a performance regression, or shares a Grafana/Loki link or asks to search logs for a problem.
|
Diagnose
When to use
/diagnose
- User says "diagnose this" or "debug this".
- User reports a bug, error, or unexpected behavior.
- Tests are failing and the root cause is not obvious.
- Something is broken, throwing, or producing wrong output.
- User describes a performance regression.
- User shares a Grafana/Loki dashboard or explore link, or asks to "search Loki"/"check Grafana"/"search the logs" for a problem.
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. Without one, no amount of staring at code will save you.
Spend disproportionate effort here. Be aggressive. Be creative. Refuse to give up.
Before building a loop, check Sentry, if the project uses it (~/.config/agentic/tools/sentry.md). Sentry issues provide stack traces, request params, and breadcrumbs that shortcut the reproduction process. Use them to narrow the scope before constructing a loop.
If the user shares a Grafana dashboard/explore link, or the project logs to Grafana (~/.config/agentic/tools/grafana.md), query the relevant time range and search terms directly instead of guessing at reproduction steps.
Ways to construct one, try them in roughly this order
- Failing test at whatever seam reaches the bug, unit, integration, or e2e.
- Curl or HTTP script against a running dev server.
- CLI invocation with a fixture input, diffing stdout against a known-good snapshot.
- Headless browser script (Playwright or Puppeteer) that drives the UI, asserts on DOM/console/network.
- Replay a captured trace: save a real network request, payload, or 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 or 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, 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 and diff outputs.
Iterate on the loop
Once you have a loop, ask: can I make it faster? Can I make the signal sharper? Can I make it more deterministic? A 30-second flaky loop is barely better than no loop. A 2-second deterministic loop is a debugging superpower.
Non-deterministic bugs
The goal is a higher reproduction rate, not a clean repro. Loop the trigger 100x, parallelise, add stress, narrow timing windows, inject sleeps. A 50%-flake bug is debuggable, 1% is not. Keep raising the rate until it is debuggable.
When you cannot build a loop
Stop and say so explicitly. List what you tried. Ask the user for: access to the environment that reproduces it, a captured artifact (Sentry issue, HAR file, log dump, core dump, screen recording with timestamps), or permission to add temporary instrumentation. Do not proceed to Phase 2 without a loop.
Phase 2: Reproduce
Run the loop. Watch the bug appear.
Confirm:
- The loop produces the failure mode the user described, not a different failure.
- The failure is reproducible across multiple runs (or at a high enough rate to debug against).
- You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix.
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.
If <X> is the cause, then <changing Y> will make the bug disappear, and <changing Z> will make it worse.
If you cannot state the prediction, the hypothesis is a vibe. Discard or sharpen it.
Show the ranked list to the user before testing. They often have domain knowledge that re-ranks instantly. Do not block on it, proceed with your ranking if the user is AFK.
Phase 4: Instrument
Each probe must map to a specific prediction from Phase 3. Change one variable at a time.
Tool preference:
- Debugger or REPL inspection if the env supports it. One breakpoint beats ten logs.
- 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. Untagged logs survive, tagged logs die.
For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, profiler, query plan), then bisect. Measure first, fix second.
Phase 5: Fix + regression test
Write the regression test before the fix, but only if there is a correct seam for it.
A correct seam is one where the test exercises the real bug pattern as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers), a regression test there gives false confidence.
If no correct seam exists, that itself is the finding. Note it. The codebase architecture is preventing the bug from being locked down.
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.
Phase 6: Cleanup + post-mortem
Required before declaring done:
- Original repro no longer reproduces (re-run the Phase 1 loop).
- Regression test passes (or absence of seam is documented).
- All
[DEBUG-...] instrumentation removed (grep the prefix).
- Throwaway prototypes deleted (or moved to a clearly-marked debug location).
- The hypothesis that turned out correct is stated in the commit or PR message.
Then ask: what would have prevented this bug? If the answer involves architectural change (no good test seam, tangled callers, hidden coupling), note the specifics for architectural follow-up.