Step 3 · Execute
Goal
Execute the refactoring plan one step at a time, verifying tests pass after every single step. Ship a codebase that is measurably better, with zero behaviour change.
Instructions
You are in workflow step 3 of the refactor-cycle. The plan is in TODO.md. Now execute it with discipline.
The Refactoring Loop
For each step in TODO.md, repeat this exactly:
READ the step
↓
CONFIRM tests are currently passing before starting
↓
MAKE the one atomic change described in the step
↓
RUN the test suite — must still be fully green
↓
IF tests fail:
→ Do NOT continue
→ Do NOT make more changes to try to fix it
→ Understand why the test failed
→ Revert if the failure can't be fixed in one small targeted change
→ Document what went wrong
↓
IF tests pass:
→ COMMIT with message: "refactor: [what you did]"
↓
MARK the step DONE in TODO.md
↓
REPEAT for next step
Every step gets its own commit. No bundling.
Tasks to Perform
0. Pre-execution baseline
[full test runner command]
# All tests must be passing before you begin
1. Execute Step-by-Step
Pick the first undone task from TODO.md. Do exactly what it says. Nothing more.
After each step:
# Run tests — must be 100% green
[test runner command]
# Confirm no debug output accidentally left in
grep -rn "var_dump\|console\.log\|dd(\|print_r\|debugger\|die(" src/ | grep -v test
# Commit
git add -p # stage only the refactoring change (not any unrelated edits)
git commit -m "refactor: [description of what was extracted/moved/renamed]"
2. Rename Protocol
When renaming a symbol (function, class, variable):
# Find all usages first
grep -rn "OldName" --include="*.{php,js,ts,py,go,rb}" . | grep -v node_modules | grep -v vendor
# After renaming, verify you got all of them
grep -rn "OldName" --include="*.{php,js,ts,py,go,rb}" . | grep -v node_modules | grep -v vendor
# Expected: no results
3. Move Protocol
When moving a function from Class A to Class B:
- Add the function to Class B (don't remove from Class A yet)
- Run tests — pass
- Update Class A to delegate to Class B
- Run tests — pass
- Remove function body from Class A
- Run tests — pass
- Commit
4. Extract Protocol
When extracting a block of code into a new function:
- Write the new function (copy, don't cut)
- Run tests — pass
- Replace the original block with a call to the new function
- Run tests — pass
- Remove the copied code from the original location
- Run tests — pass
- Commit
5. Do Not Mix Changes
If you notice a bug or want to add a feature during a refactoring:
- Stop
- Note it in TODO.md as a separate task using
- [ ] [prefix]: [description] _(ref: workflows/refactor-cycle/03-execute.md)_ - Complete the refactoring step you are on
- Then address the bug/feature in a separate commit
Status rules: [ ] = not started · [~] = in progress (one at a time) · [x] = done (prefix the date: - [x] YYYY-MM-DD refactor: …)
Quality Gate (after all steps complete)
When all refactoring tasks are done, verify the success criteria:
# Run the full test suite — must pass
[full test runner]
# Compare metrics before and after
wc -l [refactored files] # should be smaller or better organised
# Optional: run complexity analysis
[complexity tool if available]
# Check that the public interface is unchanged
git diff [first-refactor-commit]^..HEAD -- [public API files]
Check every item from the success criteria defined in Step 2.
Commit the Final Summary
After all steps are done:
git log [start-commit]..[HEAD] --oneline # shows all the refactoring commits
A good refactoring history looks like:
refactor: add PasswordService with hash/verify methods
refactor: inject PasswordService into UserService, update all callers
refactor: remove hash/verify from UserService (now in PasswordService)
refactor: add UserValidator with password policy checks
refactor: delegate UserService.validatePasswordPolicy to UserValidator
refactor: remove duplicate password validation from UserService
test: add isolated tests for PasswordService
test: add isolated tests for UserValidator
Closing
Update docs/refactoring/REFACTOR-MODULE-NAME.md:
## Status: Completed YYYY-MM-DD
### Outcome
[What improved]
### Metrics
| Metric | Before | After |
|---|---|---|
| Lines in largest class | 450 | 120 |
| Test count | 24 | 31 |
| Cyclomatic complexity | 18 | 6 |
Exit Criteria
This step is complete when:
- [ ] All refactoring steps in TODO.md are marked done
- [ ] Full test suite passes
- [ ] Every success criterion is met
- [ ] Refactoring doc updated with outcome
- [ ] No mixed commits (every commit is either refactor, test, or fix — not combined)