easysdd-refactor
There are two stable failure modes when AI refactors code independently: first, it fails to understand the real requirements and constraints of the module, resulting in functionally inequivalent changes; second, the scope it takes on exceeds the context capacity, causing it to forget previous constraints later in the process. This process inserts a scan checklist + method library between "wanting to optimize" and "starting modifications", allowing AI to only undertake tasks it can stably execute correctly, and pause honestly for the rest.
Full workflow:
scan (generate optimization checklist) → design (confirm which items to do and the order with the user) → apply (execute item by item, with manual approval for each step)
Core Discipline: Behavioral equivalence is the bottom line. If an action will change externally observable behavior, do not use the refactor workflow; use feature (for requirement changes) or issue (for bug fixes) instead.
Fastforward Mode (Use this for small refactors)
For obviously small changes — single function, single component, 1-3 optimization points, verifiable with tests, no need for human visual inspection — the full three-stage process is overkill. Trigger
easysdd-refactor-fastforward
: AI directly identifies issues, aligns changes in one go, modifies in-place, runs tests to self-verify, and does not generate scan / design / checklist outputs.
Trigger signals: User says "small refactor", "quick refactor", "simply optimize XX function", "modify directly", "skip the steps".
When not to use fastforward:
- Changes span > 1 file
- Expected modification points exceed 3
- Visual verification is required (frontend effects, performance perception)
- Modifications involve public interfaces (need to use Parallel Change)
- No test coverage
- Cross-module changes
In such cases, advise the user to follow the standard process. If the fastforward process becomes complex during execution, switch back to the full process starting from scan.
File Placement
Refactor outputs are aggregated under
, with an independent directory for each refactor:
easysdd/
└── refactors/
└── {YYYY-MM-DD}-{slug}/
├── {slug}-scan.md ← Optimization checklist generated in Phase 1
├── {slug}-refactor-design.md ← Execution plan from Phase 2 (selected items, order, verification)
├── {slug}-checklist.yaml ← Generated in Phase 2, used to drive Phase 3
└── {slug}-apply-notes.md ← Execution records from Phase 3 (what was done in each step, verification results, deviations)
Directory naming follows the same rule as feature / issue:
YYYY-MM-DD-{English slug}
. The date is set on the day of initial creation and remains unchanged; the slug uses lowercase letters, numbers, and hyphens, short enough to clearly indicate what is being modified (e.g.,
,
).
Why use a separate directory instead of mixing with features/: Refactor outputs are "scan + execution records of the current code state", which have strong timeliness and their value decays over time; feature outputs are "why this capability is designed this way", which have weak timeliness. Their archiving logic is different, so mixing them will make it hard to find content later.
Three Phases
| Phase | Sub-process | Output | Lead Role |
|---|
| 1 scan | Generate optimization checklist | {slug}-scan.md | AI scans code + performs pre-checks, user selects items |
| 2 design | Finalize execution plan | {slug}-refactor-design.md + {slug}-checklist.yaml | AI drafts, user conducts overall review |
| 3 apply | Execute item by item | Code changes + {slug}-apply-notes.md | AI executes, manual approval for each step |
Checkpoints exist between phases. The scan checklist cannot proceed to design until the user selects items; code cannot be modified until the design is approved by the user; items marked for HUMAN verification in apply cannot proceed to the next step without user confirmation.
Phase 1: scan (Generate Optimization Checklist)
First run pre-checks (7 items), stop if any are triggered
Run a pre-check before starting the scan. If any item is triggered,
abort the scan and provide routing suggestions; do not force a checklist. The 7 checks and output format are in
reference/refusal-routing.md
in the same directory.
Zero valid outputs — if no worthy optimizations are found after scanning, state this honestly; do not pad the list.
Lock Scan Scope
Before starting the scan, confirm one thing with the user: which files to scan this time. Default rules:
- If the user specifies specific files/components → scan only those
- If the user says "this page" → scan the entry component of the page + its directly imported internal modules, do not trace public dependencies
- If the user says "this module" → scan files in the module directory, do not cross module boundaries
- If the scope includes >15 files or >3000 lines → trigger the 6th pre-check, ask the user to narrow the scope
Test files should be included in the scope (to determine test coverage for the 2nd pre-check).
What to Look for During Scanning
Use the four-layer classification of the method library as a template to identify issues in code:
- L1 Behavioral Equivalence Migration Signals: A function is called in many places but its interface/implementation needs to be modified → candidate for Parallel Change; a whole block of old logic needs to be replaced with a new implementation → candidate for Strangler Fig
- L2 Code-Level Refactoring Signals: Overly long functions (>50 lines / cyclomatic complexity >10), repeated conditional fragments, mysterious temporary variables, deeply nested if-else
- L3 Structure Splitting Signals: Components >300 lines, a file serving multiple purposes, mixing container/presentation logic, duplicate logic across multiple components (frontend); Controller directly calling DB, missing Service layer, Repository being bypassed (backend)
- L4 Performance Signals: Repeated calculations (memoizable), N+1 queries, non-virtualized/unpaginated lists, unremoved event listeners, deep reactivity for large objects (Vue)
The complete method library list is in
in the same directory; load it fully as a matching table during scanning.
Output Format
- Top Overview (one paragraph): Scan scope / number of findings / distribution by category / distribution by risk / recommendations for priority items / recommendations for high-risk items
- Checklist Items (one markdown block per item): Field order and hard constraints are in
reference/scan-checklist-format.md
in the same directory
After scanning, send the entire
to the user. The user selects items to perform (mark ✓), marks questions or rejections (mark ✗ and write reasons), then proceed to Phase 2.
Do not select items on behalf of the user.
Phase 2: design (Finalize Execution Plan)
Input
- User-selected (✓ items are to be done this time, ✗ items are archived for traceability)
- Method library (each selected item must map to a method ID M-Ln-NN)
Tasks
- Order Items. Items with dependencies are placed first (e.g., L1 Parallel Change often needs to be executed first, followed by L2 extraction). Independent items are prioritized by "low risk + AI-verifiable", and HUMAN verification items are grouped at the end.
- Add Execution Details for Each Item: Referenced method ID, specific steps, preconditions, exit signals, verification responsible party (AI / HUMAN), rollback strategy (how to restore if issues occur).
- Identify Pre-Dependencies: Items with insufficient test coverage need a pre-step of "supplement characterization tests"; items involving public interfaces need a pre-step of "search for callers".
- Overall Review: Send the full draft of
{slug}-refactor-design.md
to the user. After user approval, change the in the frontmatter to .
- Extract Checklist: Extract from the design, with steps corresponding to execution order and checks corresponding to exit signals for each step.
Design File Structure
markdown
---
doc_type: refactor-design
refactor: {YYYY-MM-DD}-{slug}
status: draft | approved
scope: {one-sentence scan scope}
summary: {one-sentence description of items to be done}
---
# {slug} refactor design
## 1. Scope of This Refactor
- Which items were selected from the scan (listed by number)
- Items explicitly not to be done (marked ✗) and reasons
- Estimated total workload / total risk level
## 2. Pre-Dependencies
- Test coverage supplement actions (if needed)
- Caller search actions (if needed)
- Other one-time preparations
## 3. Execution Order
List by step, one block per step:
- Step N: {one-sentence action}
- Referenced Method: M-Ln-NN {method name}
- Specific Operations: {apply method library steps to specific files/functions in the project}
- Exit Signal: {tests AI runs / pages HUMAN checks}
- Verification Responsibility: AI Self-Verify | HUMAN
- Rollback: {how to restore if issues occur, usually git revert the step}
## 4. Risks and Key Points
- Summary of high-risk steps (separately highlight steps with high risk in this design)
- Error-prone points (e.g., cross-step data flow changes)
Phase 3: apply (Execute Item by Item)
Promotion Rules
- One Step at a Time, No Batch Execution. Strictly follow the checklist order; do not start the next step until the current step is completed.
- Verification After Each Step:
- AI Self-Verify Items: Run specified tests / type checks / lint / grep for no residual old references. Record results in apply-notes and proceed to the next step.
- HUMAN Verification Items: Pause, report "Step N is completed. Please visually confirm at {specific page / operation steps}, and I will continue after confirmation". Do not proceed without explicit "continue" from the user.
- Record Deviations Immediately: If unconsidered situations are found during execution (e.g., a caller in dynamic import), pause and report, do not act on your own. Align with the user, add the deviation to apply-notes, and return to Phase 2 to revise the design if necessary.
- Behavioral Equivalence Self-Check: After each step, ask yourself — "Could this step change externally observable behavior?" If in doubt, roll back the step and do not proceed.
apply-notes Format
markdown
---
doc_type: refactor-apply-notes
refactor: {YYYY-MM-DD}-{slug}
---
# {slug} apply notes
## Step 1: {action}
- Completion Time: {date}
- Modified Files: {file list}
- Verification Result: {test output / HUMAN confirmation quote}
- Deviation: {None / specific description}
## Step 2: ...
After Completion
- Run full tests + type checks + lint
- Ask the user to perform a final overall visual confirmation (especially for frontend: open key pages and test interactions)
- After confirmation, finalize the commit, with the commit message referencing the refactor directory
Exit Conditions
Common Pitfalls
- AI Forcing a Checklist: Bypassing obvious pre-check triggers with excuses, generating checklist items with unquantified issues like "code can be more elegant" — should pause immediately and provide routing suggestions
- Including Behavior Changes: "Incidentally fixing a bug / optimizing prompt text" during refactoring — should pause and split into an independent issue or feature
- Merging Cross-Step Actions: Performing 2-3 steps in one commit for speed — losing the ability to roll back individual steps if issues occur
- Including Preference Items: Naming preferences, quotes, arrow functions vs function — these belong to decisions, not refactor
- Starting Directly on a Large Module: Proceeding to scan without splitting a scope of >15 files / >3000 lines, resulting in an unmanageable long checklist
- Skipping HUMAN Verification Items: AI cannot see frontend effects, so "passed type check" cannot replace manual visual inspection
- Proceeding with Insufficient Coverage: Modifying modules without tests, relying only on verbal promises of "behavioral equivalence"
Boundaries with Adjacent Workflows
- feature: Adding new capabilities / modifying requirements → feature. If "incidentally implement X" emerges during refactoring, pause and split it out.
- issue: Fixing bugs / correcting incorrect behavior → issue. Bugs found during refactoring should be recorded as new issues, not fixed secretly in the current PR.
- decisions: Project-wide long-term constraints ("use composable from now on", "disable mixin") → decisions. Refactor execution can reference existing decisions as basis, but does not produce decisions.
- architecture: Cross-module boundary restructuring / layer adjustment → architecture + decisions. A single refactor does not cross modules; cross-module work should be split into "update architecture documentation + record decisions + N module-level refactors".
- tricks / learning: Reusable techniques discovered during refactoring → tricks; pitfalls encountered → learning.
Related Documents
- — Root skill of the easysdd family
easysdd-refactor-fastforward/SKILL.md
— Ultra-lightweight channel for small refactors
reference/scan-checklist-format.md
— Fields, order, hard constraints, and anti-pattern samples for scan checklist items
reference/refusal-routing.md
— 7 scan pre-checks + routing table + rejection output format
- — Refactor method library (four-layer classification L1-L4, unified fields)
easysdd/reference/shared-conventions.md
— Shared terminology across workflows
- Project architecture entry — Review before scanning to confirm module boundaries