Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Systematic approach to refactoring that prioritizes modularity, low coupling, high cohesion, and maintainable structure.
Satellite files (loaded on-demand):
references/patterns.md -- detailed refactoring patterns with before/after examples and application criteria
Core Principles
Pragmatism First: Every refactoring must have a clear purpose. Never refactor for the sake of refactoring.
Small, Safe Steps: Make incremental changes that keep the system working. Each step should be independently committable.
Behavior Preservation: Refactoring changes structure, not behavior. Tests should pass before and after.
Simplicity Over Cleverness: The simplest solution that solves the problem is the best solution.
The Four Pillars
These four are the reactive application of the software-design-principles
canon — the same balanced-coupling discipline (managing knowledge flow:
integration strength vs distance vs volatility) restored in code that already
drifted. Consult that skill for the SOLID heuristics and the up-front design
rationale; this skill covers how to restore the pillars safely.
1. Modularity
Break systems into self-contained units with clear responsibilities. Each module should have a single, well-defined purpose and be understandable in isolation.
# Before: Everything in one moduleclassUserManager:
defvalidate_email(self, email): ...
defhash_password(self, password): ...
defsend_welcome_email(self, user): ...
defstore_in_database(self, user): ...
# After: Separated by concern# user_validation.py / password_security.py / email_service.py / user_repository.py
2. Low Coupling
Minimize dependencies between modules. Depend on abstractions, use dependency injection, avoid circular dependencies.
Refactoring work reaches this skill via two complementary entry points; both produce the same [Phase: Refactoring]-tagged steps and follow the workflow below.
Planner-driven (the default). The implementation-planner tags individual plan steps [Phase: Refactoring] when a feature implementation requires restructuring as part of its delivery. The step's scope is the feature; the refactoring is opportunistic.
Architect-driven (PRE_REFACTOR_PLAN.md mini-pipeline). The systems-architect's Phase 2.5 (Pre-Refactor Assessment) may emit .ai-work/<task-slug>/PRE_REFACTOR_PLAN.md when the codebase needs targeted preparatory restructuring before a feature can land cleanly. The plan's ## Behavior Preservation Contract is the canonical input for the test-engineer's characterization-tests-first step; the same [Phase: Refactoring] tag applies to subsequent implementation steps (no new tag is invented). See agents/systems-architect.md Phase 2.5 for the WHEN/WHAT.
Either entry point delegates the HOW — the workflow, patterns, and verification checklist below — to this skill. The architect-driven path adds two contracts on top: (1) characterization tests come first, sourced from the architect's ## Behavior Preservation Contract; (2) the mini-pipeline rejoins the parent flow through an orchestrator-mediated verifier-or-loopback decision, one-pass-bounded by the architect's post-refactor-adaptation mode.
1. Understand Current State
Read and understand the code
Identify what's working, what's painful
Run existing tests (or write characterization tests)
If refactoring API integration code: check the external-api-docs skill for current docs and compare against the project's dependency version. Refactoring an API layer is a natural opportunity to detect version drift and consider upgrades alongside the structural improvement
2. Plan the Change
Define clear goal: "Extract payment processing from order service"
Break into small steps, each safe and testable
3. Execute Incrementally
Green Bar: Ensure all tests pass
Small Change: One small refactoring
Run Tests: Verify behavior unchanged
Review: Check coupling/cohesion improved
Commit: Save working state
Repeat: Next small step
If tests fail after a change, revert and try a smaller step.
4. Verify Re-Wiring and Clean Up
After restructuring, systematically verify that every consumer of the changed code is correctly reconnected:
Trace all call sites: Search for every reference to moved/renamed/extracted code — imports, function calls, type references, configuration entries
Verify integration points: Run the full test suite, not just unit tests for the changed modules — integration and end-to-end tests catch broken wiring that unit tests miss
Check indirect consumers: Templates, config files, CLI entry points, plugin registrations, dependency injection containers — anything that references code by name or path
Remove dead code: Delete unused imports, orphaned functions, abandoned classes, and stale configuration that the refactoring made obsolete — don't leave corpses behind
Clean up transitional scaffolding: Remove compatibility shims, re-exports, and forwarding functions that were only needed during the transition
Final sweep: grep/search for old names, old paths, old module references — if anything still points to pre-refactoring locations, it's a bug
Decision Framework
Should I Create a New Module?
Yes, if: Clear boundary and single responsibility, used by multiple modules, natural cohesion, reduces coupling.
No, if: Only one use case, creates artificial separation, increases complexity without benefit.
Should I Add an Abstraction?
Yes, if: Multiple implementations exist or will soon, need to swap implementations, reducing coupling.
No, if: Only one implementation exists and likely will, abstraction doesn't hide complexity, YAGNI.
Should I Split This Package?
Yes, if: Multiple unrelated responsibilities, different parts change for different reasons, too large to grasp.
No, if: Everything changes together, high cohesion across all parts, splitting would increase coupling.
Scenarios: God Object/Module, Feature Envy, Primitive Obsession, Utils Hell, Deep Nesting
Anti-Patterns
Anti-Pattern
Fix
Over-Abstraction — interfaces without multiple implementations
Start concrete, extract when second use case appears
Anemic Models — data classes with no behavior
Move behavior into the class
Shotgun Surgery — one change touches many files
Group things that change together
Speculative Generality — flexibility for hypothetical needs
Implement for current requirements only
Premature Optimization — optimizing without measurements
Profile first, optimize hot paths only
Gotchas
Process-level pitfalls distinct from the code design anti-patterns above:
Refactoring without sufficient test coverage. Before restructuring code that lacks tests, write characterization tests first -- tests that capture the current behavior as-is, even if the behavior is imperfect. Refactoring untested code turns "restructure" into "hope nothing breaks."
Mixing refactoring with behavior changes in the same commit. Keep refactoring commits pure -- structure-only, zero behavior change. When a feature requires refactoring to make room, do the refactoring in a separate commit first, then add the feature. This makes each commit independently reviewable and safely revertible.
When to Refactor
Don't refactor if:
No tests exist and behavior is unclear (write tests first)
Code is about to be deleted
Working code with no current pain point
Do refactor when:
Adding feature and current structure is an obstacle
Bug reveals structural problem
Code duplication reaches three instances
Coupling prevents testing
API version drift detected -- when the external-api-docs skill flags that the project's API dependency is outdated, restructuring the API integration layer to accommodate the upgrade is a refactoring task. Coordinate with the systems-architect for scope decisions: upgrade only vs. upgrade + restructure
Code Metrics
Monitor these thresholds:
Module size: >500 lines needs review
Cyclomatic complexity: Functions >10 need simplification
Coupling: Count dependencies per module
Cohesion: Measure internal relatedness
Language-Specific Notes
Python
Use Protocols for abstractions (PEP 544)
Dataclasses for immutable data (frozen=True)
Prefer composition over inheritance
Type hints enable safe refactoring
See the Python skill for detailed type hint patterns, testing, and code quality tools.
See the Code Review skill for structured post-refactoring review with finding classification and report templates.