# Safe Refactor

> Use when restructuring code without changing its behavior. Keeps refactors reversible and behavior-preserving so cleanup never becomes an accidental rewrite that breaks things.

- Skill: `dkenge123-oss/safe-refactor` (Agent Skill)
- Install (CLI): `npx skillmds@latest add dkenge123-oss/safe-refactor`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dkenge123-oss/safe-refactor/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: dkenge123-oss (https://skillmd.com/u/dkenge123-oss)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/dkenge123-oss/safe-refactor

---


# Safe Refactor

Refactoring changes structure, not behavior. The moment behavior changes, it stopped being a refactor and became a risk.

## Protocol

1. **Pin behavior with tests first.** Before changing structure, make sure the current behavior is covered. If it is not, add characterization tests that capture what the code does *now* (not what it should do). These are your safety net.
2. **Separate refactor commits from behavior commits.** Never mix "moved this function" with "and also fixed the logic". A reviewer must be able to trust that a refactor commit changes nothing observable.
3. **Take small, reversible steps.** Rename, then run tests. Extract, then run tests. Inline, then run tests. Each step leaves the code green. A refactor that only works at the end is a rewrite wearing a disguise.
4. **Keep the diff mechanical where possible.** Prefer automated rename/extract tools over hand-editing. Mechanical changes are easier to verify and harder to get subtly wrong.
5. **Run the full suite after each meaningful step**, not just at the end. Catching a break at step 3 of 10 is cheap; catching it after step 10 means bisecting your own work.
6. **Stop when the code is clear enough**, not when it is theoretically perfect. Refactoring has diminishing returns; a second pass tomorrow is fine.

## Never

- Never refactor and change behavior in the same commit.
- Never refactor code with no test coverage without adding characterization tests first.
- Never "improve" an interface that other code depends on without checking the callers.
- Never let a refactor grow into a rewrite midway; if it must, stop and make that an explicit, separate decision.

## Done means

Behavior is provably unchanged (the suite is green throughout), the diff is reviewable as pure restructuring, and the code is meaningfully clearer than before.

