| name | pwk-diagnose |
| description | Disciplined debugging loop for hard bugs and performance regressions. Use when a test fails unexpectedly, a bug is found during execution, or something is broken. Use this skill whenever the user reports a bug, says 'this doesn't work', 'something's wrong', 'help me debug', or when tests fail for unclear reasons. Works at any point in the workflow โ brainstorm, execute, or standalone. |
Diagnose
A 6-phase debugging discipline. Phase 1 is the skill โ spend disproportionate effort here.
Invoking /skill:pwk-diagnose exits the gated brainstorm/plan phase (the workflow guard unlocks) โ diagnosis needs to write failing tests and [DEBUG-โฆ] instrumentation. If you only wanted read-only investigation, use /skill:pwk-status (stays gated) or reinstate the lock with /pwk-guard on.
Phase 1 โ Build a feedback loop
Create a fast, deterministic, agent-runnable pass/fail signal for the bug before doing anything else. Try in this order: failing test, curl script, CLI invocation, headless browser script.
Other strategies when the basics don't work:
- Bisection โ bug appeared between two known states? Automate "boot at state X, check, repeat" to bisect
- Replay โ save a real network request or event log to disk, replay it through the code path in isolation
The loop must produce the failure mode the user described โ not a nearby but different failure. Iterate on the loop itself: can you make it faster? Sharper? More deterministic?
If you genuinely cannot build a loop, stop and say so. List what you tried. Ask for access to a reproducing environment or a captured artifact.
Hold at Phase 1 until you have a loop you believe in. Everything downstream โ hypotheses, instrumentation, the fix โ depends on that loop actually reproducing the user's symptom.
Phase 2 โ Reproduce
Run the loop. Confirm:
- The failure matches the user's reported symptom
- The failure is reproducible across multiple runs
- You've captured the exact symptom (error message, wrong output, slow timing)
Then minimize the repro โ strip it down to the smallest input, shortest path, or fewest steps that still triggers the bug. A minimized repro dramatically narrows the hypothesis space.
Phase 3 โ Hypothesise
Generate 3-5 ranked hypotheses. Each must be falsifiable:
"If <X> is the cause, then <changing Y> will make the bug disappear / <changing Z> 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 hypothesis. Change one variable at a time. Tag every debug log with a unique prefix (e.g. [DEBUG-a4f2]) for easy cleanup later. Prefer a debugger breakpoint over logs when available.
Phase 5 โ Fix + regression test
Write the regression test before the fix โ but only if there's a correct seam (one that exercises the real bug pattern at the call site). If no correct seam exists, note it โ the codebase architecture is preventing the bug from being locked down.
Phase 6 โ Cleanup
Required before declaring done:
- Original repro no longer triggers
- Regression test passes (or absence of seam is documented)
- All
[DEBUG-...] instrumentation removed
- Ask: what would have prevented this bug?
- If the answer is a repeatable pattern, append a generic rule to
docs/lessons.md (strip domain specifics) so future sessions catch it early.
- If the bug was caused by an architectural problem (no good test seam, tangled callers, hidden coupling), suggest writing an ADR to
docs/adr/ capturing that insight