WCAG 2.1 AA audit — perceivable, operable, understandable, robust criteria. Deep-dive for /launch-check accessibility.
中文简介正在准备中。当前显示原文说明。
Hypothesis-driven debugging — architecture-first reading + evidence-before-fix. For bugs that resisted naïve fix attempts.
中文简介正在准备中。当前显示原文说明。
实测评分 未实测
查看安装方法安装前可以查看交给 AI 代理的指令内容。
Writing: read docs/skills/shared/writing-rule.md before you write a durable artifact.
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:
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.
Trigger this skill when any of the following is true:
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.
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.
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.
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."
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.
Only after step 4 confirms a hypothesis. The fix should:
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.
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:
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.
After a fix lands, the next symptom often hides a second-order bug. Don't declare victory until:
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.
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-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 |
| 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 |
/decide and write an AgDR; debugging is for "it doesn't work", not "which approach should we take"./perf-debug skill could be filed if the gap matters.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.
Minimum surface evidence (step 1). Don't proceed without these:
curl -I of the failing URL — response status + Location headerCapture 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 |
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:
journalctl --user on Linux)~/Library/Logs/<App> on macOS, %APPDATA%\<App>\logs on Windows, ~/.local/state/<App>/ or stdout on Linux)<App>.app/Contents/Info.plist (macOS), <App>.exe properties (Windows), so you know what code is actually runningcodesign -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 |
The methodology body is portable across stacks. The appendices are where stack-specific knowledge accumulates.
When to add a new appendix:
When updating an existing appendix:
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.
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
WCAG 2.1 AA audit — perceivable, operable, understandable, robust criteria. Deep-dive for /launch-check accessibility.
中文简介正在准备中。当前显示原文说明。
WCAG 2.2 AA audit — perceivable, operable, understandable, robust criteria. Deep-dive for /launch-check accessibility.
中文简介正在准备中。当前显示原文说明。
Browse / search / show / stats AgDRs across the portfolio — recalls "have we decided this before?".
中文简介正在准备中。当前显示原文说明。
Analytics audit — SDK config, event naming, funnel completeness, dashboards. Deep-dive for /launch-check analytics.
中文简介正在准备中。当前显示原文说明。
Record per-PR architecture-review approval for design-artifact PRs (required by the architecture gate). ONLY on an explicit per-PR architect "approved".
中文简介正在准备中。当前显示原文说明。
Record per-PR design-review approval (UI merge gate). ONLY on an explicit per-PR designer "approved".
中文简介正在准备中。当前显示原文说明。