Best for
- A test fails and the failure is not self-explanatory
- A bug is reported (Jira, Sentry, user message) and the root cause is not obvious
- Production or staging shows unexpected behavior
event4u-app/agent-config/src/skills/systematic-debugging/SKILL.md
Use on a bug, test failure, crash, or unexpected behavior — enforce reproduce → isolate → hypothesize → verify before any fix; fires even on 'this is broken' / 'quick fix'.
Decision brief
Use on a bug, test failure, crash, or unexpected behavior — enforce reproduce → isolate → hypothesize → verify before any fix; fires even on 'this is broken' / 'quick fix'.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/event4u-app/agent-config --skill "src/skills/systematic-debugging"Inspect the Agent Skill "systematic-debugging" from https://github.com/event4u-app/agent-config/blob/0adf49a8ae84b0ff6e2de8759eea43257e020eff/src/skills/systematic-debugging/SKILL.md at commit 0adf49a8ae84b0ff6e2de8759eea43257e020eff. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Every debug session walks these six phases in order. Treat them as a checklist — tick each box before claiming the bug fixed:
Complete each phase before starting the next. Skipping ahead is the single biggest cause of wasted debug time.
Goal: make the failure happen on demand, with the smallest possible setup.
Goal: locate the failure in a single component, layer, or call site.
Goal: one testable hypothesis at a time, rejected or confirmed by evidence.
Permission review
The documentation asks the agent to read local files, directories, or repositories.
**Read the assertion, not the file.** `expected X to be Y` namesThe documentation asks the agent to run terminal commands or scripts.
npx tsx node_modules/@event4u/agent-config/src/scripts/emit_knowledge_event.ts \Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 94/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 7 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Do NOT use when:
data-flow-mapperblast-radius-analyzerFind the root cause before changing any code. A symptom fix that papers over an unknown cause is a regression waiting to happen.
NO FIX WITHOUT ROOT CAUSE. NO ROOT CAUSE WITHOUT EVIDENCE.
NO BUG MARKED FIXED WITHOUT A REGRESSION TEST.
"I think it's probably X" is not evidence. A log line, a stack trace, a diff, a reproduced failure — those are evidence. A green run after a manual edit is not a regression test — a test that fails without the fix and passes with it, is.
Every debug session walks these six phases in order. Treat them as a checklist — tick each box before claiming the bug fixed:
Skipping a box (especially #2 or #6) is the single biggest cause of wasted debug time and re-opened bugs.
Complete each phase before starting the next. Skipping ahead is the single biggest cause of wasted debug time.
Goal: make the failure happen on demand, with the smallest possible setup.
test-driven-development)
— it turns Phase 4 into a verified fix.If you cannot reproduce, you do not yet understand the bug. Stop. Add logging, re-run, collect more evidence.
Goal: locate the failure in a single component, layer, or call site.
Bisect the surface area. What is the smallest code path that still fails? Turn off/skip/mock adjacent features to narrow the window.
For multi-component systems (frontend → API → service → DB, or CI → build → deploy), log at each boundary:
The goal is not to fix — it is to answer "which boundary is the one where expected ≠ actual?".
Check recent changes: git log, git blame on the failing line,
recent dependency updates, config edits, infra changes.
Consult memory for prior matches. Via
memory-access:
agent-config memory:lookup \
--types incident-learnings,historical-patterns \
--key <error class> --key <failing path> \
--limit 3
A matching incident-learning may already name the root cause, the
fix, and the regression test. A matching historical-pattern
narrows the hypothesis space before Phase 3. Cite matching ids in
the Phase 1–4 evidence trail.
Trace backwards from the symptom. If null arrives at line 42 —
where does the value originate? Walk up the call stack until the
origin is found. Fix at origin, not at line 42.
Goal: one testable hypothesis at a time, rejected or confirmed by evidence.
If three hypotheses in a row fail, stop. You do not understand the system well enough yet, or the architecture is the problem itself — see "Three-strike rule" below.
Goal: the fix resolves the root cause, not just the observed symptom.
If the fix does not work, do not stack a second fix on top. Go back to Phase 2, treat the failure as new evidence.
If you have tried three fixes and the bug is still present:
Tactical complement to the 6-phase loop, for failing test suites,
broken builds, and regressions. Each lap completes in one turn.
Pairs with context-hygiene § Read-Loop Detection
— if you catch yourself reading-without-acting, run this loop.
npx vitest run path/to/single.test.ts,
pytest tests/x.py::test_y, phpunit --filter test_y. Full suite
between laps is forbidden — it drowns the signal.expected X to be Y names
the gap. Hypothesis comes from the error, not a hunch.git log --oneline -- <file> → git show <sha> -- <file>. The
before/after diff names the dropped logic faster than re-reading.Failure-signature triage — same taxonomy as context-hygiene § The 3-Failure Rule.
The failure signature is the same target + same error class (same failing
test with the same assertion, same lint rule id, same build error). The same
failure signature twice → stop and pivot — do not spend the next lap on a
near-identical retry; a repeated identical signature means the hypothesis is
wrong, not under-applied. A new error signature each attempt = progress and
the counter continues. And the hard-blocker classes (missing credentials,
permission denied, spend/quota/rate limit, external-service 5xx) skip retries
entirely — surface on first occurrence; another lap cannot fix them.
Anti-patterns this loop prevents:
| What you need | Tool |
|---|---|
| What does the code actually do at runtime? | dd(), var_dump(), console.log() at suspected line |
| What does the call stack look like? | Stack trace in exception, debug_backtrace(), new Error().stack |
| What data crosses the boundary? | Log at entry and exit of each function in the path |
| What does an HTTP endpoint actually return? | curl -s <url> | jq, Postman MCP, or Http::fake() assertions in tests |
| Is the env/config what I think? | Print the actual value, do not trust the docs |
| What changed recently? | git log -p <file>, git blame -L <line>,<line> <file> |
| Is this a known issue? | Search tracker / Sentry / changelog of the dependency |
| Step through execution | Xdebug — see php-debugging |
Prefer the cheapest tool that resolves the question. A dd() at the
right line beats five minutes of IDE breakpoints.
Known failure signature? If the symptom has a recognisable shape — a
tool/agent loop, HTTP 429, ECONNREFUSED, ENOENT, timeout/hang, OOM, flaky
test, or works-locally-fails-in-CI — consult the symptom → cause → first-check
lookup in failure-signatures
to shortcut Phase 2 (Isolate) with the highest-probability first check. It
supplements the loop; it does not replace it.
Intermittent tests and race conditions usually stem from waiting on
time instead of on a condition. Replace sleep(100) or
setTimeout(r, 100) with an explicit wait-for:
async function waitFor<T>(
check: () => T | undefined | null | false,
label: string,
timeoutMs = 5_000,
): Promise<T> {
const start = Date.now();
while (true) {
const result = check();
if (result) return result;
if (Date.now() - start > timeoutMs) {
throw new Error(`Timeout waiting for ${label} after ${timeoutMs}ms`);
}
await new Promise((r) => setTimeout(r, 10));
}
}
Only use an arbitrary timeout when the timing itself is the contract (debounce, throttle) — and add a comment explaining why the exact value.
When reporting debug findings to the user:
mistake_made event)If the root cause traces to a agents/knowledge/ page that was
followed while implementing (a documented convention was wrong, an
API shape page was stale, a procedure was incomplete), append a
mistake_made event to the knowledge intake — never rewrite the page
mid-task (see knowledge-pages):
npx tsx node_modules/@event4u/agent-config/src/scripts/emit_knowledge_event.ts \
--type mistake_made \
--error-category "<one or two words>" \
--context-source "<agents/knowledge/... path, or 'null' if no page was followed>" \
--correction "<what the fix actually was>" \
--recurrence-key "<stable slug for this class of mistake>"
Verify the append landed: check the command's exit code (0 = appended),
then grep <recurrenceKey> agents/knowledge/intake/events-*.jsonl
finds the new line.
Live contradiction exception. If the followed page is DEMONSTRABLY
wrong right now (observed reality ≠ documented claim, not a one-off),
this is the hybrid immediate-fix case instead — surface the proposed
correction and ask before continuing (see
knowledge-pages
§ Contested entries). Approved → isolated fix commit. Declined →
npx tsx node_modules/@event4u/agent-config/src/scripts/append_contested.ts on that page, then still
emit the context_stale event above it for the consolidation pass.
view / grep /
git log / codebase-retrieval, no edits, no test runs) — trips the
Read-Loop Detection 15-minute warning. See
context-hygiene § Read-Loop Detection
and run the Debug micro-loop instead: one failing test → read the
assertion → read the producer once → one edit → re-run that single
test.test-driven-developmentphp-debuggingplaywright-testingquality-toolsverify-before-completeBefore declaring a bug fixed:
Alternatives
obra/superpowers
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
event4u-app/agent-config
Use BEFORE writing/changing tests, adding mocks, or test-only methods on production classes — vs mocking-the-mock, production pollution, partial mocks, and overfit/tautological assertions
event4u-app/agent-config
Use when the user says "review the design", "check the UI", or wants a comprehensive UI/UX review. Uses a 7-phase methodology covering interaction, responsiveness, accessibility, and more.