intermediate 3 min answer

Review this plan. Eighteen months to rebuild the policy engine. Feature parity is required before any traffic moves. The legacy team is frozen to bug fixes only so that no effort is wasted on code that will be thrown away. What would you remove, what would you change, and what would you leave alone?

rewritefeature-parityarchitecture-reviewincremental-migration
Show the full answer Hide the answer

What is actually required

The business needs the policy engine to keep working and to become changeable. Nothing in that requires a single moment when the new system is complete. Two elements of this plan are load-bearing constraints that nobody asked for: the parity gate and the freeze.

What I would remove

Remove the parity gate. Requiring every behaviour before any traffic moves means the first piece of production feedback arrives at month eighteen, which is also when the estimate is discovered to be wrong. It also imports every accumulated bug as a requirement, because parity is measured against what the old system does, not what it should do. Replace it with per-capability gates: a slice moves when its own comparison run is clean.

Remove the freeze. This is the one that kills programmes. The business does not stop needing policy changes for eighteen months, so one of two things happens: the freeze holds and the modernisation becomes the thing blocking revenue, or it quietly breaks and every unfrozen change has to be built twice, so the new system never converges. A frozen legacy system is a promise the business has not made.

The one change that matters

Put a routing layer in front of the policy engine on day one and move the smallest real capability through it in the first quarter, with production traffic shadowed to the new implementation and outputs compared. That single change converts an eighteen-month bet into a series of small ones, and it produces the thing the plan lacks entirely: evidence, before the money is spent, about how different the two implementations actually are.

Expect the comparison to be noisy. The useful exit condition is not zero differences but every difference explained, because rounding, clock skew and legitimately fixed bugs will always produce some.

What I would leave alone

  • The separate team. Splitting attention across maintenance and rebuild is worse than a dedicated team, and the cost of coordination is lower than the cost of context-switching.
  • The eighteen-month horizon. It is probably optimistic, but arguing about the estimate distracts from fixing the shape. A well-shaped programme that runs long still delivers value at month four.
  • The new data model, if it differs. Reviewers reflexively demand the new system match the old schema. That is the one place a rewrite earns its keep, provided there is a documented translation both ways.

When this is the wrong answer

If the legacy engine is genuinely small, has no consumers in production other than one batch job, and the team has read all of it, a straight rewrite with a single cutover is cheaper than the routing layer and the comparison harness. Routing plus a comparison harness is on the order of 3 to 6 weeks of work before any migration value appears; below roughly 20,000 lines with a single consumer, that is more machinery than the risk justifies. Choose the incremental shape whenever the system has more than one consumer or more than one team depending on it, and accept the cutover only when you can name every caller.

Common weak answers

  • "Extend the timeline." The shape is wrong, not the duration. A thirty-month version of this plan fails the same way, later.
  • "Add more tests to the legacy system first." Characterisation tests help, but they cannot tell you what the old system does on the inputs nobody thought to write a test for. Production comparison can.
  • "Keep parity but cut scope." Parity and reduced scope are the same decision stated twice; without a named list of behaviours you will not reproduce, scope creeps straight back.