debug
Skill542 starsChanged 11 days agoMITView on GitHub
Hypothesis-driven debugging — architecture-first reading + evidence-before-fix. For bugs that resisted naïve fix attempts.
We split this skill into the rules it gives an agent
21 rules. 0 are common, 20 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 171 edited versions we read keep these.
20
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 32
If the cause is genuinely obvious (typo in a string, off-by-one in a loop), don't invoke this — just fix it.
- Distinctive: line 38
Write down, in this exact shape:
- Distinctive: line 49
If any field is "I'm not sure" — STOP and gather it before going further.
- Distinctive: line 55
Before forming hypotheses, read the relevant files.
- Distinctive: line 79
If you can't write a confirm-or-refute test for a hypothesis, it's not a hypothesis — it's a vibe.
- Distinctive: line 85
Run the confirm test for H1 first.
- Distinctive: line 93
Only after step 4 confirms a hypothesis.
- Distinctive: line 97
NOT bundle "while I'm here" improvements (those are separate PRs)
- Distinctive: line 99
If you're tempted to fix two things in the same PR because "they're related" — split.
- Distinctive: line 107
No new error appears in the chain
- Distinctive: line 113
After a fix lands, the next symptom often hides a second-order bug.
- Distinctive: line 116
No new error appears in browser DevTools / server logs
- Distinctive: line 119
If the user reports a new symptom right after your fix, do not treat it as a separate bug.
- Distinctive: line 149
Keep it under 30 lines. The discipline matters more than the documentation.
- Very specific: line 176
Architectural decisions: use /decide and write an AgDR.
- Distinctive: line 185
Minimum surface evidence (step 1): Don't proceed without these:
- Distinctive: line 194
Architecture-surface map (step 2): Read the file at every layer the request touches:
- Distinctive: line 236
Architecture-surface map (step 2): Read the file at every layer the failing operation touches:
- Distinctive: line 275
When to add a new appendix:
- Distinctive: line 280
When updating an existing appendix:
- Distinctive: line 285
Don't add an appendix until you have a real session's worth of patterns to seed it.
“Common” is measured: kept by at least 6 in 10 of the 171 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Writing: read docs/skills/shared/writing-rule.md before you write a durable artifact.
/debug — Structured Debug Methodology
Most "stuck" debug sessions look the same: pattern-match on the symptom, propose a fix, ship it, find a different symptom, repeat. Each cycle costs a deploy + a CEO approval + the user's patience. This skill enforces the discipline that prevents the loop:
- Capture the symptom precisely — the exact URL, the exact response, the exact step that fails.
- Read the architecture before guessing — map every layer the request touches.
- Form a hypothesis ladder — 3–5 candidate causes ordered by probability, each with an explicit evidence test.
- Gather evidence first, fix second — never ship a fix without a verification step that would have caught the wrong hypothesis.
- Verify the fix against the original evidence — re-run the symptom check, not just the unit tests.
The cost of one extra curl, one extra Read, one extra "what does the server actually return?" — is one minute. The cost of one wrong fix that ships, deploys, blocks the user, and then has to be diagnosed again is hours.
When to invoke
Trigger this skill when any of the following is true:
- A previous fix attempt didn't resolve the symptom
- The symptom involves multiple layers (CDN, framework, backend, auth, network)
- Pattern-matching on the symptom produces more than one plausible cause
- The CEO has had to point out the bug exists more than once
If the cause is genuinely obvious (typo in a string, off-by-one in a loop), don't invoke this — just fix it. The skill is for the cases where you're tempted to guess.
Process
Step 1 — Capture the symptom
Write down, in this exact shape:
URL / endpoint: <exact URL or command>
Action: <what the user did>
Expected: <what should have happened>
Observed: <what actually happened>
Repro recipe: <minimal steps that reproduce>
Surface evidence: <screenshot URL, console output, response headers, logs>If any field is "I'm not sure" — STOP and gather it before going further. Hypotheses built on a fuzzy symptom are guesses dressed up.
The minimum surface-evidence bar is stack-specific — see the appendix matching the bug's stack at the bottom of this skill (Web, Desktop). If your stack isn't listed, fall back to the general principle: capture what the system actually does at the moment of failure, not what it should do.
Step 2 — Map the architecture
Before forming hypotheses, read the relevant files. Don't reason about what the code probably does; check.
The architecture-surface table is stack-specific — see the appendix at the bottom matching the bug's context. The general rule is: walk every layer the failing operation touches, from the user input down to the persistence/external boundary, and read the file that handles each layer's responsibility.
Do not skip this step. This is where the actual bug usually lives. Most "tricky" bugs are tricky because the agent reasoned about an imagined architecture instead of reading the real one.
Step 3 — Hypothesis ladder
List 3–5 candidate causes, ordered by probability. For each, write the specific evidence that would prove or disprove it.
Format:
H1 (most likely): <one-sentence cause>
Evidence to confirm: <command or observation that proves it>
Evidence to refute: <command or observation that proves it isn't this>
H2: <one-sentence cause>
Evidence to confirm: ...
Evidence to refute: ...
H3: ...If you can't write a confirm-or-refute test for a hypothesis, it's not a hypothesis — it's a vibe. Replace it with one you can test, or drop it.
Common anti-pattern: "It might be a cache issue" — too vague. Replace with: "Browser has a cached 301 redirect for /auth/callback → /auth/callback/ from a previous deploy state. Confirm by reproing in incognito; refute if the symptom persists in incognito."
Step 4 — Gather evidence
Run the confirm test for H1 first. If it confirms → go to step 5. If it refutes → run the refute test, then move to H2.
The evidence-tests cookbook is stack-specific — see the appendix at the bottom matching the bug's context (Web, Desktop). Each table maps common hypothesis classes to the specific command or observation that confirms or refutes them.
Critical: the evidence test must be specific enough that "the test passed" actually rules out the hypothesis. "It looked right when I tested" doesn't count.
Step 5 — Implement the fix
Only after step 4 confirms a hypothesis. The fix should:
- Target the verified mechanism, not adjacent code that "looks suspicious"
- Be the smallest change that addresses the confirmed root cause
- NOT bundle "while I'm here" improvements (those are separate PRs)
If you're tempted to fix two things in the same PR because "they're related" — split. The wrong-diagnosis cost is N times higher when multiple changes are in flight.
Step 6 — Verify the fix against the original evidence
Re-run the same evidence command you used in step 4. If the original test was curl -I https://staging.x.com/auth/callback/, run that exact command again. Confirm:
- The status code changed in the expected direction
- The expected content is now served
- No new error appears in the chain
Unit tests passing is necessary but not sufficient — they verify code correctness, not feature correctness. A fix that passes tests but doesn't change the curl output didn't actually fix anything.
Step 7 — Watch for compounding issues
After a fix lands, the next symptom often hides a second-order bug. Don't declare victory until:
- The user confirms the original repro recipe now works end-to-end
- No new error appears in browser DevTools / server logs
- The fix has been tested in two distinct contexts (different machine, different account, different browser) — the same-session cache can mask both successes AND failures
If the user reports a new symptom right after your fix, do not treat it as a separate bug. It's almost always a compounding issue from the same root cause or your fix's side effect. Re-enter step 1 with the new symptom.
Output shape
A debug session run through this skill produces a single concise report:
DEBUG REPORT — <symptom summary> @ <date>
## Symptom
<filled in from step 1>
## Architecture surface
<bullet list of layers traversed in step 2 — file paths only, no narrative>
## Hypothesis ladder
H1 (chosen): <hypothesis> — confirmed by <evidence>
H2: <hypothesis> — refuted by <evidence>
H3: <hypothesis> — not tested (refuted by H1 confirmation)
## Fix
<file path>:<line>: <one-line summary of the change>
## Verification
<command run, before-output, after-output>
## Open follow-ups
<anything noticed that's NOT this bug but should be tracked>Keep it under 30 lines. The discipline matters more than the documentation.
Anti-patterns this skill prevents
| Anti-pattern | Example from real debug session |
| Hypothesis-then-fix without evidence | "Looks like a trailing-slash issue, let me set trailingSlash: true" — without verifying that /auth/callback.html was the file actually being requested |
| Pattern-match on URL shape | "URL ends with /, must be a trailing-slash routing problem" — without reading the SPA-fallback code that's the real handler |
| Multiple parallel fixes | Three sequential PRs chasing the same symptom because each was based on a different guess (no evidence test in between cycles) |
| Skipping the architecture read | Six round trips into "what does the server return?" before reading not-found.tsx for the first time |
| Declaring victory on unit-test pass | "All 101 tests pass" — but the actual repro still 404s in the browser |
| Treating compounding symptoms as separate bugs | "OK that fixed the 404, now there's a redirect loop" → file new ticket → repeat. Usually it's the same root cause |
Relationship to other skills
| Skill | Use when |
/debug (this skill) | A bug is resisting fixes; you need methodology |
/decide | Picking between options that all work — different decision class |
/threat-model / /security-review | The bug class is "is this exploitable?" not "why doesn't it work?" |
/code-review (Rex agent) | Reviewing a finished PR, not investigating a live symptom |
/launch-check | Auditing readiness across dimensions; not triaging a single bug |
When NOT to use this skill
- Simple bugs: typos, missing imports, obvious off-by-ones. The methodology overhead exceeds the gain.
- Greenfield exploration: you're learning the codebase, not debugging a regression.
- Architectural decisions: use
/decideand write an AgDR; debugging is for "it doesn't work", not "which approach should we take". - Performance investigation: similar discipline, but the toolkit is different (profiles, traces, flamegraphs). A separate
/perf-debugskill could be filed if the gap matters.
Stack appendices
Each appendix carries the stack-specific surface-evidence requirements (step 1), architecture-surface map (step 2), and evidence-tests cookbook (step 4). The body of the skill stays methodology-only so it doesn't bloat as more stacks land.
Web appendix
Minimum surface evidence (step 1). Don't proceed without these:
curl -Iof the failing URL — response status + Location header- Browser DevTools Network tab redirect chain — every status code and Location header from the user action to the visible failure
- Browser DevTools Console — any errors, including the stack trace
- The exact URL in the address bar at the moment of failure (often differs from what the user typed — note both)
Capture that evidence with a browser-automation MCP server (Playwright MCP or equivalent) rather than an ad-hoc headless-browser CLI invocation. Prefer an accessibility-tree snapshot over a screenshot when the hypothesis is about what the page says — a snapshot returns rendered text and roles, and it does not depend on animation timing. If you take a screenshot, wait until the page settles: a chart's draw-in animation captured at frame 0 renders empty, and that frame has already produced at least one confident, wrong root-cause finding.
Architecture-surface map (step 2). Read the file at every layer the request touches:
| Layer | What to read | What you're looking for |
| Browser routing | The page component for the URL path | Component logic, redirects, error boundaries |
| App framework | next.config.*, nuxt.config.*, vite.config.* | Build mode (SSR/SSG/SPA), trailingSlash, basePath |
| App router fallback | not-found.*, 404.*, custom error pages | Whether the app catches 404s itself and re-routes (this was the missed layer in the originating session) |
| CDN | infrastructure/**/cdn/**/*.tf, CloudFront/Vercel/Netlify config | Custom error responses, rewrites, redirect rules |
| Origin | S3 bucket policy, web host index document | What gets served when the path doesn't exist literally |
| API client | The shared fetch wrapper / api-client.ts | Auth-header injection, 401-redirect, retry logic |
| Backend handler | The handler the page calls | What status codes it returns and when |
| Auth | The auth provider's config + the token-validation code | Where session reads happen and what triggers a redirect |
Evidence-tests cookbook (step 4).
| Hypothesis class | Evidence test |
| Server returns wrong status | curl -I <url> and read the HTTP code + Location header |
| File missing from origin | aws s3 ls s3://bucket/<path> (or platform-equivalent) |
| CDN cache stale | curl -I and check x-cache: Hit/Miss/Error from cloudfront; force cache miss with a query-string buster |
| Redirect loop | curl -L --max-redirs 10 -v and read the redirect chain |
| Wrong content served | curl <url> and grep for distinctive strings (something only the expected page has, something only the unexpected page has) |
| Client-side error | Browser DevTools console — actual error message and stack trace |
| Missing route in route table | grep for the route name in the router config / route manifest |
| Auth header missing | Browser DevTools network tab → request headers → Authorization |
| Token not stored | DevTools → Application → Local Storage / Session Storage — check the keys the auth lib uses |
| Env var unset at build | Read the build log for the relevant NEXT_PUBLIC_* / VITE_* value |
| CORS rejection | Network tab shows preflight OPTIONS returning 4xx, or response missing Access-Control-Allow-* headers |
| State lost between tabs | Reproduce in a single tab end-to-end vs. the original flow that crossed tabs |
Desktop appendix
Covers Electron / Tauri (web tech in a native shell) and native (Swift/Cocoa, .NET/Win32, GTK/Qt). For Electron and Tauri, the renderer process is essentially a web app — use the Web appendix for renderer-side bugs and this appendix for everything that crosses the native boundary.
Minimum surface evidence (step 1). Don't proceed without these:
- The exact reproduce sequence (which window, which menu item, which IPC call)
- Crash log if the app crashed (Console.app → Crash Reports on macOS, Event Viewer → Application on Windows,
journalctl --useron Linux) - App's own log file — most desktop apps log to a known path (
~/Library/Logs/<App>on macOS,%APPDATA%\<App>\logson Windows,~/.local/state/<App>/or stdout on Linux) - Build/version info —
<App>.app/Contents/Info.plist(macOS),<App>.exeproperties (Windows), so you know what code is actually running - For sandbox / permission issues: the entitlements (macOS:
codesign -d --entitlements - <App>.app) or manifest capabilities (Windows AppX)
Architecture-surface map (step 2). Read the file at every layer the failing operation touches:
| Layer | What to read | What you're looking for |
| App entry point | main.ts (Electron), src-tauri/src/main.rs (Tauri), AppDelegate.swift (macOS), Program.cs / App.xaml.cs (Windows) | Initialization order, lifecycle hooks (willFinishLaunching, applicationDidFinishLaunching) |
| Window / view | The window creation code (Electron BrowserWindow, Tauri tauri::Builder, native window controllers) | preload scripts, webPreferences, content security policy, navigation guards |
| IPC bridge | Electron ipcMain / ipcRenderer handlers, Tauri commands (#[tauri::command]), native XPC / COM definitions | Channel names, message shape, error propagation, async vs sync |
| Renderer / UI thread | The component the user interacted with | Same as web for Electron/Tauri; AppKit/SwiftUI/WinUI/Qt view code for native |
| Native modules | package.json dependencies for *-native, node-gyp builds, .dylib / .dll / .so paths | Whether the binary is signed, ABI-compatible, present at runtime |
| App lifecycle | app.on('ready'), app.on('quit'), etc. | Resource cleanup, save-on-quit, sleep/wake behavior |
| File-system / sandbox | macOS App Sandbox container path (~/Library/Containers/<bundle-id>/), Windows AppData paths, entitlements / capabilities | Whether the app can actually read/write the path it's hitting |
| Auto-updater | Squirrel.Mac / Squirrel.Windows / Sparkle / Tauri updater configuration | Update feed URL, signature key, update phase the failure happens in |
| Crash reporter | Sentry / Bugsnag SDK init, OS crash-dump configuration | Whether crashes are even being captured |
| Network | Same as web — use the Web appendix for HTTPS calls; add the platform's network proxy if relevant (Charles, Proxyman, Wireshark) | |
| Code signing / notarization | macOS codesign -dv <App>.app, spctl -a -vv <App>.app, Windows signtool verify /pa <exe> | Signature validity, notarization status (macOS Gatekeeper) |
Evidence-tests cookbook (step 4).
| Hypothesis class | Evidence test |
| Crash on launch | Console.app (macOS) / Event Viewer (Windows) / journalctl --user -e (Linux), filtered by app bundle id; look for Termination Reason, Exception Type, signal name |
| App won't open at all | macOS: spctl -a -vv <App>.app (Gatekeeper), codesign -dv <App>.app (signature); Windows: SmartScreen prompt, signature on .exe properties |
| Sandbox-denied file access | macOS: tail ~/Library/Logs/DiagnosticReports/Sandbox-* and log stream --predicate 'subsystem == "com.apple.sandbox"'; check codesign -d --entitlements - <App>.app for the right entitlement |
| Native module won't load | macOS: otool -L <binary> (missing dylibs, wrong arch); Windows: Dependency Walker / dumpbin /dependents; Linux: ldd <binary> |
| IPC message lost | Add a log on both ends (main + renderer or host + extension); compare timestamps; check channel names match exactly |
| Auto-update fails | Read updater logs (Squirrel: ~/Library/Caches/Squirrel/Logs/, Sparkle: app's own logs, Tauri: same); verify code-signing key matches between current app and update bundle |
| Hang on quit | macOS: sample <pid> 5 -file /tmp/sample.txt then read for stuck threads; Windows: WinDbg attach + ~*kn for thread stacks |
| Memory leak | Instruments (macOS Allocations / Leaks template); Windows perfmon; live Activity Monitor / Task Manager during repro |
| Wrong version installed | <App>.app/Contents/Info.plist CFBundleShortVersionString; Windows: file properties → Details → Product version. Compare to expected build artifact |
| Network call fails inside the app but works in browser | Charles/Proxyman: route the app through a proxy and inspect TLS handshake; suspect ATS (App Transport Security) on macOS / cert store on Windows |
| Renderer JS error in Electron/Tauri | Open DevTools in the running app (Electron: Cmd+Opt+I if enabled, Tauri: tauri dev); use the Web appendix tests from there |
Native crash with EXC_BAD_ACCESS / 0xC0000005 | Symbolicated crash log (atos on macOS, WinDbg !analyze -v on Windows); look at the thread that crashed for stack trace |
| Permission prompt skipped | macOS: TCC database (tccutil reset <service> <bundle-id> to re-prompt); Windows: capabilities in app manifest |
| Different behavior in dev vs packaged | Compare entitlements + signing between npm run dev build and npm run package build; the dev build often has wider entitlements implicitly |
Notes for skill maintainers
The methodology body is portable across stacks. The appendices are where stack-specific knowledge accumulates.
When to add a new appendix:
- A debug session in a new stack class (mobile, backend service, CLI tool, data pipeline) produces a useful evidence-tests pattern
- The user reports the existing appendices don't cover their stack and the gap is concrete
When updating an existing appendix:
- New evidence-test pattern proven useful in a real session — append to the cookbook table and mention the originating session in the commit message
- A row points at deprecated tooling — replace with the current best tool, don't keep both
Don't add an appendix until you have a real session's worth of patterns to seed it. A speculative "Mobile" appendix with three half-formed rows is worse than no Mobile appendix.
Part of ApexYard — multi-project SDLC framework for Claude Code · MIT.
Other versions192 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 192
- Yeachan-Heo/oh-my-claude-sisyphus★ 40ksame name
- Yeachan-Heo/oh-my-claudecode★ 40ksame name
- anthropics/knowledge-work-plugins★ 34ksame name
- qwibitai/nanoclaw★ 31ksame name
- gavrielc/nanoclaw★ 31ksame name
- nanocoai/nanoclaw★ 31ksame name
- openai/symphony★ 27ksame name
- FalkorDB/FalkorDB★ 11ksame name
- NVIDIA/TensorRT-Model-Optimizer★ 5.5ksame name
- NVIDIA/Model-Optimizer★ 5.5ksame name
182 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use add-discord, add-slack and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkilladd-discord
Add Discord bot channel integration via Chat SDK.
Also in 11 projects that use this
MicrosoftSkilladd-slack
Add Slack channel integration via Chat SDK.
Also in 11 projects that use this
juancruzmunozalbeloSkilladd-telegram-swarm
Add Agent Swarm (Teams) support to Telegram. Each subagent gets its own bot identity in the group. Requires Telegram channel to be set up first (use /add-telegram). Triggers on "agent swarm", "agent teams telegram", "telegram swarm", "bot pool".
Also in 7 projects that use this
- +9 more from microsoft
In this repository71 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .cursor/rules/apexyard.mdcCursor rule
- accessibility-auditSkill
- agdrSkill
- analytics-auditSkill
- approve-architectureSkill
- approve-designSkill
- approve-mergeSkill
- audit-depsSkill
- bugSkill
- c4Skill
- challengeSkill
- code-reviewSkill
- codify-ruleSkill
- compliance-checkSkill
- decideSkill
- design-reviewSkill
- design-syncSkill
- dfdSkill
- docs-auditSkill
- eval-agentsSkill
- extract-featuresSkill
- fan-outSkill
- feature-diagramSkill
- featureSkill
- geo-auditSkill
- handoverSkill
- ideaSkill
- inboxSkill
- investigationSkill
- journeySkill
- launch-checkSkill
- migrationSkill
- monitoring-auditSkill
- mutation-testSkill
- onboardSkill
- orbitSkill
- pdfSkill
- performance-auditSkill
- plan-initiativeSkill
- preflightSkill
- processSkill
- projectsSkill
- prototype-closeSkill
- prototypeSkill
- releaseSkill
- release-syncSkill
- report-apexyard-bugSkill
- request-apexyard-featureSkill
- roadmapSkill
- scaffoldSkill
- security-reviewSkill
- seo-auditSkill
- setupSkill
- spike-closeSkill
- spikeSkill
- split-portfolioSkill
- stakeholder-updateSkill
- start-ticketSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

