Design: Large-Scale Code Migration Agent
Published:
๐ฏ Problem Statement
Design an agent system to migrate 2M lines of Objective-C to Swift across 50 modules, while 200 engineers continue landing features on the same codebase. Timeline: 6 months.
Constraints:
- Correctness: the build can never stay red; every migrated module must pass existing tests and behave identically.
- Incremental: big-bang rewrites are banned โ migrate module by module, shippable at every step.
- Human review required: no machine-generated code lands without human sign-off.
- Parallel development: humans keep merging; the migration must not constantly conflict.
- Measurable: leadership wants a dashboard, not vibes.
๐ Architecture
The verifier is the product; the converter is interchangeable. Every loop back to the converter is cheap because verification is automated.
๐งญ Discussion Framework
A strong answer walks through these areas in order:
1. Phased rollout, not a flag day
- Pilot: 2โ3 representative modules (one easy, one gnarly, one high-churn). Learn the failure modes small.
- Scale: module-by-module with a priority queue (leaf modules first, or highest-churn first โ argue the tradeoff).
- Sustain: the system keeps running as new ObjC lands; migration is a standing process, not a project.
2. The agent architecture
- Per-module converter agent: reads module, plans file-by-file conversion, emits diffs. Bounded scope per run (one module, not the world).
- Verification layer (deterministic, not LLM): build โ unit tests โ behavioral diff (run old vs new against recorded traffic / snapshot tests). The verifier is the real product; the converter is interchangeable.
- Review agent / human checkpoint: summarizes the diff for the human reviewer (what changed semantically, risk areas) โ humans review judgment, not syntax.
- Coordinator: schedules modules, tracks state per module (pending โ converting โ verifying โ in review โ done), handles retries.
3. Living with parallel human development
- Migrate at module boundaries with clear ownership; coordinate via the moduleโs owning team.
- Rebase strategy: converter works on fresh checkouts; if a human lands mid-conversion, re-run (cheap if verification is automated) or diff-and-patch.
- Generated-code hygiene: mark migrated regions, prevent the agent from โre-migratingโ converted code (state tracking per file).
4. Token efficiency & cost
- Internal research angle: Swiftโs token efficiency vs ObjC affects agent coding cost โ batch related files, share context across files in one module, cache repo maps.
- Measure $/merged module, optimize the expensive parts (usually verification + review cycles, not generation).
5. Metrics dashboard
- Conversion rate (modules/week), build health, test pass rate on migrated code, human review burden (comments per diff, revert rate), and defect escape rate on migrated modules vs baseline.
๐ Deep-Dive Questions
- โHow do you prove behavioral equivalence?โ โ Layered: compiles + existing tests + snapshot/behavioral diffs + staged rollout with production monitoring. No single layer suffices; argue which catches what.
- โThe agent produces correct but unidiomatic Swift โ accept?โ โ Define a style bar (linters as deterministic gates); unidiomatic-but-correct ships, with a follow-up modernization pass. Donโt let perfect block the migration.
- โA module has 80% test coverage and the rest is untestable legacy โ migrate?โ โ Risk-tier the modules; low-coverage modules get more human scrutiny and smaller batches, or characterization tests written first (by an agent, verified by humans).
๐ก What Great Looks Like
The candidate separates the non-deterministic converter from the deterministic verifier, treats human review as a designed bottleneck to optimize (summarization, risk ranking), plans for parallel development conflicts explicitly, and defines success in metrics โ not โwe migrated everything.โ
Share on
Twitter Facebook LinkedInโ Buy me a coffee! ๐
If you found this article helpful, consider buying me a coffee to support my work! ๐
