Restructure existing code safely without changing externally observable behavior. Composes context, design, architecture, code quality, and testing guardrails into a characterization-first refactoring workflow. Use when the user says 'refactor this', 'clean this up', 'untangle this module', 'move this to the right layer', 'simplify this code', or 'improve this structure'.
Scanned 9/1/2026
Install to Claude Code
npx -y skills add techygarg/lattice --skill refactor-safely --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Refactor Safely?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/techygarg-refactor-safely)More formats (shields.io, HTML) on the badges page.
---
name: refactor-safely
description: "Restructure existing code safely without changing externally observable behavior. Composes context, design, architecture, code quality, and testing guardrails into a characterization-first refactoring workflow. Use when the user says 'refactor this', 'clean this up', 'untangle this module', 'move this to the right layer', 'simplify this code', or 'improve this structure'."
---
# Refactor Safely
## Required Skills
Load these skills based on refactor scope (see Steps 3, 5, 6 for conditional use):
1. `framework:knowledge-priming` -- Load project context so the refactor grounds in the real codebase. (always)
2. `framework:context-anchoring` -- Find and load the feature's context doc; capture approved plans and decisions in it. (always)
3. `framework:learning-harvest` -- Load prior operational learnings at session start; harvest new ones at session end. (always)
4. `framework:collaborative-judgment` -- Surface trade-offs in structure, seams, and migration sequence instead of silently assuming. (always)
5. `framework:clean-code` -- Readability, responsibility boundaries, local craft. (always)
6. `framework:test-quality` -- Characterization tests and the safety net. (always)
7. `framework:design-first` -- Target-structure planning for significant structural changes. (conditional: Step 3)
8. `framework:architecture` -- Layer placement and dependency direction. (conditional: responsibilities move across layers in Steps 5/6)
9. `framework:domain-driven-design` -- Aggregate boundaries and domain behavior. (conditional: domain rules move or sharpen in Step 6)
10. `framework:secure-coding` -- Trust bounds, authorization, sensitive data handling. (conditional: security-sensitive code touched in Step 6)
## Workflow
### Step 1: Establish Refactor Context
Start from the current pain, not from a preferred abstraction.
- Identify the target area: a module, service, aggregate, endpoint path, or subsystem.
- Clarify why the refactor is needed: mixed responsibilities, duplication, wrong-layer logic, coupling, poor testability, or unreadable control flow.
- Clarify what the user expects to improve: simpler structure, correct layer placement, smaller units, clearer domain behavior, easier testing, or safer extension points.
- Run `framework:learning-harvest` Load behavior. Focus hint: "refactoring session — focus: structural health, quality signals".
- Run `framework:context-anchoring` Document Discovery to check for an existing context doc covering the affected feature/module:
- **Found** → Load behavior. Honor every logged decision and constraint as an active commitment while planning the refactor. The doc already contains an approved refactor plan (preservation boundaries + target structure) → confirm it still matches the user's intent, then resume at Step 4 unless the user wants to revisit the plan first.
- **Not found** → Proceed from the conversation and the current code. Do not block planning on a missing context doc.
End the step by summarizing the intent in one sentence:
> "Refactor X to improve Y while preserving Z."
**STOP:** If you cannot state both the improvement target and the preservation target that clearly, continue clarifying with the user before planning any changes.
**Persistence check**:
- Refactor is substantial, risky, or likely to span multiple sessions → ask whether the user wants to persist an approved plan.
- A relevant context doc already exists and the user wants persistence → use it and update it.
- No relevant doc exists and the user wants persistence → propose creating one; confirm the doc name per `framework:context-anchoring`, then use it as the source of truth for the approved plan.
- The user declines persistence, or the refactor is small and local → continue in non-persistent mode. Approval gates still apply; the plan simply stays in-session.
### Step 2: Define Preservation Boundaries
Refactoring changes structure, **not behavior**. Make the preservation contract explicit before proposing any structural edits.
List the behaviors that must remain unchanged:
- Public API contracts and response shapes
- Domain invariants and state transitions
- Persistence semantics and side effects
- Event emission and integration behavior
- Authorization and security posture
- Error behavior wherever externally visible
- Performance or operational characteristics, if part of the current contract
Also list explicit **out-of-scope changes**:
- New features
- Schema changes
- Contract changes
- Intentional behavior changes
- Unrelated cleanup outside the approved area
If the desired outcome requires changing preserved behavior, stop and discuss what the task actually is — a bug fix (`/bug-fix`), a feature change (`/design-blueprint`), or a broader redesign. **STOP:** Never proceed as a refactor after making one of those determinations.
### Step 3: Propose High-Level Structural Plan
**Zero Refactor Rule**: make no structural code changes until the user approves both the target structure and the transition plan.
For small refactors the plan may be brief. For larger ones, use `framework:design-first` selectively:
- Start at **Level 2 (Components)** to define target responsibilities and boundaries.
- Use **Level 3 (Interactions)** when data flow or dependency direction will change.
- Use **Level 4 (Contracts)** when internal interfaces or seams need to be formalized.
- Skip Level 1 (Capabilities) unless the user-facing scope is actually changing.
Present:
- **Current structural problems** -- what is wrong with the current shape
- **Target structure** -- which components, classes, and functions should exist after the refactor
- **Movement plan** -- what logic moves where
- **Preservation boundaries** -- what will stay behaviorally unchanged
- **Out-of-scope items** -- what will not be changed in this pass
End the step with an explicit gate:
> "Does this refactor plan look correct? Should I proceed to Step 4: characterization tests?"
**STOP:** Do not write any refactoring code until the user explicitly approves this plan.
If persistence is enabled, use `framework:context-anchoring` Enrich to capture the approved preservation boundaries, target structure, movement plan, and out-of-scope items. **STOP:** When persistence is enabled, do not proceed to Step 4 until the approved plan is written.
### Step 4: Add Characterization Protection First
Before changing any structure, lock in current behavior with tests.
- Identify existing tests that already protect preserved behavior.
- Strengthen existing tests that are too implementation-coupled or too vague to serve as guardrails.
- Add **characterization tests** for important behaviors that are currently implicit.
- Prefer the lowest-level test that faithfully captures each preserved behavior without missing important integration effects.
- Characterization tests must describe the **current observable behavior**, not the intended refactored shape.
- Apply `framework:test-quality` inline while writing them.
- Run the safety net where the environment allows. If tests cannot be executed here, say so explicitly — the safety net then counts as unverified, and the stopping rule below applies.
**Stopping rule**:
- An important preserved behavior is not protected by tests → pause and make that gap explicit before refactoring.
- **STOP:** Do not start structural edits without a believable safety net unless the user explicitly accepts the risk.
- Green characterization tests are the baseline for the refactor. Anything red before the first structural change must be resolved first, or the task re-scoped.
End the step with an explicit gate:
> "Characterization tests in place and passing. Ready to discuss refactor strategy and pacing?"
**STOP:** Do not proceed to strategy selection until the safety net is verified green — or the user has explicitly accepted an unverified safety net per the stopping rule above.
### Step 5: Choose Refactor Strategy and Pacing
With the high-level plan approved and the safety net green, choose the implementation approach.
Preferred strategies:
- **Extract and redirect** -- extract focused units, route callers gradually.
- **Introduce seam, then migrate** -- add an interface or boundary, then move behavior behind it.
- **Move behavior inward** -- shift business rules from outer layers into the appropriate inner layer per `framework:architecture`.
- **Split and collapse** -- separate unrelated responsibilities, then remove the old mixed path.
Ask the user to choose a pacing mode:
> "How would you like to review the refactor?"
> 1. **Slice-by-slice** (recommended) -- refactor one safe slice at a time, pausing after each slice. Best for risky legacy code.
> 2. **Layer-by-layer** -- complete the refactor for one structural layer or concern, then pause for review. Best for broader architectural cleanup.
> 3. **Full autonomy** -- execute the approved refactor end-to-end and present the complete result at the end. Best for tightly scoped, low-risk refactors. (Still pause immediately if any slice reveals the approved plan unsafe or invalid — see the Deviation Rule in Step 6.)
Default to **slice-by-slice** when the user expresses no preference.
### Step 6: Refactor in Small Green Steps
Implement only within the approved preservation boundaries and the approved target structure.
For each slice:
1. Make one structural improvement from the approved plan.
2. Re-run the relevant characterization tests.
- Any characterization test goes red → **stop immediately**. Do not start the next slice. Fix the regression or revert the slice before continuing.
3. Apply the applicable atom Self-Validation Checklists.
4. Run the applicable Active Anti-Pattern Scans.
5. Fix violations before presenting the slice.
6. Collect judgment calls for the slice via `framework:collaborative-judgment` and surface them before presenting the slice's code. Do not interrupt mid-slice unless the approved plan becomes unsafe or invalid.
Always apply:
- `framework:clean-code` -- better boundaries, simpler control flow, smaller focused units, clearer naming.
- `framework:test-quality` -- maintain strong characterization tests and nearby supporting tests.
Conditionally apply:
- Responsibilities move across layers or dependency direction changes → apply `framework:architecture`.
- Business rules, aggregates, value objects, or domain behavior move or sharpen → apply `framework:domain-driven-design`.
- Trust boundaries, authorization, validation, queries, or sensitive data handling are touched → apply `framework:secure-coding`.
**Deviation rule**: if the implementation reveals the approved plan incomplete, unsafe, or requiring changes to preserved behavior → **STOP:** pause immediately and discuss before continuing.
### Step 7: Verify Preservation and Structural Improvement
The refactor succeeds only if **both** are true:
1. **Behavior preserved**
2. **Structure measurably better**
Verify preservation:
- Characterization tests still pass.
- No unintended outward behavior changed.
- Preserved contracts remain intact.
- Security posture not weakened.
Verify structural improvement:
- Responsibilities clearer.
- Dependency direction improved, or at least no worse.
- Duplication or entanglement reduced.
- Testability and readability improved.
- Old paths and temporary scaffolding removed once migration is complete.
When reporting completion, be explicit about both sides:
- What behavior was preserved and how it was verified.
- What structural improvement was achieved.
- What was intentionally deferred to a later refactor.
### Step 8: Capture Decisions and Remaining Debt
Use `framework:context-anchoring` Enrich to preserve the important parts of the refactor:
- Refactor scope: what area changed.
- Preservation boundaries: what was explicitly kept stable.
- Target structure: what shape was approved.
- Strategy chosen: why this migration path was selected over the alternatives.
- Key files changed: path + role in the doc's Key Files table (skip a path already listed).
- Deferred debt: what remains and why it was intentionally left for later.
No context doc exists and the refactor involved non-trivial structural reasoning → suggest creating one so the decisions are not lost across sessions.
**Harvest learnings**: run `framework:learning-harvest` Harvest behavior. Session context: "refactoring session — structural restructuring and debt resolution". Synthesize and propose cross-cutting patterns from this session — structural debt that accumulated, migration strategies that worked, characterization test gaps discovered. The user confirms what enters the document. **STOP: run this before recommending `/review` below.**
After the refactor is complete, recommend `/review` when the change:
- touches multiple layers
- changes domain boundaries
- changes security-sensitive code
- leaves temporary migration scaffolding behind
- is large enough that an independent quality pass would add confidence
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!