Direct answer
Use the agent first to map dependencies, callers, data flows, and undocumented behavior. Add characterization tests around observable contracts, then migrate one reversible slice at a time behind stable interfaces; verify old and new paths with the same inputs before removing legacy code.
Key takeaways
- Map behavior and ownership before asking for structural changes.
- Characterization tests record current behavior but do not declare every legacy behavior correct.
- Keep compatibility boundaries stable while internals move in small slices.
- Remove the old path only after migration, rollback, and observability gates pass.
Key facts
| Fact | Verified value | Evidence |
|---|---|---|
| Repository instructions | AGENTS.md can provide scoped repository guidance for Codex, including commands and directory-specific conventions. | View source |
| Large repository context | Claude Code documents techniques for exploring and working within large codebases instead of loading every file at once. | View source |
| Persistent project context | Claude Code memory files can carry maintained project instructions across sessions and directory scopes. | View source |
| Compatibility language | Semantic Versioning defines how public API changes relate to major, minor, and patch version numbers. | View source |
What this guide helps you solve
Plan and execute AI-assisted legacy refactoring without treating broad code generation as evidence of preserved behavior.
Verification scope and limits
- Evidence basis
- Official documentationSpecificationLocal verification
- Verification scope
- Covers legacy discovery, behavior capture, migration slicing, compatibility validation, rollout, and removal gates.
- Limits and invalidation conditions
- - Characterization tests may preserve defects and must be reviewed against current business requirements.
- - The workflow does not replace production migration planning for data, traffic, or external consumer contracts.
Build a map of contracts and change boundaries
Ask the agent to identify entry points, consumers, persistent data, scheduled jobs, external protocols, and deployment units. It should cite code and documentation, and mark uncertain behavior instead of filling gaps with assumptions.
Review ownership and operational constraints with maintainers. A dependency graph is useful only when it reflects runtime integration and not just import statements.
Capture observable behavior before changing structure
Add tests at public APIs, events, database effects, files, or user-visible outputs. Include representative edge and error cases found in logs or incident records after redaction. Label questionable behavior so tests do not silently turn defects into permanent requirements.
- Record representative inputs and outputs with sensitive data removed.
- Separate documented contracts from incidental implementation details.
- Identify consumers that cannot migrate in the same release.
- Define rollback signals before dual paths are introduced.
Define reversible migration slices
Choose a seam such as one endpoint, command, data adapter, or package boundary. Ask the agent for a file-level plan that keeps public behavior stable and lists the tests for that slice. Do not authorize a repository-wide rewrite from an architectural summary.
Keep formatting and unrelated cleanup outside the migration diff. Smaller changes preserve blame history and make behavioral differences easier to isolate.
Compare old and new paths under controlled inputs
Where feasible, run both implementations against the same sanitized fixtures or shadow inputs and compare externally meaningful outputs. Differences need classification: intended contract changes, tolerated nondeterminism, or defects.
Protect dual execution with resource limits and explicit data-write rules. Never duplicate irreversible production side effects simply to obtain comparison data.
Use gates for rollout and legacy removal
Each slice should pass characterization tests, new contract tests, package checks, review, and rollback rehearsal. Observe errors and resource use during gradual rollout. Remove old code only after consumers, data, documentation, and alerts have moved.
- 01Behavior gateOld and new paths satisfy the reviewed contract.
- 02Compatibility gateConsumers and versioning expectations remain valid.
- 03Operations gateTelemetry and rollback identify regressions safely.
- 04Removal gateNo live caller, job, or data path depends on the legacy implementation.
Keep repository guidance aligned with the new architecture
Update architecture documentation, repository instruction files, ownership, build commands, and runbooks as slices land. Remove obsolete guidance so future coding-agent sessions do not keep routing work through retired modules.
Official sources and verification scope
This guide is based on public official documentation. Commands and configuration may change between client versions, so verify the linked sources before use.
Read the verification methodology