bugfix-pipeline
Skill23 starsChanged 2 months agoCC0-1.0View on GitHub
ALWAYS invoke this skill when the user reports a bug to fix — it traces the active code path, writes a failing test, iterates the fix, and reviews the diff, with test gates that prevent fixing the wrong code path. Do not edit suspected code directly before tracing the active path and writing a failing test. Triggers: "/bugfix", "fix bug", "investigate bug", "trace and fix", or a referenced issue ID. Do NOT use for new features (use /tdd), refactoring without bugs, or documentation changes.
In this repository8 other files it gives its agents.
- attack-surfaceSkill
- deep-researchSkill
- deploy-verifySkill
- first-principlesSkill
- naming-gateSkill
- shipSkill
- tddSkill
- wrap-upSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
23 rules. About 0 are common, 21 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈21
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
Ask an agent to fix a bug and it will grep for a plausible-looking function, find one, and fix it.
- Distinctive: line 27
Every gate below exists to make that failure impossible rather than unlikely:
- Distinctive: line 51
Before touching any code:
- Distinctive: line 59
Follow function calls and imports
- Distinctive: line 76
Ask: "Is this the correct active code path?
- Distinctive: line 78
Do NOT proceed until the user confirms.
- Very specific: line 88
Test framework and run command (detected the same way tdd does it in its Step 0)
- Distinctive: line 92
Test failure output (proving the bug exists)
- Distinctive: line 97
If the test passes → either the bug is already fixed, or the test doesn't reproduce the issue, or Step 1 traced the wrong path.
- Distinctive: line 105
Test file path (from Step 2)
- Distinctive: line 112
Test success output (all tests pass)
- Distinctive: line 114
GATE: All tests pass AND every modified file is within the traced active code path.
- Distinctive: line 116
If the implementer modified files outside the path → flag as a potential wrong-path fix and report to the user rather than accepting it.
- Distinctive: line 121
Do this directly (no subagent needed):
- Distinctive: line 123
Diff review: run git diff on modified files
- Distinctive: line 128
Regression check: run the FULL test suite, not just the new test
- Distinctive: line 129
All existing tests must still pass
- Distinctive: line 130
If any fail → the fix has side effects.
- Distinctive: line 175
ALWAYS: run the full test suite after the fix, not just the new test
- Distinctive: line 176
ALWAYS: verify modified files are within the traced code path
- Distinctive: line 185
Test: "sync 5000 records should succeed" — FAILS (parameter limit exceeded)
- Distinctive: line 191
No issue ID. Extracts: "search returns stale/cached results"
- Distinctive: line 194
Test: "search after a record update should return fresh data" — FAILS
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/bugfix — Bug-Fix Pipeline With Test Gates
Trace active code path → write failing test → iterate fix → review diff → report.
Prevents the most expensive failure mode in agent-assisted debugging: confidently fixing code that never runs.
Why the tracing step exists
Ask an agent to fix a bug and it will grep for a plausible-looking function, find one,
and fix it. The fix is often correct — applied to the wrong copy. Codebases accumulate
searchUsers() in a service and searchUsers() in a legacy helper nobody deleted; a
barrel file re-exports one of them; only one is actually imported by the running route.
The agent reports success, the tests it never ran still pass, and the bug survives.
Every gate below exists to make that failure impossible rather than unlikely:
- The path is traced and confirmed before any edit — so the target is known, not guessed.
- The test must fail first — proving the bug reproduces in the path you traced. A test that passes on the first run means you traced the wrong path (or the bug is gone).
- The fix is constrained to the traced files — an implementer that wanders outside them is a signal you're back to guessing.
Instructions
Step 0: Context Gathering
If the user references an issue ID and an issue tracker is available (Linear, Jira, GitHub Issues — via CLI, MCP server, or whatever this project uses): fetch it and extract expected behavior, actual behavior, and reproduction steps from the description and comments.
If not: extract the bug description from the user's prompt. A tracker is optional — everything below works from a plain description.
Always: detect the project from cwd and read whatever architecture docs it has
(README, ARCHITECTURE.md, CONTRIBUTING, or the project's own conventions file).
Step 1: Code Path Tracing (CRITICAL)
Before touching any code:
- Identify the entry point for the buggy behavior:
- API endpoint → find the route handler
- UI bug → find the component/view
- CLI/background job → find the command handler
- Trace the call chain forward from the entry point using Grep and Read:
- Follow function calls and imports
- At each step, verify which implementation is ACTUALLY imported (not a similarly-named duplicate)
- Pay special attention to: re-exported functions, barrel imports, service/repository layers with legacy copies
- Document the active code path:
Active Code Path: 1. routes/api/orders.ts:45 → handleOrderSearch() 2. services/orderService.ts:120 → searchOrders() 3. repositories/orderRepo.ts:88 → findByFilters() ← BUG IS HERE Also found (NOT active — dead code): - services/orderServiceLegacy.ts:50 → searchOrders() (unused, imported nowhere) - utils/searchHelpers.ts:30 → buildFilterConditions() (different code path) GATE: Present the traced code path to the user for confirmation. Ask: "Is this the correct active code path? Should I proceed with writing a failing test targeting [file:line]?"
Do NOT proceed until the user confirms.
Step 2: Write Failing Test (RED Phase)
Invoke the tdd-test-writer agent via the Agent tool with subagent_type: "tdd-test-writer".
Pass to agent:
- Bug description (expected vs actual behavior)
- Active code path from Step 1 (so the test imports the correct module)
- Project path
- Test framework and run command (detected the same way
tdddoes it in its Step 0)
Receive from agent:
- Test file path
- Test failure output (proving the bug exists)
- What each test verifies
GATE: The test must FAIL, proving the bug is reproduced in the active code path.
If the test passes → either the bug is already fixed, or the test doesn't reproduce the issue, or Step 1 traced the wrong path. Report and ask how to proceed — do not "fix" anything.
Step 3: Iterate Fix (GREEN Phase)
Invoke the tdd-implementer agent via the Agent tool with subagent_type: "tdd-implementer".
Pass to agent:
- Test file path (from Step 2)
- Bug description (brief — 1-2 sentences)
- Active code path constraint: "Only modify files in the active code path: [list]. Do NOT modify files outside this list."
- Test run command
Receive from agent:
- Files modified (must be a subset of the active code path files)
- Test success output (all tests pass)
GATE: All tests pass AND every modified file is within the traced active code path.
If the implementer modified files outside the path → flag as a potential wrong-path fix and report to the user rather than accepting it.
Step 4: Review & Report
Do this directly (no subagent needed):
- Diff review: run
git diffon modified files- Were any test files modified? (violation — the test is the spec)
- Were files outside the active code path changed? (flag)
- Any new
// TODOor// HACKcomments? (warn)
- Regression check: run the FULL test suite, not just the new test
- All existing tests must still pass
- If any fail → the fix has side effects; report details
- Generate report:
## Bug Fix Report
**Issue:** [ID](url) — Title
**Status:** Fixed, pending approval
### Active Code Path
1. `file:line` → function()
2. `file:line` → function()
3. `file:line` → function() ← ROOT CAUSE
### Root Cause
[Brief explanation of why the bug occurs]
### Fix Applied
[What was changed and why]
### Files Modified
| File | Change |
|------|--------|
| path/to/file.ts | Description of change |
### Test Coverage
| Test | Status |
|------|--------|
| new-test.test.ts | N tests PASS |
| Full suite | N tests PASS, 0 failures |
### Side Effects
None detected / [details if any]- Ask the user: "Ready to commit and push? Or do you want to review the diff first?"
Hard Rules (Never Break)
- NEVER modify code before tracing the active code path (Step 1)
- NEVER skip user confirmation of the traced path
- NEVER modify test files during the fix phase (Step 3)
- NEVER push without user approval
- NEVER let the implementer weaken test assertions
- ALWAYS run the full test suite after the fix, not just the new test
- ALWAYS verify modified files are within the traced code path
Examples
Example 1: Duplicate functions
User says: /bugfix ENG-233 — "Record sync fails on collections with >3000 items"
- Fetches the issue (or takes the description straight from the prompt)
- Traces:
routes/api/sync.ts → syncService.ts → batchInsert(). FindsbatchInsertLegacy()in the same file (dead code). ConfirmsbatchInsert()is the active path. - User confirms the path
- Test: "sync 5000 records should succeed" — FAILS (parameter limit exceeded)
- Fix: chunks
batchInsertinto 500-item batches — test PASSES - Full suite: 42/42 pass. Report generated.
Example 2: No issue ID, ambiguous code
User says: "fix the search returning stale results"
- No issue ID. Extracts: "search returns stale/cached results"
- Traces:
routes/search.ts → searchService.ts → runQuery() → cache.get(). Identifies a cache TTL issue. - User confirms: "Yes, the cache is the problem"
- Test: "search after a record update should return fresh data" — FAILS
- Fix: adds cache invalidation on update — PASSES
- Full suite: all pass. Report generated.
Example 3: Test already passes (the useful failure)
User says: /bugfix ENG-45
- Fetches the issue, traces the code path
- Writes a test reproducing the described bug — the test PASSES
- Reports: "The test passes, meaning the described behavior doesn't reproduce. Either the bug was fixed in a recent commit, the reproduction steps need adjustment, or the traced path isn't the one the bug lives in. How should I proceed?"
This is the gate earning its keep: without it, Step 3 would have "fixed" a bug that wasn't there and reported success.
Requirements
tdd-test-writerandtdd-implementeragents. Both ship with thetddskill in this repo — copy itsagents/files to~/.claude/agents/.- A project with a runnable test suite.
See Also
tdd— the full Red-Green-Refactor cycle for new behavior./bugfixis its counterpart: same discipline, but the failing test's job is to reproduce a defect rather than specify a feature. Route by intent — new behavior →/tdd, something broken →/bugfix, pure refactor → neither.
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.

