| name | systematic-debugging |
| description | Use when encountering any bug, test failure, or unexpected behavior.
Iron Law: no fixes without root cause investigation first.
Four phases: Investigate → Analyze → Hypothesize → Implement.
Triggers: any error, test failure, "it's broken", "why isn't X working".
|
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob"] |
| when_to_use | Use for KNOWN errors, test failures, or unexpected behavior. Iron Law: no fix without root-cause investigation. NOT for open exploration — use investigate for that.
|
| produces | null |
| consumes | null |
| dispatch-agent | explorer |
Preamble (Core)
Status protocol — end every session with one of: DONE (evidence provided) · DONE_WITH_CONCERNS (list each) · BLOCKED (state what blocks you) · NEEDS_CONTEXT (state what you need).
Auto-advance — pipeline: THINK → PLAN → REVIEW → BUILD → VERIFY → RELEASE. Only human gate is spec approval at THINK. On DONE at other stages, print [STAGE] DONE -> advancing to [NEXT-STAGE] and invoke the next skill. On any non-DONE status at any stage, STOP.
Output directory — all artifacts go in docs/superomni/<kind>/<kind>-[branch]-[session]-[date].md. See CLAUDE.md for the full directory map.
TACIT-DENSE — before high-tacit decisions, classify D1 (domain expertise) · D2 (user-facing UX) · D3 (team culture) · D4 (novel pattern). On hit, output TACIT-DENSE [D#]: [question] — My default: [recommendation]. See reference for actions.
Anti-sycophancy — take a position on every significant question. Name flaws directly. No filler ("that's interesting", "you might consider", "that could work").
Telemetry (local only) — at session end, log bin/analytics-log. Nothing leaves the machine.
See preamble-ref.md for detailed protocols.
Systematic Debugging
Iron Law
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST.
If you haven't completed Phase 1, you cannot propose fixes. "I think it might be X" is not a root cause. A root cause is a specific, testable claim about what is wrong.
Good Execution Example
User reports: Button click has no response
Agent:
1. Check event listener bindings -> confirmed bound correctly
2. Check if handler function is called -> found it is NOT called
3. Check for event propagation blockers -> found parent element has e.stopPropagation()
4. Root cause identified: parent stopPropagation() prevents click from reaching button
5. Fix: remove incorrect stopPropagation() call
Bad Execution Example (AVOID)
User reports: Button click has no response
Agent:
Guesses it might be CSS pointer-events: none
-> Adds pointer-events: auto
-> Still broken
-> Guesses it might be z-index
-> Adjusts z-index
-> Still broken
[VIOLATED: Started fixing without root cause investigation]
Common Excuse Rebuttals
| Excuse | Rebuttal |
|---|
| "The problem is obvious, root cause is X" | "Obvious" is not evidence — spend 2 minutes verifying |
| "Similar bug was fixed this way before" | Similar is not identical — verify root cause before applying fix |
| "User described the cause already" | User describes symptoms, not causes — investigate anyway |
Phase 1: Root Cause Investigation
Scope Lock (built-in freeze)
Before investigating, lock the edit scope to the affected area to prevent accidental changes elsewhere:
FREEZE_DIR=$(cd "<affected-directory>" 2>/dev/null && pwd || echo "")
if [ -n "$FREEZE_DIR" ]; then
mkdir -p "${HOME}/.omni-skills"
echo "${FREEZE_DIR%/}/" > "${HOME}/.omni-skills/debug-scope.txt"
echo "Debug scope locked to: ${FREEZE_DIR%/}/"
fi
While scope lock is active, do NOT edit files outside the locked directory. Flag out-of-scope fixes as follow-up tasks. Say "unfreeze" or remove ~/.omni-skills/debug-scope.txt when done debugging.
Investigation Steps
- Read error messages carefully — read the full stack trace; note exact file names and line numbers
- Reproduce consistently — can you reproduce the error every time? If not, gather more data first
- Check recent changes —
git log --oneline -20 -- <affected-files>
- Gather evidence in multi-component systems — add logging at each boundary; don't guess
- Trace data flow — see
root-cause-tracing.md for backward tracing technique
git log --oneline -20 -- <file-or-directory>
grep -r "<error-string>" . --include="*.log" -l 2>/dev/null | head -5
git diff HEAD~5 HEAD -- <affected-area>
Required output: "Root cause hypothesis: ..." — a specific, testable claim.
Example: "Root cause hypothesis: The authenticate() function returns null when the JWT is expired, but the caller doesn't handle null and passes it directly to getUserData(), causing a NullPointerException at line 47."
Dispatch: explorer Agent (Evidence Gathering)
After completing Phase 1 (scope locked, initial evidence gathered), dispatch the explorer agent with:
- Bug statement: "When [X], [Y] happens instead of [Z]."
- All Phase 1 evidence: error messages, stack traces,
git log output
- The scope-locked directory path
- Reproduction steps (if found)
The explorer agent surveys the scope-locked area in isolated context, returns a DEBUG EVIDENCE REPORT (execution path trace, candidate hypothesis list, and pointers to the likely failure site). This skill's Phases 2-4 then pick up with the agent's evidence to form and verify hypotheses. (Debugging protocol content was consolidated from the retired debugger agent into this skill; explorer provides the isolated-context survey.)
Handoff protocol:
DONE → incorporate evidence into Phase 2 pattern analysis; run Phases 3-4 (hypothesis + fix) in main context; proceed to Phase 5 Debug Report
DONE_WITH_CONCERNS → note concerns, continue to Phase 3, flag to user before closing
BLOCKED (3 failed hypotheses) → apply the 3-Strike Rule in Phase 3 and escalate with full evidence
The skill's Phases 2–4 may also run inline as a fallback when the debugging session is simple.
Scope Lock
After forming a hypothesis, lock edits to the affected module to prevent scope creep:
STATE_DIR="${HOME}/.omni-skills"
mkdir -p "$STATE_DIR"
AFFECTED_DIR="<detected-directory>"
echo "${AFFECTED_DIR}/" > "$STATE_DIR/debug-scope.txt"
echo "Debug scope locked to: ${AFFECTED_DIR}/"
echo "Run 'rm ~/.omni-skills/debug-scope.txt' to unlock scope."
You may only edit files within the locked scope during debugging.
If the fix requires touching files outside scope → flag to user and unlock explicitly.
Phase 2: Pattern Analysis
Match the symptom to known patterns:
| Pattern | Signature | Where to look |
|---|
| Race condition | Intermittent, timing-dependent failures | Shared mutable state, async code |
| Nil/null propagation | NullPointerError, TypeError on access | Missing null guards, unexpected returns |
| State corruption | Inconsistent data after operations | DB transactions, event hooks, caches |
| Integration failure | Timeout, unexpected response format | Service boundaries, API contracts |
| Configuration drift | Works locally, fails in CI/staging | Env vars, feature flags, secrets |
| Stale cache | Old data returned, fixes on cache clear | Redis, CDN, browser cache, memoize |
| Off-by-one | Wrong count, missing last element | Loop bounds, array indexing |
Also: Find a working example → compare with broken case → list every difference.
See root-cause-tracing.md for systematic backward tracing techniques.
Phase 3: Hypothesis Testing
- State your hypothesis: "I think X is happening because Y"
- Write it down — if you can't write it, you don't understand it yet
- Test minimally — make the SMALLEST possible change to test the hypothesis
- One variable at a time — change exactly one thing per test; never two
- Verify — did the change fix it?
- Yes → proceed to Phase 4
- No → form a new hypothesis (go back to step 1)
3-Strike Rule
After 3 failed hypotheses, STOP. Do not guess further. Choose:
A) Form a completely different hypothesis (change your mental model, not just the details)
B) Add more logging/instrumentation and gather more data before hypothesizing
C) Escalate: report BLOCKED with your 3 hypotheses and evidence gathered
D) Other — describe your own next step: ___________
Phase 4: Implementation
- Create failing test first — see
test-driven-development skill
- Single fix — fix the root cause only; ONE change; no "while I'm here" modifications
- Verify — test passes, no regressions
- Check blast radius — if the fix touches >5 files, flag to user before applying
- If 3+ different fixes failed — question the architecture, not just the code
See defense-in-depth.md for multi-layer validation after finding root cause.
See condition-based-waiting.md for async/timing issues.
Phase 5: Debug Report
DEBUG REPORT
════════════════════════════════════════
Symptom: [what the user observed]
Root cause: [what was actually wrong — specific, verified]
Fix: [what changed, with file:line references]
Evidence: [test output or command + result proving fix works]
Regression test: [file:line of new test added]
Scope unlocked: [yes/no — was debug-scope.txt removed?]
Status: DONE | DONE_WITH_CONCERNS | BLOCKED
════════════════════════════════════════
Supporting Techniques
root-cause-tracing.md — backward tracing through call stack
defense-in-depth.md — multi-layer validation after finding root cause
condition-based-waiting.md — replace fragile timeouts with condition polling