Debug
Purpose
Systematic debugging skill. Four phases, always in order. NEVER fix symptoms -- always find and fix the root cause. After 2 failed fix attempts, escalate to the user.
When to Use
- Test failures (expected vs actual mismatch)
- Runtime errors (exceptions, crashes, hangs)
- Regressions (worked before, broken now)
- Unexpected behavior (no error, but wrong result)
Process
Phase 1: Symptom Analysis (WHAT, WHEN, WHERE)
Gather facts before forming hypotheses:
- WHAT: exact error message, stack trace, log output
- WHEN: always? intermittent? after a specific change? under load?
- WHERE: which file, function, line? which test? which environment?
- SINCE WHEN:
git log --oneline -20 -- what changed recently?
Output: symptom report with all facts classified as KNOWN or SUSPECTED.
Phase 2: Reproduction (MINIMAL REPRO)
Make the bug reproducible with the smallest possible case:
- Run the failing test or reproduce the error
- If not reproducible: document exact conditions and STOP (cannot debug what cannot be reproduced)
- Strip to minimal repro: remove unrelated code, simplify inputs, isolate the component
- Confirm: the minimal repro fails consistently
Output: exact command to reproduce the failure.
Phase 3: Root Cause (WHY)
Apply the 5 Whys to move from symptom to cause:
- Why does it fail? -> [immediate cause]
- Why does that happen? -> [deeper cause]
- Why does that happen? -> [root cause]
(Continue until you reach a cause you can fix directly)
Techniques (use as appropriate):
- Binary search: comment out code, add assertions to narrow the location
- Git bisect:
git bisect start HEAD <known-good> to find the breaking commit
- Print tracing: add targeted print/log statements at decision points
- Diff analysis:
git diff <known-good>..HEAD -- <file> to see what changed
- Assumption check: list every assumption the code makes, verify each one
Classification: identify the root cause category:
- Logic error (wrong condition, off-by-one, missing case)
- State corruption (mutation, shared state, race condition)
- Contract violation (caller sends wrong type, missing field)
- Environment (missing dependency, wrong version, config)
- Data (unexpected input, encoding, edge case)
Output: root cause statement (1-2 sentences, specific and testable).
Phase 4: Solution Design (FIX + REGRESSION TEST)
- Design the fix: minimal change that addresses the root cause
- Fix the ROOT CAUSE, not the symptom
- One logical change only
- If the fix is large, the root cause analysis may be wrong -- revisit Phase 3
- Write regression test: a test that fails without the fix and passes with it
- Apply the fix
- Verify: regression test passes AND all existing tests pass
- Check for siblings: does the same bug pattern exist elsewhere? (
grep for similar code)
Escalation Protocol
| Attempt |
Action |
| 1st fix fails |
Try a different approach (not the same thing again) |
| 2nd fix fails |
STOP. Escalate to user with: symptom, repro, root cause analysis, 2 approaches tried |
Never retry the same approach. Never loop silently.
5 Whys Example
Symptom: test_parse_config_handles_empty fails with KeyError
Why 1: config["database"] raises KeyError
Why 2: parse_config returns empty dict when file is empty
Why 3: the YAML parser returns None for empty files, not empty dict
Root cause: missing None -> {} coercion after yaml.safe_load()
Fix: add `config = yaml.safe_load(f) or {}` instead of `config = yaml.safe_load(f)`
Common Mistakes
- Fixing the symptom (add a try/except) instead of the root cause
- Not writing a regression test for the fix
- Guessing without reproducing first
- Changing multiple things at once (change one thing, verify, repeat)
- Retrying the same approach that already failed
- Not checking for sibling bugs (same pattern elsewhere)
Integration
- Called by:
/ai-dispatch (debug tasks), ai-build agent (when tests fail), user directly
- Calls: test runners (to reproduce),
/ai-test (regression test)
- Transitions to:
ai-build (fix implementation), /ai-commit (after verified fix)
$ARGUMENTS
1---2name: debug-373description: Use when investigating unexpected behavior, test failures, runtime errors, or regressions. Systematic 4-phase diagnosis: symptom analysis, reproduction, root cause, solution.4---5
6
7
8# Debug
9
10## Purpose
11
12Systematic debugging skill. Four phases, always in order. NEVER fix symptoms -- always find and fix the root cause. After 2 failed fix attempts, escalate to the user.
13
14## When to Use
15
16- Test failures (expected vs actual mismatch)
17- Runtime errors (exceptions, crashes, hangs)
18- Regressions (worked before, broken now)
19- Unexpected behavior (no error, but wrong result)
20
21## Process
22
23### Phase 1: Symptom Analysis (WHAT, WHEN, WHERE)
24
25Gather facts before forming hypotheses:
26
271. **WHAT**: exact error message, stack trace, log output
282. **WHEN**: always? intermittent? after a specific change? under load?
293. **WHERE**: which file, function, line? which test? which environment?
304. **SINCE WHEN**: `git log --oneline -20` -- what changed recently?
31
32Output: symptom report with all facts classified as KNOWN or SUSPECTED.
33
34### Phase 2: Reproduction (MINIMAL REPRO)
35
36Make the bug reproducible with the smallest possible case:
37
381. Run the failing test or reproduce the error
392. If not reproducible: document exact conditions and STOP (cannot debug what cannot be reproduced)
403. Strip to minimal repro: remove unrelated code, simplify inputs, isolate the component
414. Confirm: the minimal repro fails consistently
42
43Output: exact command to reproduce the failure.
44
45### Phase 3: Root Cause (WHY)
46
47Apply the 5 Whys to move from symptom to cause:
48
491. **Why** does it fail? -> [immediate cause]
502. **Why** does that happen? -> [deeper cause]
513. **Why** does that happen? -> [root cause]
52 (Continue until you reach a cause you can fix directly)
53
54**Techniques** (use as appropriate):
55- **Binary search**: comment out code, add assertions to narrow the location
56- **Git bisect**: `git bisect start HEAD <known-good>` to find the breaking commit
57- **Print tracing**: add targeted print/log statements at decision points
58- **Diff analysis**: `git diff <known-good>..HEAD -- <file>` to see what changed
59- **Assumption check**: list every assumption the code makes, verify each one
60
61**Classification**: identify the root cause category:
62- Logic error (wrong condition, off-by-one, missing case)
63- State corruption (mutation, shared state, race condition)
64- Contract violation (caller sends wrong type, missing field)
65- Environment (missing dependency, wrong version, config)
66- Data (unexpected input, encoding, edge case)
67
68Output: root cause statement (1-2 sentences, specific and testable).
69
70### Phase 4: Solution Design (FIX + REGRESSION TEST)
71
721. **Design the fix**: minimal change that addresses the root cause
73 - Fix the ROOT CAUSE, not the symptom
74 - One logical change only
75 - If the fix is large, the root cause analysis may be wrong -- revisit Phase 3
762. **Write regression test**: a test that fails without the fix and passes with it
773. **Apply the fix**
784. **Verify**: regression test passes AND all existing tests pass
795. **Check for siblings**: does the same bug pattern exist elsewhere? (`grep` for similar code)
80
81## Escalation Protocol
82
83| Attempt | Action |
84|---------|--------|
85| 1st fix fails | Try a different approach (not the same thing again) |
86| 2nd fix fails | STOP. Escalate to user with: symptom, repro, root cause analysis, 2 approaches tried |
87
88Never retry the same approach. Never loop silently.
89
90## 5 Whys Example
91
92```
93Symptom: test_parse_config_handles_empty fails with KeyError
94Why 1: config["database"] raises KeyError
95Why 2: parse_config returns empty dict when file is empty
96Why 3: the YAML parser returns None for empty files, not empty dict
97Root cause: missing None -> {} coercion after yaml.safe_load()
98Fix: add `config = yaml.safe_load(f) or {}` instead of `config = yaml.safe_load(f)`
99```
100
101## Common Mistakes
102
103- Fixing the symptom (add a try/except) instead of the root cause
104- Not writing a regression test for the fix
105- Guessing without reproducing first
106- Changing multiple things at once (change one thing, verify, repeat)
107- Retrying the same approach that already failed
108- Not checking for sibling bugs (same pattern elsewhere)
109
110## Integration
111
112- **Called by**: `/ai-dispatch` (debug tasks), `ai-build agent` (when tests fail), user directly
113- **Calls**: test runners (to reproduce), `/ai-test` (regression test)
114- **Transitions to**: `ai-build` (fix implementation), `/ai-commit` (after verified fix)
115
116$ARGUMENTS