← All craftbooks

Reproduce-Then-Fix a Bug

Build: software and codeevalv1.0.1released 2026-07-16workflow: build-loop

Fix a bug the disciplined way: first write a failing test that reproduces it, then make the smallest change that turns the test green without breaking others, then verify and guard against regression. Reproduces FIRST with a red test that captures the exact wrong behavior — because a bug you cannot reproduce you cannot prove fixed — then applies the minimal fix, then a reviewer confirms the new test passes, root cause is addressed, and the suite is green. Covers test-driven bug fixing, regression tests, minimal diffs, root-cause vs symptom, and red-green verification.

Steps

Entry step: reproduce. Each step names the specialist role it wants; the full working prompt is expandable.

  1. Reproduce with a failing testdeveloperentry

    write a red test that captures the wrong behavior

    Show working prompt
    Reproduce the bug as a failing test before attempting any fix — a bug you cannot reproduce you cannot prove fixed. Step 1: Pin down the exact wrong behavior: the input, the expected output, and the actual (buggy) output. Step 2: Write a focused test that asserts the CORRECT behavior; run it and confirm it FAILS (red) for the right reason — capturing the bug, not a typo in the test. Step 3: Note your hypothesis for the root cause (not just the symptom). Step 4: Write a numbered acceptance-criteria checklist of 4-7 items (e.g. 'the new test fails before the fix and passes after', 'the root cause is addressed, not masked', 'no existing test regresses', 'the input that triggered the bug now produces the expected output'). `write_task_note` the repro + hypothesis + checklist and write the failing test to the produces path.
  2. Apply the minimal fixdeveloper

    smallest change that turns the test green

    Show working prompt
    Make the smallest change that turns the failing test green. Step 1: Address the ROOT CAUSE you identified, not just the symptom — do not special-case the one input to silence the test. Step 2: Run the new test and confirm it now passes (green). Step 3: Run the FULL suite and confirm nothing else broke; if something regressed, your fix was too broad — narrow it. Step 4: Keep the diff minimal and focused on the bug. Write the fixed source to the produces path. On a loop-back, address only the reviewer's specific concern. `write_task_note` what the root cause was, the fix, and which criteria now pass.
  3. Verify the fixreviewer

    confirm green, root cause fixed, no regressions

    Show working prompt
    Verify the bug is genuinely fixed. Step 1: Run the repro test and confirm it now passes. Step 2: Confirm the fix addresses the root cause rather than masking the symptom (would a nearby variant of the input also be correct now?). Step 3: Run the full suite and confirm no regressions. Step 4: Confirm the diff is minimal and scoped to the bug. Write a verification note with the test results and a root-cause-vs-symptom judgment to the produces path.
  4. Evaluatereviewer

    Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.

    Show working prompt
    Run the full test suite including the new repro test. For EACH acceptance criterion: confirm the repro test now PASSES (and would have failed before the fix), confirm the root cause is addressed not just masked, confirm no existing test regressed, and confirm the diff is minimal. Write PASS/FAIL per criterion.
    
    Then route — this is the whole point of the loop:
    
    - **Every criterion PASSES →** call `advance_task_step({ ref, stepId: "evaluate", next: "finish" })`.
    - **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: "evaluate", next: "fix" })` to loop back. The builder fixes exactly those gaps.
    
    Never route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in.
  5. Finishdeveloper

    All acceptance criteria met. Stamp a short summary and report DONE.

    Show working prompt
    Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.

Triggers

Phrases that suggest this craftbook to a crew.

Source

View this craftbook on GitHub · MIT license