Skip to main content

debug

Diagnosis loop for bugs and performance regressions. Use when the user explicitly asks to diagnose or debug, or provides a concrete runtime failure, shares a log file or measured regression.

Source facts

Repository
davesnx/setup
Last source activity
September 7, 2026 at 20:22
Detected SKILL.md language
English
Stars
11
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
5 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
debug
description
Diagnosis loop for bugs and performance regressions. Use when the user explicitly asks to diagnose or debug, or provides a concrete runtime failure, shares a log file or measured regression.
# Debug Read enough code, tests, and logs to identify the reported behavior and the smallest useful check. When exploring the codebase, read `CONTEXT.md` (if it exists) to get a clear mental model of the relevant modules, and check ADRs in the area you're touching. ## Redact This skill has you show commands, outputs and captured artifacts. **Redact every secret first** — write `<REDACTED>` in its place. Build loops against env vars, so the credential stays in the environment rather than in what you show. Captured artifacts carry auth headers: quote only the lines that carry the signal. If the redacted output is not enough to diagnose the bug, say so and ask the user. ## Phase 1 — Build a feedback loop Build a check that distinguishes the reported failure from correct behavior. Initial code inspection and provisional hypotheses help choose that check; they are not proof of the cause. Prefer an existing focused test over a new harness. ### Ways to construct one — try them in roughly this order 1. **Failing test** at whatever seam reaches the bug — unit, integration, e2e. 2. **Curl / HTTP script** against a running dev server. 3. **CLI invocation** with a fixture input, diffing stdout against a known-good snapshot. 4. **Headless browser script** (Playwright / Puppeteer) — drives the UI, asserts on DOM/console/network. 5. **Replay a captured trace.** Save a real network request / payload / event log to disk; replay it through the code path in isolation. 6. **Throwaway harness.** Spin up a minimal subset of the system (one service, mocked deps) that exercises the bug code path with a single function call. 7. **Property / fuzz loop.** If the bug is "sometimes wrong output", run 1000 random inputs and look for the failure mode. 8. **Bisection harness.** If the bug appeared between two known states (commit, dataset, version), automate "boot at state X, check, repeat" so you can `git bisect run` it. 9. **Differential loop.** Run the same input through old-version vs new-version (or two configs) and diff outputs. 10. **HITL bash script.** Last resort. If a human must click, drive _them_ with `scripts/hitl-loop.template.sh` so the loop is still structured. Captured output feeds back to you. Run the check before changing the implementation when the environment permits it. ### Tighten the loop Treat the loop as a product. Once you have _a_ loop, **tighten** it: - Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.) - Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".) - Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.) A 30-second flaky loop is barely better than no loop; a 2-second deterministic one is tight — a debugging superpower. ### Non-deterministic bugs The goal is not a clean repro but a **higher reproduction rate**. Loop the trigger 100×, parallelise, add stress, narrow timing windows, inject sleeps. A 50%-flake bug is debuggable; 1% is not — keep raising the rate until it's debuggable. ### When you genuinely cannot build a loop State what you tried and what prevents reproduction. Continue useful source or log analysis, but label its conclusions as provisional. Ask for missing access, a redacted artifact, or instrumentation approval only when it blocks the next useful check. Do not claim a verified fix without evidence from the failing path. ### Completion criterion — a tight loop that goes red Runtime reproduction is established when you can name a command you have run (show its output, redacted) that is: - [ ] **Red-capable** — it drives the actual bug code path and asserts the **user's exact symptom**, so it can go red on this bug and green once fixed. Not "runs without erroring" — it must be able to _catch this specific bug_. - [ ] **Deterministic** — same verdict every run (flaky bugs: a pinned, high reproduction rate, per above). - [ ] **Fast** — seconds, not minutes. - [ ] **Agent-runnable** — you can run it unattended; a human in the loop only via `scripts/hitl-loop.template.sh`. Until then, keep investigation findings separate from reproduction evidence. ## Phase 2 — Reproduce + minimise Run the loop. Watch it go red — the bug appears. Confirm: - [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix. - [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against). - [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it. ### Minimise Once it's red, shrink the repro to the **smallest scenario that still goes red**. Cut inputs, callers, config, data, and steps **one at a time**, re-running the loop after each cut — keep only what's load-bearing for the failure. Why bother: a minimal repro shrinks the hypothesis space in Phase 3 (fewer moving parts left to suspect) and becomes the clean regression test in Phase 5. Stop reducing the reproduction when it isolates a testable cause. Do not spend time removing every input from an already decisive test. If reproduction is unavailable, retain that limitation when proceeding with source analysis. ## Phase 3 — Hypothesise Start with the cause best supported by the evidence. When several causes remain plausible, rank them and choose a check that distinguishes them. One clear cause does not require invented alternatives. Each hypothesis must be **falsifiable** — state the prediction it makes, or discard it as a vibe. > Format: "If <X> is the cause, then <changing Y> will make the bug disappear / <changing Z> will make it worse." Share competing explanations when the user's context could change the next check. Otherwise proceed with the focused test and report what it establishes. ## Phase 4 — Instrument Each probe must map to a specific prediction from Phase 3. **Change one variable at a time.** Tool preference: 1. **Debugger / REPL inspection** if the env supports it. One breakpoint beats ten logs. 2. **Targeted logs** at the boundaries that distinguish hypotheses. 3. Never "log everything and grep". **Tag every debug log** with a unique prefix, e.g. `[DEBUG-a4f2]`, so cleanup at the end is a single grep. **Perf branch.** For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, `performance.now()`, profiler, query plan), then bisect. Measure first, fix second. ## Phase 5 — Fix + regression test Write the regression test **before the fix** — but only if there is a **correct seam** for it. A correct seam is one where the test exercises the **real bug pattern** as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers, unit test that can't replicate the chain that triggered the bug), a regression test there gives false confidence. **If no correct seam exists, that itself is the finding**: the codebase architecture is preventing the bug from being locked down. Flag it for the next phase. If a correct seam exists: 1. Turn the minimised repro into a failing test at that seam. 2. Watch it fail. 3. Apply the fix. 4. Watch it pass. 5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario. ## Phase 6 — Cleanup + post-mortem Required before declaring done: - [ ] Original repro no longer reproduces (re-run the Phase 1 loop) - [ ] Regression test passes (or absence of seam is documented) - [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix) - [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location) - [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns **Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling), hand the specifics to the `improve-codebase-architecture` skill. Make the recommendation **after** the fix is in, not before — you have more information now than when you started.
View on GitHub