
Behavior-Preserving Refactor
Refactor a module to improve its structure, readability, or design WITHOUT changing observable behavior — the defining constraint is that the tests stay green throughout. Plans the refactor FIRST — the target structure, the seams to introduce, the safe step sequence, and the green-tests guardrail — then refactors in small reversible steps, then a reviewer confirms behavior is unchanged and the code is genuinely cleaner. Covers extract-function/module, dependency seams, removing duplication, naming, and test-green-as-invariant refactoring.
Steps
Entry step: plan. Each step names the specialist role it wants; the full working prompt is expandable.
- Plan the refactorplannerentry
lock target structure, steps, green-tests guardrail
Show working prompt
Plan the refactor before touching code — the prime directive is preserving behavior. Step 1: Identify the specific smells (duplication, long function, tangled responsibilities, poor names) and the target structure you want. Step 2: Confirm there is a test safety net; if coverage is thin, note the characterization tests to add FIRST so behavior is pinned before changing structure. Step 3: Break the work into small, individually-reversible steps (extract this function, introduce this seam, rename that), each of which keeps tests green. Step 4: Write a numbered acceptance-criteria checklist of 5-9 items (e.g. 'all existing tests pass before and after', 'public API/behavior is unchanged', 'the targeted duplication is gone', 'no function exceeds N lines / responsibilities are separated'). `write_task_note` the plan + checklist and write the same to the produces path.
- Refactordeveloper
apply small reversible steps, tests green throughout
Show working prompt
Execute the refactor in small steps, keeping the tests green the entire time. Step 1: If the plan called for characterization tests, add them first and confirm they pass against current behavior. Step 2: Apply one planned step at a time — extract, rename, dedupe, introduce a seam — and run the tests after EACH step; if a step breaks them, revert it and try smaller. Step 3: Do not change public signatures or observable behavior unless the plan explicitly says so. Step 4: Stop when the target structure is reached and the smells are gone. Write the refactor summary (what changed structurally, tests still green) to the produces path. On a loop-back, address only the reviewer's points. `write_task_note` the summary and which criteria now pass.
- Verify behavior preservedreviewer
confirm tests green and code is genuinely cleaner
Show working prompt
Verify the refactor preserved behavior and actually improved the code. Step 1: Run the full test suite and confirm it is green (this is the hard gate). Step 2: Confirm the public API/observable behavior is identical to before. Step 3: Confirm the targeted smell is actually fixed — the duplication is gone, the function is decomposed, names are clearer — not just moved around. Step 4: Confirm no behavior was sneaked in under cover of the refactor. Write a verification note with the test result and a before/after readability assessment to the produces path.
- Evaluatereviewer
Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.
Show working prompt
Run the test suite. For EACH acceptance criterion: confirm ALL existing tests pass (green is mandatory), confirm public behavior is unchanged, confirm the targeted smell is genuinely fixed, and confirm no new behavior crept in. Write PASS/FAIL per criterion; a single failing test is an automatic FAIL of the whole refactor. 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: "refactor" })` 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. - 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.
- refactor this module
- clean up the code
- improve code structure
- behavior-preserving refactor
- reduce duplication
Source
View this craftbook on GitHub · MIT license