# Refactoring Planning

Restructures code without changing what it does — in steps small enough to verify, and never in the same step as a behaviour change.

## Deliverable

One Markdown document, `refactoring-plan.md`, in the structure set out under **Output** below. Each step in it is executed and reviewed on its own, and **Code Review** is the check applied between them.

## Required inputs

- **The code to be restructured** — the files, modules or area, with access to read them.
- **The reason for restructuring** — what is hard now and what should be easier afterwards. Restructuring with no stated reason has no finish line.
- **The current test coverage of that code**, or the means to determine it.

If any of the three is absent, stop and report which one. In particular, a refactor planned without knowing what the tests cover is a rewrite with optimism attached.

## Optional inputs

- The behaviour the code is believed to have, in whatever written form exists
- Performance characteristics that must be preserved
- Callers and dependants inside and outside the module
- The version control history of the area, including earlier attempts
- Deployment or release constraints on the area
- Changes already planned for the same code, and when they land

Where an optional input is absent, the plan names the steps it would have constrained and marks them `unverified`, rather than proceeding as if the constraint does not exist.

## Execution

**1 — State the end condition.** What must be true when the refactor is finished, in terms someone can check: the structure, the boundary, the dependency that no longer exists. A refactor without an end condition continues until someone gets tired.

**2 — Establish the safety net.** Determine what the existing tests actually cover on this code. Where the behaviour is not pinned, write characterisation tests that record what the code does today — including behaviour that looks wrong. These tests land BEFORE the first refactoring step, as their own step.

**3 — Separate restructuring from behaviour change.** List everything the work will do, then split it into two lists: changes that preserve behaviour and changes that alter it. The two never occur in the same step, and the plan says which steps belong to which list.

**4 — Break the work into revertible steps.** Each step is one transformation, verifiable on its own and revertible on its own without unwinding the steps before it. A step that cannot be reverted alone is split until it can.

**5 — Set the checkpoint after each step.** The tests that must pass, the behaviour that must be unchanged, and how that is observed. The characterisation tests from step 2 run at every checkpoint, unchanged — a test edited during a refactor stops being evidence.

**6 — Name the point of no return.** The step after which reverting costs more than continuing, usually where a data shape, a published interface or a stored format changes. Everything before it is cheap to undo; everything after it is a commitment, and the plan says so.

**7 — List what the refactor will not touch.** The code that stays as it is, and the improvements deliberately left for later. Scope that grows inside a refactor is what turns it into an outage.

## Output

`refactoring-plan.md`, in this order:

- **1. Input and reason** — the code, why it is being restructured, and when the plan was written
- **2. End condition** — what must be true at the finish, stated so that it can be checked
- **3. Coverage assessment** — what the existing tests pin, and what they do not
- **4. Characterisation tests** — the tests to write first, what each one records, and where they live
- **5. Steps** — ordered; per step: the transformation, the files, whether it preserves behaviour, and how to revert it
- **6. Checkpoints** — after each step: what runs, what must pass, what must be unchanged
- **7. Behaviour changes** — separated out; each with the step it belongs to and why it is not in a refactoring step
- **8. Point of no return** — the step, what makes it irreversible, and what must be decided before it
- **9. Out of scope** — what is deliberately left alone

## Validation

The plan is ready when all of these hold:

- Section 4 lands before the first step in section 5
- Every step in section 5 is marked behaviour-preserving or listed in section 7, never both
- Every step names how to revert it without unwinding the steps before it
- Every checkpoint names the tests that run and states that they are unchanged
- Section 8 names a step, or states that no step is irreversible
- Section 2 is written so that someone other than its author can tell when it is met

Fail the run if a single step both restructures and changes behaviour, or if a step lands before the tests that cover it.

## Failure handling

- **No test coverage and no way to add it** — stop. Report that a behaviour-preserving change cannot be verified here, and that the only honest options are to add a way to observe the behaviour first or to treat the work as a rewrite with its own specification.
- **No stated reason** — stop. Report that the refactor has no end condition and would be judged on taste.
- **Coverage unknown** — plan step 2 alone, deliver it, and state that the remaining steps cannot be written until what the tests pin is known.
- **The reason requires a behaviour change** — say so plainly, split the work into a refactor and a change, and plan them as separate sequences with separate approvals.
- **The area is under active change** — list the conflicting work in section 9, and either sequence the refactor around it or state that the two cannot proceed at once.
