| name | bug-fix |
| description | Investigate, reproduce, and safely fix a bug with regression protection. Composes context, diagnosis, architecture, code quality, and testing guardrails into a reproduce-first repair workflow. Use when the user says 'fix this bug', 'debug this', 'investigate this failure', 'patch this regression', 'repair this issue', or 'why is this broken'. |
Bug Fix
Required Skills
Load these skills based on bug scope:
framework:knowledge-priming -- Load project context so the diagnosis grounds in the real codebase. (always)
framework:context-anchoring -- Find and load the feature's context doc; capture diagnosis and repair decisions in it. (always)
framework:learning-harvest -- Load prior operational learnings at session start; harvest new ones at session end. (always)
framework:collaborative-judgment -- Surface hypotheses and repair trade-offs as structured options instead of silently assuming. (always)
framework:clean-code -- Keep the fix focused, readable, and free of drive-by changes. (always)
framework:test-quality -- Regression tests, characterization baseline, assertion quality. (always)
framework:architecture -- Layer placement and dependency direction. (conditional: layer placement is in question — Steps 2/4/5)
framework:domain-driven-design -- Domain invariants and aggregate behavior. (conditional: domain invariants involved — Steps 2/5)
framework:secure-coding -- Trust bounds and sensitive data handling. (conditional: trust boundary crossed — Steps 2/5)
Workflow
Step 1: Establish Bug Context
Start from the failure, not from a proposed fix.
- Gather the observed behavior, the expected behavior, the reproduction path, and any evidence: failing test, error message, stack trace, log excerpt, request payload, recent change.
- Run
framework:learning-harvest Load behavior. Focus hint: "bug investigation — focus: reliability, quality signals".
- Run
framework:context-anchoring Document Discovery to check for an existing context doc covering the affected feature/module:
- Found → Load behavior. Honor every logged decision and constraint as an active commitment while diagnosing. An open investigation of this same bug is already logged in it → confirm with the user whether to resume that investigation or start fresh.
- Not found → Proceed from the bug report and the current code. Do not block diagnosis on a missing context doc.
End the step by summarizing the bug in one sentence:
"Observed X, expected Y, reproducible via Z."
STOP: If you cannot yet state the bug that clearly, gather more evidence before proposing any code changes.
Step 2: Reproduce and Localize
Primary discipline: never present a fix for a bug you have not reproduced.
Reproduce the failure using the strongest evidence available, in this order:
- Existing failing automated test -- best case; use it as the regression guard.
- New failing automated test -- preferred when no test exists yet.
- Executable reproduction path -- command, request sequence, or deterministic manual flow when automation is not yet possible.
Localize the issue before editing:
- Which layer is the likely source? Use the layer definitions from
framework:architecture to identify which architectural layer the defect originates in.
- Production bug or test bug? Sometimes the code is correct and the test or fixture is wrong.
- Failure symptom or root cause? The crashing line is often downstream of the real defect.
- Does the bug cross a trust boundary? If yes,
framework:secure-coding applies to the fix (Step 5).
- Does it involve domain invariants or aggregate behavior? If yes,
framework:domain-driven-design applies to the fix (Step 5).
- Will the likely fix touch multiple layers or dependency flow? If yes,
framework:architecture applies to the fix (Steps 4–5).
If multiple plausible root causes remain, use framework:collaborative-judgment to present the leading hypotheses and what evidence would distinguish them.
Before writing any regression test, state the root-cause hypothesis explicitly via framework:collaborative-judgment:
"The bug is caused by [X]. When [C holds], the correct outcome should be [P].
We confirm this by writing a test that is red before the fix and green after."
If the user identifies a flaw in the hypothesis, revise it before writing tests.
End the step with an explicit bug contract:
C (bug condition): [exact input/state triggering the bug]
P (fix postcondition): [what correct behavior looks like when C holds]
Preserved: [what must remain identical for all inputs outside C]
STOP: If you cannot state all three, keep localizing before writing tests.
Persistence check — now that the bug is reproduced and localized, decide whether to persist the investigation:
- Investigation is complex, involves multiple hypotheses, or is likely to span multiple sessions → ask whether the user wants to persist the diagnosis and repair decisions.
- A relevant context doc exists → enrich it in Step 7.
- None exists and the user wants persistence → propose creating one; confirm the doc name per
framework:context-anchoring, then use it as the source of truth.
- The user declines persistence, or the bug is narrow and local → continue in non-persistent mode. The repair workflow still applies; decisions remain in-session.
Step 3: Add Regression Protection First
Phase A — Bug-Condition Tests (must start RED)
- Write the smallest failing test that fires when C holds.
- Prefer the lowest-level test that reproduces the real failure without losing signal.
- Name the test for the broken behavior, not the implementation detail.
- Assert the correct expected outcome (postcondition P), not just the absence of failure.
- Apply
framework:test-quality inline while writing it.
- Run it against the unfixed code where the environment allows, and confirm RED. If tests cannot be executed here, say so explicitly — the reproducer then counts as unverified, and the limitations below apply.
- Green before any fix → the bug-condition hypothesis is wrong. STOP: Do not proceed — return to Step 2 and re-localize.
Stopping rule:
- STOP: If no stable failing automated test can be created or executed, explain why before making any code changes.
- Record the closest executable reproduction you have.
- STOP: Never present a speculative fix as complete without an automated reproducer unless the user explicitly accepts the limitation.
- The bug cannot be tested directly because of tight coupling or deep integration → introduce the minimum structural seam needed to make it testable (method extraction, parameter injection, interface boundary). This is not refactoring — it is a prerequisite for regression protection. Apply
framework:clean-code inline and keep the seam minimal.
Phase B — Preservation Baseline (must stay GREEN)
- Identify existing tests covering behavior outside C.
- Important adjacent behavior has no coverage → add at most 2–3 targeted characterization tests.
- Confirm every preservation-baseline test is green before applying the fix.
- These tests must remain green through every change in Step 5 — any flip to red means the fix has side effects; stop and narrow the scope.
Step 4: Choose the Minimal Safe Fix
Separate the repair strategy from the code change itself.
Before editing, decide:
- What is the root cause?
- What is the smallest safe change that corrects it?
- Which layer is the right repair location?
- Does the issue require a local patch or a small structural correction?
Default to the smallest safe fix that restores correct behavior without architectural backsliding.
Guardrails:
- Apply
framework:architecture layering rules when choosing the repair location — do not patch in an outer layer when the rule belongs inward.
- Do not widen the task into unrelated cleanup.
- Do not delete or weaken the failing test just to make the suite green.
- A real fix requires a contract or design change beyond the narrow repair → stop and discuss scope explicitly; if the user agrees the scope is a design change, route to
/design-blueprint.
- Do not add guard clauses, null checks, or defensive handling for inputs outside C — the code path for correct inputs must be byte-for-byte identical before and after the fix.
Multiple valid repair strategies exist with meaningful trade-offs → present them using framework:collaborative-judgment before proceeding.
Step 5: Implement the Fix
Always apply:
framework:clean-code -- keep the delta focused, readable, and easy to reason about.
framework:test-quality -- maintain the regression test and any nearby supporting tests.
Conditionally apply, based on the localized root cause:
- Fix changes layer responsibilities, dependency direction, or architectural flow → apply
framework:architecture.
- Fix changes domain behavior, invariants, aggregate boundaries, or value objects → apply
framework:domain-driven-design.
- Fix touches input validation, authorization, queries, external boundaries, or sensitive data → apply
framework:secure-coding.
After implementing the fix, before presenting:
- Re-run the regression test and confirm it is now green. Tests cannot execute in this environment → state that explicitly; never imply the test passed unrun.
- Run the applicable atoms' Self-Validation Checklist sections against the changed code.
- Run the applicable atoms' Active Anti-Pattern Scan checklists.
- Fix violations before presenting the result.
Step 6: Verify Non-Regression
Verify the repair on three levels:
- Fix proof -- the regression test that was red before the fix is now green, asserting the correct outcome rather than just the absence of the original failure.
- Preservation proof -- tests covering behavior adjacent to the bug still pass. Preservation-baseline tests added in Step 3 must remain green. Any flip from green to red means the fix has side effects — stop and narrow the scope before continuing.
- Structural confidence -- the fix introduced no wrong-layer workaround, no dependency violation, no weakened security posture.
When reporting completion, be explicit about the verification scope:
- What was re-run.
- What now passes.
- What was not verified, and why.
If the fix is narrow and confidence is high, say so briefly. If verification is partial, say so clearly.
Step 7: Capture Root Cause and Close the Loop
If a context doc is active (persistence accepted in Step 2), use framework:context-anchoring Enrich to preserve the important parts of the repair. In non-persistent mode, skip to the harvest below:
- Bug summary: observed vs expected behavior.
- Root cause: what actually failed, and where.
- Repair decision: why this fix was chosen over the alternatives.
- Protection added: the regression test or executable reproducer now guarding the behavior.
- Key files changed: path + role in the doc's Key Files table (skip a path already listed).
No context doc exists and the fix exposed a non-trivial design or domain lesson → suggest creating one so the lesson survives the session.
Harvest learnings: run framework:learning-harvest Harvest behavior. Session context: "bug investigation — root cause diagnosis and repair". Synthesize and propose cross-cutting patterns from this session — root-cause categories, failure modes likely to recur elsewhere, boundary-condition gaps. The user confirms what enters the document. STOP: run this before recommending /review below.
After the fix is complete, recommend /review when the change:
- touches multiple layers
- changes security-sensitive code
- changes domain behavior
- introduces a non-trivial structural correction