refactoring · diff
git:20260814.e4441f3 to git:20261015.f440cbb
9 added, 65 removed. Audit A to A.
---
name: refactoring
- description: Use when restructuring code without changing behavior — extract modules, move classes, redraw dependency boundaries, split or merge files. Behavior-preserving structural changes that make the codebase easier to evolve, distinct from single-file clarity cleanup. Triggers on "refactor structure", "extract module", "move class", "split file", "change dependency", "重构结构", "提取模块", "拆分文件", "改依赖图". Not for single-file clarity cleanup (use simplify), architecture audit producing a design doc (use codebase-design), or lint/style fixes (use linting).
+ description: Execute an agreed structural move while preserving behavior. Triggers on "refactor structure", "重构结构".
---
# Refactoring
- Restructure code while preserving exact behavior — extract a module, move a class to its better
- home, redraw a dependency boundary, split or merge files. The goal is a codebase that is easier to
- evolve, not fewer lines or prettier names. Every move is behavior-preserving and test-pinned.
-
## When to use
- - Extracting a module or class from inline code to redraw a boundary
- - Moving a function/class to where it has the most context (Feature Envy fix at structure level)
- - Splitting one oversized file/module into cohesive units, or merging near-duplicates into one
- - Changing a dependency direction — inverting, decoupling, replacing a concrete dep with an interface
- - Preparing a codebase for a feature by reshaping it first (then implement separately)
- - Triggers on "refactor structure", "extract module", "move class", "split file", "change dependency", "重构结构", "提取模块", "拆分文件", "改依赖图"
+ - Execute an agreed structural move while preserving behavior.
- **Not for:** single-file clarity cleanup — renaming, nesting, dead-code removal (use `simplify`); producing an architecture audit or design doc without executing the change (use `codebase-design`); machine-detectable lint/style issues (use `linting`).
+ **Not for:** codebase-design for choosing boundaries; simplify for local clarity.
## Steps
- ### 1. Pin behavior before moving anything
-
- Refactoring is behavior-preserving by definition — if behavior can shift, you're not refactoring,
- you're rewriting. Pin it first:
-
- - Run the test suite; it must be green. If it isn't, stop — fix the breakage or establish the baseline separately.
- - If the area has weak coverage, add **characterization tests** that capture current behavior (inputs → observed outputs) before you touch structure. You're not testing what it *should* do; you're pinning what it *does* do so the refactor can't silently change it.
- - Note any behavior you suspect is accidental (a bug tests currently encode). Don't fix it here — refactoring preserves behavior, bugs included. File it; fix it in a separate change.
-
- ### 2. Name the structural move
-
- State the move in one sentence before executing. The catalog:
-
- - **Extract** — pull a cohesive responsibility out into its own module/class/function behind a named interface.
- - **Move** — relocate a function/class to where it has the most context (where its data lives).
- - **Split** — break an oversized file/module along a cohesive seam into smaller units.
- - **Merge** — fold near-duplicates into one canonical implementation.
- - **Change dependency** — invert a dependency, decouple via interface, or replace a concrete dependency with a port.
-
- For before→after examples and characterization-test guidance per move, load `references/refactoring-catalog.md`.
-
- If you can't name it as one of these, it's probably clarity cleanup (→ `simplify`) or a design question (→ `codebase-design`).
-
- ### 3. Plan the move as the smallest behavior-preserving steps
-
- Decompose the move into steps small enough that each one leaves the codebase green. "Extract module"
- is not one step — it's: create the empty module → move one responsibility → update callers → run
- tests → move the next. Large structural moves done in one pass are where regressions hide.
-
- - At scale or for the separate-PR/incremental rules, follow §9 (behavior-preserving change discipline) in engineering-principles.md.
-
- ### 4. Execute incrementally — test after every step
-
- One step, then the full suite, then the next step. Never batch structural changes into one untested
- commit.
-
- - Make the move → run the suite → pass: continue; fail: revert the step and reconsider.
- - The separate-PR and Rule-of-500 rules are in §9 (behavior-preserving change discipline) of engineering-principles.md.
-
- ### 5. Verify the structure improved
+ 1. Define the move and behavior contract; establish tests or characterization evidence.
- Step back and compare before and after:
+ 2. Plan incremental file, symbol, import and ownership changes; use automation for repetitive moves.
- - Is the boundary cleaner? Do callers depend on less?
- - Did the move concentrate complexity (good) or just relocate it (no gain)?
- - Is the diff reviewable as a pure structural change — no behavior drift mixed in?
+ 3. Move coherent units and run affected checks; separate features and use compatibility only for actual consumers.
- If the "refactored" structure is not clearly better, or the diff entangles behavior changes, revert. Not every refactor improves things.
+ 4. Verify old references, exports, packaging, documents and runtime paths.
## Verify
- - [ ] Test suite green before and after, with no test modifications (modified tests mean behavior changed)
- - [ ] Each step is an independently revertible, behavior-preserving change; the diff is purely structural
- - [ ] The structural move is named (extract / move / split / merge / change-dependency) and the result concentrates complexity rather than relocating it
- - [ ] No behavior change mixed in — bugs observed during the refactor are filed, not silently fixed
- - [ ] Behavior-preserving change discipline followed (§9: incremental, separate-PR, Rule-of-500)
-
- **Red flags:** tests modified to pass after the move (behavior shifted); a "refactor" PR that also fixes a bug or adds a feature; large structural change in one untested pass; moving code without pinning behavior first; a refactor that leaves complexity merely relocated, not reduced.
+ - Contracts are preserved; moved symbols resolve and abandoned references are removed.
## References
- - [${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md](${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md) — shared discipline (verify don't assume, surgical scope, enforce simplicity)
+ - [engineering-principles.md](../../../references/engineering-principles.md) — shared decision boundaries, scope and verification.
- [references/refactoring-catalog.md](references/refactoring-catalog.md) — before→after examples + characterization-test guidance for each move (extract, move, split, merge, change-dependency)