Debug
Installable Python agent workflow: AGENTS.md rules plus skills for scaffold, TDD, debugging, refactoring, and handoff.
npx -y skills add DavisMcCracken/pyxis --skill debugAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Diagnose hard or uncertain bugs, reproduce-first — build a feedback loop before hypothesizing. Use when reproduction or cause is unclear, the failure is intermittent or cross-system, or performance regressed.
SKILL.md
5.9 KB, as published. Nobody here has run it
Debug
Discipline for hard bugs. Skip a phase only with stated justification. Ordinary bug with an obvious repro? The AGENTS.md rule (failing test, then fix) suffices — this skill is the escalation path.
Before exploring, load the project's domain glossary (CONTEXT.md, if present) and check ADRs near the affected area.
Phase 1 — Build a feedback loop
This phase IS the skill. A tight, agent-runnable pass/fail signal makes the rest mechanical — bisection, hypothesis tests, and instrumentation all just consume it. Without one, staring at code is all you have.
Spend disproportionate effort here.
Construction options, roughly in order
- Failing test at whatever seam reaches the bug — unit, integration, e2e.
- HTTP script (curl etc.) against a running dev server.
- CLI run on a fixture input, output diffed against a known-good snapshot.
- Headless browser script (Playwright) asserting on DOM/console/network.
- Trace replay — capture a real request/payload/event log, replay it through the code path in isolation.
- Throwaway harness — minimal slice of the system (one service, faked deps) hitting the bug path in a single call. Follows the AGENTS.md spike convention:
spike_*.py,THROWAWAYheader, PEP 723 deps if standalone. - Property/fuzz loop — for "sometimes wrong output", randomized inputs hunting the failure;
hypothesiswith its saved failing example beats a hand-rolled loop. - Bisection harness — bug appeared between two known states? Automate "boot at X, check" so
git bisect runcan drive it. - Differential loop — same input through old vs new version (or two configs), diff the outputs.
- HITL script — last resort when a human must click. Drive them with
scripts/hitl-loop.template.shso even manual steps feed structured output back.
Then make the loop tight
A tight loop is the product; treat it as one:
- Faster — cache setup, skip unrelated init, narrow scope (
uv run pytest --last-failed -xfor test-shaped loops). - Sharper — assert the exact symptom, not "didn't crash".
- More deterministic — inject the clock, seed RNG, isolate filesystem via
tmp_path, freeze network.
A 30-second flaky loop barely beats none; make it 2 seconds.
Non-deterministic bugs
Chase reproduction rate, not perfection: loop the trigger 100×, parallelise, add stress, squeeze timing windows. 50% flake is debuggable; 1% is not. Raise the rate until it is.
Genuinely can't build one?
Say so explicitly, list what you tried, and ask the user for: (a) access to a reproducing environment, (b) a captured artifact (HAR, log dump, core dump, timestamped recording), or (c) permission for temporary production instrumentation. Never hypothesise loopless.
Gate: the loop goes red on the bug, or there's no Phase 2.
Phase 2 — Reproduce
Run the loop; watch the bug happen. Confirm:
- It's the failure the user described, not a nearby lookalike — wrong bug = wrong fix
- Reproducible across runs (or at a rate high enough to debug)
- Exact symptom captured (message, wrong value, timing) so the fix can be verified against it
Gate: not reproduced → not diagnosed.
Phase 3 — Hypothesise
Write 3–5 ranked hypotheses before testing any — a single hypothesis anchors you to the first plausible story.
Each must be falsifiable, with its prediction stated:
"If <X> is the cause, then <changing Y> makes the bug vanish / <changing Z> makes it worse."
No prediction = vibe. Sharpen or discard.
Show the ranked list to the user before probing — they often re-rank instantly ("we deployed #3's area yesterday") or kill hypotheses they've already ruled out. Don't block on a reply; proceed with your ranking if they're AFK.
Phase 4 — Instrument
Every probe maps to one Phase 3 prediction. One variable at a time.
- Debugger / REPL first where the env allows — one breakpoint beats ten logs.
- Targeted logs at the seams that distinguish hypotheses.
- Never "log everything and grep".
Tag every debug log with a unique prefix ([DEBUG-a4f2]) — cleanup becomes one grep. Untagged logs outlive the bug.
Performance regressions: logs lie about time. Baseline first (timing harness, profiler, query plan), then bisect. Measure, then fix.
Phase 5 — Fix + regression test
Regression test before the fix — the AGENTS.md bug rule — but only at a correct seam: one where the test exercises the real bug pattern as it occurred at the call site. A too-shallow seam (single-caller unit test for a multi-caller interaction bug) gives false confidence.
No correct seam? That IS a finding. Document it — the architecture is blocking the bug from being locked down — and flag it for Phase 6.
With a correct seam:
- Minimised repro → failing test at that seam
- Watch it fail
- Apply the fix
- Watch it pass (
uv run pytest --last-failed -xwhile iterating) - Re-run the Phase 1 loop on the original, un-minimised scenario
Phase 6 — Cleanup + post-mortem
Done means:
- Original repro dead (Phase 1 loop re-run)
- Regression test green — or the missing seam documented
- All
[DEBUG-...]instrumentation gone (grep the prefix) - Throwaway harnesses deleted —
spike_*.pynever merges - Full verify loop green (
uv run ruff check --fix && uv run ruff format && uv run ty check && uv run pytest) - Winning hypothesis stated in the commit/PR message — the next debugger learns
Last question: what would have prevented this? If the answer is architectural (no test seam, tangled callers, hidden coupling), hand the specifics to refactor — after the fix lands, not before. You know more now.