Skip to main content

Refactoring workflow

Purpose​

This workflow defines a safe, repeatable refactoring process that preserves behavior while improving structure.

In AI-assisted development, refactoring is high-risk because large automated edits can introduce subtle regressions and architectural drift. This workflow reduces that risk through explicit planning, safety nets, and incremental execution.

Phase 0: Prerequisite Check​

Strict Rule: If NO tests exist for the target code:

  • You must Write a Regression Test before changing any functional code.
  • Refactoring without tests is forbidden.

Scope​

This workflow applies to:

  • Structural improvements (module boundaries, naming, extraction)
  • Simplification and maintainability work
  • Dependency cleanup
  • Testability improvements
info

It does not apply to behavior changes (see Feature Development) or pure bug fixes (see Defect Handling).


Core Principle​

Core Principle

Refactoring changes structure, not behavior. If you cannot confidently prove behavior preservation, you are not refactoring — you are redesigning.


Inputs​

Required Inputs
  • Refactoring goal (why this is worth doing)
  • Current code area(s) and boundaries
  • Definition of Done
  • Architecture Principles

Phase 0: Decide If Refactoring Is Justified (ROI Check)​

Goal​

Avoid unnecessary refactors and "cleanup binges".

The Business Case​

  • Why Now? Is this code blocking a new feature? Is it a frequent source of bugs?
  • Cost vs. Value: Does the time invested (e.g., 4 hours) save at least that much time in the next 3 months?
  • Risk: Is this a critical path? If it breaks, does the system stop working?

Output​

  • A short, explicit refactoring goal statement

Phase 1: Create a Safety Net​

Goal​

Make regressions detectable.

Activities​

  • Ensure the code builds and tests pass on the current baseline
  • Add or improve automated tests that lock down behavior:
    • Unit tests for pure logic
    • Integration tests for boundaries
    • Characterization tests if behavior is unclear

Output​

  • A test suite that would fail if behavior changes

If testing is hard, treat that as a signal: improve testability first.


Phase 2: Write a Refactoring Plan (Required)​

Goal​

Prevent loss of direction and uncontrolled scope growth.

Create​

Plan Content (minimum)​

  • Goal and non-goals
  • Scope boundaries (what you will not touch)
  • Step-by-step plan (small, mergeable steps)
  • Risks and mitigation
  • Validation checklist

Output​

  • A written plan that can be followed without improvisation

Phase 3: Execute Incrementally​

Goal​

Refactor in small steps with continuous validation.

Guidelines​

  • Prefer multiple small commits/PRs over one large diff
  • Run relevant tests frequently
  • Avoid mixing refactoring with new features
  • Keep each step reviewable and explainable

Techniques (examples)​

  • Rename for clarity
  • Extract functions/components
  • Introduce interfaces/adapters
  • Move code to enforce boundaries
  • Reduce duplication carefully

Output​

  • Incremental structural improvements with preserved behavior

Phase 4: Validation, Cleanup, and Closure​

Goal​

Ensure the refactor improved the system without hidden costs.

Activities​

  • Run full test suite (unit + integration)
  • Run build checks and linters
  • Remove temporary instrumentation or scaffolding
  • Update documentation if structure changed
  • Validate against Definition of Done

Output​

  • A clean, validated codebase with improved structure

Completion Criteria​

A refactor is considered complete only if:

  • Behavior is preserved and proven by tests (where feasible)
  • The refactoring goal is achieved
  • The codebase is at least as understandable as before
  • All applicable Definition of Done criteria are satisfied

Use AI to plan and execute refactoring, but always with constraints.

Act as a Developer.

Context:
- Refactoring goal
- Refactoring Plan document
- Architecture Principles
- Definition of Done

Task:
Execute the next refactoring step exactly as described in the plan.
Keep changes minimal and reviewable.
Add or update tests as needed.

Rules:
- Do not expand scope.
- Do not change behavior.
- Do not perform unrelated cleanup.

Anti-Patterns​

Avoid These
  • Flying Blind: Refactoring without tests.
  • Big Bang: Large, AI-generated sweeping changes.
  • Scope Creep: "While I'm here" changes.
  • Feature Mixing: Mixing logic changes into refactoring.

Notes for React + TypeScript Projects (Optional Guidance)​

  • Prefer incremental component extraction over rewrites
  • Use tests (e.g., Vitest) to lock down behavior before moving code
  • Keep UI refactors small; isolate visual changes from structural changes
  • Consider adding a lightweight smoke test for critical flows