The module passed. Every test green, every acceptance criterion signed off, a modernization the whole team was proud of: a gnarled old routine, rewritten into a clean modern service in a fraction of the time it would have taken by hand. Everyone moved on. Then, three weeks later, it broke, and it broke on a single input nobody had thought to test, because the behavior it needed had never been written down anywhere a test could reach. The old code had a reason. The new code had the code.
I have watched some version of that scene play out for 25 years in enterprise software delivery, long before AI could do the rewrite. What changed is the speed, and I want to give the speed its due before I complain about anything, because the gains are real and the people shipping them are not fools. The trap sits elsewhere. Modernization is not slow anymore; it just feels finished when it is only half done.
Is AI-driven legacy modernization actually fast now?
Yes. Really. This is the part where I refuse to be the person who waves away a real advance because it complicates my argument, because the advance is genuine and the numbers are not subtle. Work that used to eat quarters now takes days, and a serious chunk of the old drudgery of modernization, the mechanical translation of one framework or language version into another, has basically fallen off the effort curve.
Sit with that. A thousand applications, two days, five people. Amazon's chief executive later put the aggregate at roughly 4,500 developer-years of work saved across its Java estate, with more than half of its production Java systems modernized in under six months. Vendor numbers deserve the usual pinch of salt, and this one is a vendor describing its own tooling on its own code. Even halved, it describes a genuine shift. Multi-year core migrations that used to be career-defining slogs are finishing inside a single fiscal year. If that were the whole story, I would have nothing to write about, and I would be delighted.
Why does modernized code pass every test and still fail in week three?
Because a transpiler translates syntax. Not intent. That sentence is the entire article, so let me slow down on it. An automated rewrite is extraordinarily good at answering one question: what does this code do? It reads the branch, reproduces the branch, and the tests, which were also written against what the code does, light up green. The question it cannot answer is the one that actually matters over the next decade: why is this branch here at all?
Those are not the same question. Not even close. "What it does" is legible in the source; a machine can extract it, and increasingly a machine can extract it beautifully. "Why it does it" usually is not in the source at all. It lives in a decision someone made in 2009 after a bad night, in a regulator's letter, in the muscle memory of an analyst who has since retired to a lake somewhere and is not answering email. The code is the fossil. The reasoning that laid it down is the soft tissue, and soft tissue is exactly what does not fossilize.
And the scale of that soft tissue is easy to underestimate, because so much of the world still runs on code old enough to have children of its own.
Every one of those lines is a decision that a person once made for a reason. Multiply a fraction of them by the reasons nobody captured, and you have the real liability on a modernization program. Not the syntax. The syntax is the cheap part now. The expensive part is the intent, and the faster the rewrite gets, the more tempting it becomes to skip straight past the intent and ship.
What does an AI rewrite quietly drop?
The reasons. Specifically, three kinds of them, and I have been burned by all three. The exception buried in a twenty-year-old routine, the one branch that looks like a bug until you learn it was load-bearing. The rule a retired analyst added after an outage, undocumented because at the time it was obvious to everyone in the room. And the constraint that only ever lived in a person, never in a system, the kind of thing where the whole team assumed everyone else already knew it, so nobody said it out loud, so nobody wrote it down.
Here is the cruel mechanics of it. A rewrite that faithfully reproduces the code will faithfully reproduce the visible logic and silently discard the invisible reasoning, because reasoning is not code. Worse. It launders the loss. The old system at least had the weird branch sitting there as a clue, an artifact you could interrogate. The clean new system looks so tidy, so obviously modern, that the missing constraint leaves no trace. You have not just lost the knowledge. You have removed the last physical evidence that the knowledge ever existed, which is the same trap we described in the knowledge drain: the moment the person who held the context is gone, the artifact they left behind stops being a record and becomes a riddle.
The most-studied version of this is not a COBOL routine. It is a whole bank. In April 2018, TSB in the United Kingdom migrated roughly five million customers off the legacy platform they had been renting from Lloyds Banking Group onto a new core built by their parent company. On paper it was a modernization. In practice, around 1.9 million customers were locked out of digital banking, some saw the wrong balances, and the cleanup ran to about £366 million, with regulators later adding a £48.65 million fine.
The independent review that TSB itself commissioned and published, a rare and genuinely commendable act of transparency, is the interesting part. It did not blame a single bug. It found that the board had gaps in its understanding of the new platform's scope and complexity, and that testing had never been run at the scale the real system demanded. Read that again through today's lens. Nobody lost a line of code. They moved before they had fully recovered what the old system actually did and required. The syntax migrated. The understanding did not, and no amount of AI speed would have saved a migration that was fast in exactly the wrong half of the problem.
Source: TSB, independent review of the 2018 IT migration (Slaughter and May).
Can you recover intent before the rewrite?
You can. And this is the genuinely hopeful part, so I want to give it real room, because recovering intent is where the speed stops being a threat and quietly turns into the best tool you have. It is not one thing. It is two, and each half calls for a very different tool.
The first half is the documented logic: the calculations, the decision paths, the dependencies that really are sitting in the code, just tangled and uncommented. AI is superb here. The most credible modernization tooling already treats this as step one, not an afterthought. IBM's watsonx Code Assistant for Z ships a Business Rule Discovery capability whose entire purpose is to surface the policies and calculations embedded in old COBOL applications and document them before anyone touches the rewrite. Read that as the tell it is: the biggest name in mainframe modernization built a product step around the belief that you must recover the rules first. Nobody builds that if translating the syntax were sufficient.
The second half is harder, and no transpiler reaches it. It is the reasoning that was never in the code: the why behind the odd rule, the outage that prompted a fix, the exception that lives in a person. That half is not extraction. It is discovery, the human kind, the kind where you sit down with the supervisor who has run the process for eleven years and ask the questions nobody thought to ask. This is the entire premise of requirements intelligence: treat the intent behind a system as a first-class artifact to be recovered and made testable, not as a happy byproduct of reading the code. In a modernization, requirements are not the code. They are the reasons the code exists, and those reasons have to be pulled back into the light before the rewrite, because after the rewrite they are gone.
What does AI legacy modernization done right look like?
It looks like doing the two halves in the right order. Discovery first. Speed second.
Concretely: before the transpiler runs, pull the documented rules out of the old system with AI and get them in front of humans, then run real discovery on the reasons behind the strange ones, the branches that look wrong until someone explains the outage they prevent. Write each recovered reason as a testable statement, so it becomes a requirement a test can hold rather than a story that evaporates. Then, and only then, let the AI move at full speed, because now it is racing toward a target that includes the parts everyone used to assume. The velocity stops being a risk and starts being leverage. That is the whole reframe of AI legacy modernization requirements: the requirements were never the code, and once you have recovered them, the rewrite is the easy, fast, genuinely-improved part everyone has been celebrating.
Skip that order and the speed works against you. A fast rewrite on unrecovered intent does not save you the discovery work. It just moves the discovery to production, where it arrives as an incident instead of a conversation, and where it is many times more expensive to resolve. Modernization without discovery does not escape the old system's mistakes. It re-ships them, in a new language, with the evidence scrubbed off.
The half of modernization AI can't do for you
AI-driven legacy modernization is genuinely fast, and that is a real, valuable advance. A transpiler will move your syntax across in months. It will not move the intent: the exception in the odd branch, the rule a retired analyst added after an outage, the constraint that only ever lived in a person.
So recover the requirements before the rewrite. Extract the documented rules with AI, discover the undocumented reasons with the people who hold them, and write each one as a testable statement. Then let the speed loose. Do it in that order and modernization keeps the old system's hard-won wisdom while shedding its age. Skip it and you ship the old mistakes, faster, in a language nobody can blame.