---
name: safe-refactor
description: |
When refactoring, rewriting, or migrating critical code paths, orchestrate a
safe cycle: assess risks → implement → verify → document. Chains pre-mortem
and prove-it with built-in implementation phase. Prevents "refactor broke
production" disasters. Activates on "refactor", "rewrite", "migrate", or
"clean up" for non-trivial code.
allowed-tools: |
bash: git, grep, find, npm, pytest, jest
file: read, write
---
# Safe Refactor
An elixir for risky code changes. Refactors feel safe ("I'm just cleaning up")
but they're where bugs hide. This chains risk assessment → careful implementation
→ verification → documentation. The ceremony slows you down just enough to
catch problems before production does.
## Prerequisites
This elixir works best with these skills installed:
| Skill | Purpose | If Missing |
|-------|---------|------------|
| pre-mortem | Risk assessment before starting | Falls back to built-in checklist |
| prove-it | Verification enforcement | Falls back to built-in verification |
| retrospective | Document learnings | Skipped (optional phase) |
## When To Activate
- "Refactor this"
- "Clean up this code"
- "Rewrite this to be more..."
- "Migrate from X to Y"
- "Replace this implementation"
- Large-scale find-and-replace
- Changing shared utilities or core abstractions
- Touching code you didn't write
## Instructions
### Phase 1: Assess Risk
**If pre-mortem skill installed:** Invoke it now.
**If not installed, evaluate:**
```markdown
## Refactor Risk Assessment
**What's changing:**
- [ ] Files affected: [list them]
- [ ] Functions/classes modified: [list them]
- [ ] Estimated lines changed: [number]
**Risk factors:**
- [ ] Touches shared/core code (used by multiple features)
- [ ] Affects data persistence (database, files, cache)
- [ ] Changes public API/interfaces
- [ ] Lacks test coverage
- [ ] Written by someone else / unfamiliar code
- [ ] Production-critical path
**Risk level:** [Low / Medium / High / Abort]
```
**GATE:** Do not proceed if:
- Risk is "Abort"
- More than 3 risk factors checked AND no tests exist
- You can't list all affected files
If high risk: Consider breaking into smaller refactors.
### Phase 2: Prepare
Before touching code:
1. **Ensure tests exist** (or write them first)
```
- [ ] Existing tests cover the behavior being preserved
- [ ] If no tests: write characterization tests NOW
```
2. **Create escape hatch**
```bash
git stash # or commit current state
git checkout -b refactor/[description]
```
3. **Document current behavior**
```
Before: [How it works now]
After: [How it should work - must be identical externally]
```
**GATE:** Do not proceed without:
- Tests that verify current behavior
- Clean git state (can revert easily)
- Clear before/after behavior description
### Phase 3: Implement
**Rules for safe refactoring:**
1. **One thing at a time**
- Don't mix refactoring with feature changes
- Don't fix bugs you discover (note them, fix separately)
- Don't "while I'm here" other improvements
2. **Small commits**
```bash
# Good: multiple small commits
git commit -m "Extract helper function"
git commit -m "Rename variables for clarity"
git commit -m "Move file to new location"
# Bad: one giant commit
git commit -m "Refactor everything"
```
3. **Run tests frequently**
- After each logical change
- Before each commit
- If tests fail: revert and try smaller steps
4. **Preserve behavior exactly**
- No "improvements" to logic
- No fixing edge cases (that's a separate change)
- External behavior must be identical
### Phase 4: Verify
**If prove-it skill installed:** Invoke it now.
**If not installed:**
```markdown
## Refactor Verification
**Automated checks:**
- [ ] All existing tests pass
- [ ] No new linter errors
- [ ] Type checking passes (if applicable)
**Manual verification:**
- [ ] Tested the primary use case manually
- [ ] Checked one edge case
- [ ] Compared behavior before/after for critical paths
**Regression check:**
- [ ] git diff shows only intended changes
- [ ] No accidental behavior changes
- [ ] No debug code left in
```
**GATE:** Do not merge until all checks pass.
If verification fails:
```bash
git revert HEAD # or reset to before refactor
# Start over with smaller scope
```
### Phase 5: Document (Optional)
**If retrospective skill installed:** Invoke for significant refactors.
For large refactors, capture:
- What was refactored and why
- Any tricky parts or gotchas discovered
- Patterns that emerged (potential future skills)
## Output Format
```markdown
## Safe Refactor: [Description]
### Risk Assessment
- Risk level: [Low/Medium/High]
- Files affected: [count]
- Risk factors: [list]
### Preparation
- [x] Tests verified/written
- [x] Branch created: refactor/[name]
- [x] Current behavior documented
### Implementation
- Commits: [count]
- Approach: [brief description]
### Verification
- [x] Tests pass
- [x] Manual verification complete
- [x] No regressions detected
### Learnings (if significant)
[What you'd do differently]
```
## NEVER
- Refactor and add features in the same change
- Skip the risk assessment ("it's just a small cleanup")
- Make large changes without test coverage
- Commit all changes in one giant commit
- "Fix" bugs discovered during refactoring (note them separately)
- Proceed when tests are failing
## ALWAYS
- Assess risk before starting
- Ensure tests exist (write them if needed)
- Work on a branch with escape hatch ready
- Make small, incremental commits
- Run tests after each logical change
- Verify behavior is preserved exactly
## Example
**User:** "Refactor the authentication module to use the new token format"
**Phase 1 - Risk Assessment:**
> Refactor Risk Assessment:
> - Files affected: auth.ts, token.ts, middleware.ts, 12 test files
> - Risk factors: ✓ Core code, ✓ Production-critical, ✓ Written by someone else
> - Risk level: **High**
>
> Recommendation: Break into smaller refactors:
> 1. First: Add new token format support alongside old
> 2. Second: Migrate consumers one by one
> 3. Third: Remove old format
**Phase 2 - Prepare:**
> - [x] Existing tests cover token generation and validation
> - [x] Created branch: refactor/token-format-v2
> - [x] Documented: Old format is JWT with RS256, new format adds `typ` header
**Phase 3 - Implement:**
> Making changes incrementally...
> - Commit 1: "Add TokenV2 class with new format"
> - Commit 2: "Add feature flag for token format"
> - Commit 3: "Update token generation to use flag"
> - Tests passing after each commit ✓
**Phase 4 - Verify:**
> - [x] All 47 auth tests pass
> - [x] Manual test: login flow works with both formats
> - [x] Manual test: token refresh works
> - [x] git diff shows only intended changes
>
> Ready to merge.