Focused Refactor
Improve code structure without changing behavior. Zero behavior change is non-negotiable.
Steps
- Establish green baseline:
- Run the full test suite and confirm all tests pass
- Run the type checker (
tsc --noEmit,go vet,cargo check,mypy) - If tests don’t exist for the code being refactored, stop and suggest using
/test-first - Record the test results as the baseline
- Identify the refactoring:
- Clarify what the user wants to improve (or suggest based on code smells)
- Common refactorings: rename, extract function/method, inline, simplify conditionals, remove duplication, split file, consolidate imports
- Scope the change — one refactoring at a time
- Apply the refactoring:
- Make the minimum changes necessary
- Update all references (imports, call sites, type definitions)
- Preserve all public API contracts
- Don’t change test assertions — tests are the behavior contract
- Verify behavior is preserved:
- Run the full test suite again
- Run the type checker again
- Compare results to baseline — must be identical pass/fail
- If tests fail — revert immediately:
git checkout -- .to discard changes- Analyze why the refactoring broke tests
- Try a different, safer approach
- Never fix tests to accommodate refactoring — that means behavior changed
- Final checks:
- Run linter to confirm no new warnings
- Show the diff summary to the user
- Confirm the refactoring achieved the intended improvement
Important
- Zero behavior change is the rule. If any test fails after refactoring, revert. No exceptions.
- Don’t combine refactoring with feature work. Refactor in one commit, features in another.
- Tests are the contract. If you need to change tests, you’re not refactoring — you’re changing behavior.
- One refactoring per pass. Don’t rename AND extract AND simplify in one go.
- If no tests exist, stop. Refactoring without tests is guessing. Write tests first.