Systematic Debugging
Diagnose before changing code. Prefer evidence over plausible guesses.
When to use
Use this skill for:
- reproducible or intermittent bugs;
- regressions after a change;
- failing tests, crashes, exceptions, incorrect UI behavior, or state mismatches;
- behavior that differs from a stated specification;
- debugging requests where the root cause is not already demonstrated.
Do not use this skill merely because code is being edited.
Inputs and context
Before editing:
- Read the applicable
AGENTS.mdfiles. - Read the task, expected behavior, and any reproduction steps.
- Inspect current Git status and relevant recent diff when the failure may be change-related.
- Locate the smallest relevant execution path, tests, logs, and call sites.
- Separate:
- observed failure;
- verified facts;
- hypotheses;
- unverified assumptions.
Procedure
Reproduce or otherwise establish the failure.
- Prefer an existing test or deterministic command.
- If reproduction is impossible, state what evidence is available and keep conclusions provisional.
Bound the failure.
- Identify the first known-good and first known-bad state when possible.
- Narrow the affected component, input, state transition, or call path.
- Do not scan or refactor unrelated areas without evidence.
Generate the minimum useful hypothesis set.
- Rank hypotheses by evidence and diagnostic value.
- Prefer checks that eliminate multiple hypotheses at once.
Test hypotheses before editing.
- Inspect values, control flow, state transitions, ownership/lifetime, error paths, timing, and external assumptions as relevant.
- Add temporary instrumentation only when existing evidence is insufficient.
Identify the root cause.
- A root-cause claim must explain both the observed failure and why the current code produces it.
- Do not treat correlation or a nearby suspicious line as proof.
Apply the smallest fix that addresses the demonstrated cause.
- Preserve unrelated behavior.
- Avoid opportunistic cleanup, dependency changes, architecture changes, or broad refactors.
Verify.
- Re-run the original reproduction.
- Run the narrowest relevant tests first, then broader tests when justified.
- Inspect the final diff for unrelated changes.
- Remove temporary instrumentation unless explicitly useful.
Efficiency plan
- Start from the failure path, not the entire repository.
- Reuse already-read files and command output.
- Prefer one discriminating experiment over many speculative edits.
- Stop expanding the investigation once the root cause is demonstrated and the fix is verified.
- If evidence is insufficient, report the uncertainty rather than inventing a cause.
Pitfalls and fixes
Symptom: multiple files edited before the failure is reproduced.
- Likely cause: solution-first debugging.
- Fix: revert speculative edits and establish the failure first.
Symptom: changing architecture to fix a local defect.
- Likely cause: scope drift.
- Fix: return to the demonstrated failure path and implement the minimum causal fix.
Symptom: test passes but original behavior is still wrong.
- Likely cause: verification did not match the reproduction.
- Fix: verify against the original failure condition.
Symptom: root cause is stated without direct evidence.
- Likely cause: hypothesis promoted to conclusion.
- Fix: identify the missing discriminating check and run it.
Verification checklist
Before declaring success, confirm:
- the original failure was established;
- the causal mechanism is supported by evidence;
- the fix targets that mechanism;
- the original failure no longer reproduces;
- relevant tests pass;
- no temporary debug artifacts remain;
- the final diff contains no unrelated refactor or cleanup;
- remaining uncertainty or untested paths are stated explicitly.