Plan a large refactor in safe steps
Turns a large refactor into small, independently shippable steps that keep the build green, each with a rollback, using patterns like expand-contract. Use for refactors too big for one PR.
Large refactors fail as long-lived branches: they drift from main, conflict with everyone, and land as one unreviewable change. The ones that succeed ship as many small steps, each merged and deployed, with old and new code living side by side until the switch-over. The plan matters more than the code.
Plan this refactor: Only if [CONSTRAINTS] is given: Constraints:
- Map the current state. Read the code involved and list the components touched, their callers and how many there are, and the tests that cover them. Count call sites rather than guessing.
- Choose a strategy and say why it fits:
- branch by abstraction: put an interface in front of the old code, build the new implementation behind it, switch over, then delete the old one;
- expand and contract (parallel change): add the new form beside the old one, migrate callers in batches, then remove the old form;
- strangler fig: route traffic or calls to the new component piece by piece;
- a feature flag around the switch-over when it must be reversible at runtime.
- Write the steps. Each step must be mergeable on its own with all tests passing, small enough for one reviewer to review in under an hour, and reversible. For each step give the change, how it is verified, and how it is rolled back.
- Put the safety net first. If behaviour is not pinned by tests, the first steps add characterization tests.
- Mark the point of no return, if there is one, such as a data migration or a public API removal, and what must be true before it.
- Plan only. Do not edit code.
- No step may leave main broken or depend on a later step to compile.
- Base effort and call-site numbers on what you found in the code; mark estimates as estimates.
- If the goal is unclear or seems not worth its cost, say so with the reason, and propose a smaller goal.
- Read the relevant code before making a claim about it. Do not guess what a file, function or config contains.
- If the information you need is not available, say what is missing and how to get it instead of inventing it.
- Separate what you verified from what you inferred. Mark inferences as such.
- When you do not know, say "I don't know" once and state what would settle it.
Current state
Bullets: the components, call-site counts and test coverage you found.
Strategy
The chosen pattern and why, in a short paragraph.
Steps
A numbered table: # | Change | Verified by | Rollback | Size (S, M, L).
Risks
Bullets: each risk and its mitigation, including the point of no return.
Done when
A checklist of conditions that prove the refactor is finished, including removal of the old code path.
1 required value still a placeholder; the assistant will ask for it.
details
- kind
- Prompt: a task you run by name to get one finished thing back
- domain
- Software engineering
- category
- Refactoring
- level
- Expert
- made for
- Tech lead / staff engineer, Software architect, Software engineer
- needs
- repo-read
- risk
- read-only
- version
- v1.0.0 · incubating
- reviewed
- 2026-10-02
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md
use in
npx @hermes-hq/hodios install plan-large-refactor --target claude-codenpx skills add hermes-hq/hodios-dist --skill plan-large-refactor -a claude-codeclaude plugin marketplace add hermes-hq/hodios-distclaude plugin install hodios-software-engineering@hodiosThe plugin brings every entry in this domain at once.
pairs well with
All of RefactoringAdd characterization tests to legacy code
Pins down what untested legacy code does today with characterization and golden-master tests, bugs included, so it can be changed safely. Use before refactoring or modifying code with no tests.
add-characterization-testsExtract a module
Moves one responsibility out of a large file or class into its own module in small, test-verified steps, without changing behaviour or the public API. Use when a file does too many things.
extract-moduleImprove naming in code
Proposes clearer names for variables, functions, types and modules, explains each rename and applies them without changing behaviour. Use when code reads poorly because of its names.
improve-namingReduce code duplication
Finds duplicated logic, separates true duplication from code that only looks alike, and merges only true duplicates behind one well-named function. Use when one fix keeps landing in many places.
reduce-duplicationRemove dead code safely
Finds unused code, flags, endpoints, jobs and dependencies, proves each dead with static and runtime evidence, and removes it or stages a reversible retirement. Use to shrink a codebase.
remove-dead-codeSimplify a complex function
Rewrites a hard-to-follow function into a clearer one with identical behaviour, using guard clauses, named steps and simpler conditions, verified by tests. Use on long or deeply nested code.
simplify-function