Skip to content

refactor

Restructure code with behavioral parity proven through unmodified pre-existing tests, then refactor. No behavior change.

This is the lane for moving or reshaping code without changing what it does — a rename, an extract, an inline, a dedup, or swapping an internal implementation for another one that behaves identically. The proof that nothing changed comes from tests that already existed before the restructure started; editing one of those tests to make it pass again is treated as a behavior change in disguise, not valid proof. If the surface isn’t covered well enough to prove parity, the work pauses to add tests first. And if what comes out the other end would actually classify as new behavior, the whole thing reroutes to feature work instead of finishing as a refactor.

/ca:refactor <surface and motivation>

State the exact surface being restructured and why it’s worth doing — both parts are required.

> /ca:refactor extract the retry logic in OrderClient.submit() into a shared withRetry() helper — three other clients duplicate it
Surface locked: OrderClient.submit(), PaymentClient.submit(), InventoryClient.reserve().
Parity coverage: each has a direct test; PaymentClient's covers only the success path — backfilling
a failure-path test before continuing.
[backfill test added, suite green]
Applying the extraction... no new branches, no new error paths.
Running full suite unmodified: 187 passed, 0 failed, zero test files touched.
Coverage on the named surface: unchanged. Parity proven.

Reach for /ca:refactor when the behavior is staying the same and only the shape of the code is changing. If the motivation is “the current behavior is wrong,” that’s /ca:fix; if it adds new behavior, that’s /ca:feature.

GateWhenEffect
named surfacebefore the restructure startsthe exact files, functions, or methods in scope must be stated; a vague target like “the auth module” is rejected
parity coveragebefore any code movespre-existing tests must already cover the named surface, with at least one direct test per public method — an under-covered surface halts and backfills first
parity verificationafter the restructurethe full pre-existing suite passes with zero edits to any pre-existing test file
Source — plugins/ca/commands/refactor.md (v2.9.1)
---
description: Restructure code with behavioral parity proven through unmodified pre-existing tests, then refactor. No behavior change.
argument-hint: "<surface and motivation>"
---
# /ca:refactor — behavior-preserving restructure
The only permitted entry to refactor work. A refactor that cannot prove parity through unmodified pre-existing tests is a feature change in disguise and routes to `/ca:feature`. Two required parts: the **surface** (exact files, functions, classes, or methods — vague surfaces like "the auth module" are rejected) and the **motivation** (why the restructure is worth doing).
## Flow
Routes to the `refactor` skill — six phases:
1. **Surface identification** — lock the exact files, symbols, and public signatures.
2. **Parity coverage proof** — demonstrate pre-existing tests already cover the named surface, with at
least one direct test per public method.
3. **Red parity tests (conditional)** — if the refactor exposes a new test seam, route to `tdd`
Phase 1 to write failing tests pinning the seam's contract first.
4. **Implementation** — apply the restructure mechanically within the surface table; no new behavior,
branches, error paths, or side effects.
5. **Parity verification** — the full pre-existing suite passes with zero edits to any pre-existing
test file.
6. **Lint / coverage gate** — lint, type-check, and coverage clear; surface coverage MUST NOT regress.
## Routes to
`refactor` (`${CLAUDE_PLUGIN_ROOT}/skills/refactor/SKILL.md`) — all six phases.
## When NOT to use
- New behavior — a new branch, error path, side effect, public method beyond a Phase 3 seam, or a
change to what any input maps to → `/ca:feature`.
- A change motivated by "the current behavior is wrong" → `/ca:fix`.
- Questions or discussion → `/ca:btw`.
- Persisting an already-completed refactor → `/ca:commit`.
## Hard gate
No refactor proceeds without behavioral-parity coverage proof in Phase 2; if the surface is
under-covered, the skill halts and routes to `tdd` Phase 1 to backfill before resuming. A Phase 4 diff
that would classify as `feat`, or a Phase 5 verification that depends on edits to a pre-existing test,
terminates the refactor and re-routes to `/ca:feature` or `/ca:fix`.

View in repo