Applying AI to Legacy and Complex Codebases

Legacy Systems AI Modernization

Last updated: 13 September 2026

What does it mean to apply AI to a legacy codebase?

Applying AI to a legacy codebase means using models to read, guide, and gradually modernize systems that still run the business but no longer match how new software is built. Vamsi Katragadda’s October 2024 SSRN paper treats this as a strategy problem, not a plugin problem. The model has to be taught the old system. The old system will not politely resemble a tutorial repo.

Enterprises keep these systems because they work, they hold years of rules, and a rewrite is expensive. They are also rigid, under-documented, and hard to change with the methods that built them. The research article argues that AI can offer guidance, automate routine work, and help optimize that code, if teams face three recurring obstacles: poor documentation, outdated technologies, and complex interdependencies. The rest of the paper is a roadmap: refactoring, model customization, hybrid human-AI work, and continuous learning. A copy also sits on SSRN as abstract 5150439 for readers who want the working-paper record.

"A coding assistant that only knows modern stacks will sound fluent while it breaks a twenty-year-old batch boundary. Fluency is not understanding."

This piece stays with that roadmap. If you are trying to put an assistant on a mainframe-adjacent service, a long-lived Java monolith, or a tangle of scripts nobody wants to own, the useful question is not “which model is smartest.” It is “what has to be true about the code, the model, and the people before a suggestion is safe to try.”

Why do poor documentation, outdated tech, and interdependencies block AI?

Poor documentation, outdated tech, and interdependencies block AI because most assistants infer intent from comments, current APIs, and clean module boundaries. Legacy systems often have none of those. Katragadda’s point is blunt: a model that cannot see why a function exists will still propose a change, and the change can be locally pretty and globally wrong.

Documentation is the first failure. Tools that offer refactoring or bug detection usually need some account of logic and flow. In the absence of comments or specs, the model guesses from names and nearby code. That guess is often a modern idiom pasted onto an older contract. Missed opportunities are the kind outcome. Incorrect recommendations are the expensive one. A deleted “unused” branch that only fires on a year-end file is a classic example of the latter, even if the paper does not stage that scene. The mechanism is the same: missing context.

Outdated technologies are the second failure. Legacy stacks were built with languages, frameworks, and runtimes that current training sets under-represent. Incompatibility is not only about parsers. It is about idioms: copybooks, stored procedures, generated code, and frameworks that froze a decade ago. An assistant that wants to rewrite everything in the style of last year’s web tutorial is not helping. It is proposing a migration you did not ask for, inside a pull request you thought was a cleanup.

Interdependencies are the third. Complex codebases hide coupling in shared tables, implicit call orders, and “do not touch this file” folklore. A local refactor can change timing, lock order, or a side effect that another team depends on. Traditional methods already struggle here. AI does not magically see the graph if the graph was never written down. Mapping dependencies is therefore part of applying AI, not a separate archaeology project you do later if you have time.

That mapping can start as a boring inventory. Which jobs write which tables. Which services read those tables at night. Which libraries are pinned because a vendor certificate still lives in a forgotten store. An assistant can help list imports and call sites. It cannot tell you that two modules must run in a fixed order because a file lock is the only coordination they have. Someone who has been paged at 2 a.m. still has to annotate that. Once the annotation exists, customization and retrieval have something to hold. Until then, “intelligent guidance” is a confident walk through a minefield.

The three blockers, in working terms

  • Docs: no comments, stale wikis, and business rules that live only in production behavior
  • Tech: languages and frameworks the model barely saw during training
  • Coupling: changes that look local and are not

How should teams use refactoring with AI in the loop?

Teams should treat refactoring as both a way to make the codebase readable to a model and a task the model can help perform. Katragadda puts code refactoring at the center of the strategy list. You do not wait for a greenfield rewrite. You create seams, then let assistance work inside those seams, with tests that prove behavior did not move.

A practical sequence looks like this. First, pick a slice that matters and is bounded: one batch, one service, one screen flow. Second, add characterization tests or golden files so you can see breakage. Third, do a small human-led cleanup so the model has modules instead of a 4,000-line file. Fourth, ask the assistant for targeted refactors: extract a function, rename with care, isolate a side effect. Fifth, review as if a new hire wrote the patch, because in a sense one did.

The paper’s modernization goal is long-term sustainability, not a demo that translates a file into another language and calls it done. Translation without structure copies the debt. Refactoring that preserves behavior and reveals intent is the slower path that actually unlocks later AI use. If your organization wants “AI on the monolith” by Friday, the honest answer is that Friday is for mapping and tests. The model comes after there is something it can hold onto.

Refactoring that helps AI

Clearer names, smaller units, fewer hidden globals, and tests that pin behavior before the assistant touches a line.

Refactoring that wastes the week

Style-only rewrites, framework jumps inside a hotfix, and generated modules nobody can review against a spec.

Why must AI models be customized for legacy systems?

AI models must be customized for legacy systems because tools built for modern codebases often fail out of the box on older structure, naming, and defects. Katragadda’s claim is that fine-tuning on historical data from that system is how the model learns the patterns, problems, and optimization chances that actually exist there. Generic skill is not the same as local skill.

Retraining, in this sense, can mean a full pass on proprietary corpora or a lighter fine-tune on diffs, tickets, and representative files. The training set is the archaeology: how this team names things, which errors keep returning, which modules are sacred. A model that has seen your incident history is more likely to treat a “weird” branch as load-bearing. A model that has only seen public GitHub is more likely to “simplify” it away.

Customization also includes retrieval. If you cannot fine-tune, you can still ground the assistant in local docs, runbooks, and a dependency map, and you can constrain it to a language pack that matches the stack. The paper’s emphasis is still on learning from the system itself. Prompting harder is a weak substitute when the distribution of your code is far from the distribution of the base model. Budget for that gap, or the assistant will keep offering answers for a different company.

What is a hybrid human-AI approach to legacy work?

A hybrid human-AI approach splits work so the model automates repetition and the person keeps context and sign-off. Katragadda is explicit that AI is unlikely to fully replace expertise on complex legacy systems. Bug detection, refactor drafts, and performance hints can be machine-paced. Interpreting those hints against a business rule that is not in the file is a human job.

That split is easy to endorse and easy to skip in a demo. A tool that opens a pull request without a named reviewer is not hybrid. It is unsupervised change on a system that already has scar tissue. Hybrid means the assistant is in the IDE or the review bot, and a person who knows why the payroll calendar is weird still merges. It also means the person can reject a suggestion without having to fight the tool’s confidence score.

Job Better as machine-paced Better as human-owned
Comprehension Summaries, call graphs, “what does this module do” Confirming the summary against production behavior
Defect work Scanning for known bug patterns and similar past fixes Deciding whether a match is a real fault
Refactoring Draft extracts, renames, dead-code candidates Preserving hidden contracts and rollout order
Performance Hints from profiles and repeated hot paths Capacity and failure-mode judgment

If you need a one-line policy, use the table as the policy. The assistant may draft. The person who can still explain the batch window owns the merge. That is how you get speed without donating the system to a model that has never seen a year-end close.

How does continuous learning keep the assistant honest?

Continuous learning keeps the assistant honest by updating it as the codebase, the incidents, and the team’s habits change. Katragadda includes it as a core strategy because a one-time fine-tune is a snapshot. Legacy systems keep accruing patches. An assistant frozen in last year’s tree will start recommending patterns the team already abandoned.

In operations terms, this looks like feeding accepted refactors, rejected suggestions, and new tickets back into retrieval or training, on a schedule, with a review of whether quality is rising or falling. It also looks like watching for drift: a sudden taste for a new library, a rise in reverted AI patches, a cluster of incidents in files the bot touched. Continuous learning without evaluation is just continuous change. The paper’s goal is sustainability and efficiency. Those words only hold if someone is scoring the suggestions against production truth.

There is a people side. Teams that treat the assistant as a junior will correct it. Teams that treat it as an oracle will not. Hybrid work and continuous learning are the same idea at two timescales: the person in the review, and the process that remembers what the person did. Skip either and you get a tool that was impressive in week one and noisy in month four.

Katragadda’s four strategies only work as a set. Refactoring without customization still feeds the model a dialect it barely speaks. Customization without a hybrid gate produces fluent patches nobody should merge. Hybrid review without a learning loop repeats the same bad suggestion next month. Continuous learning without tests will happily learn the wrong lesson. The paper is a roadmap for sustainability, which is a slower word than transformation. That slowness is the point. Legacy systems survived because they were careful in the wrong places and reckless in the forgotten ones. AI does not reverse that pattern unless you force it to.

A worked example, still in the paper’s spirit rather than a numbered case study, looks like a billing batch written in an older language, with a thin comment header and three downstream jobs that consume its file. You do not ask the model to rewrite the batch. You ask it to list side effects, then you confirm the list with an operator. You add a golden output from last month’s run. You fine-tune or retrieve on this team’s diffs. You let the assistant propose a extract of a validation block. A person who knows the leap-year rule reviews it. Next week the accepted extract is in the context again. That is applying AI. A chat window that emits a new language is not.

What should a legacy team do first?

A legacy team should first pick a bounded slice, capture behavior with tests, and decide whether the assistant will be customized, retrieved-against, or both. Katragadda’s roadmap is not “turn on Copilot in the monorepo.” It is a sequence that respects how brittle these systems are, then uses AI where repetition and pattern matching are actually the bottleneck.

A first-month sequence

Inventory the three blockers: where docs are missing, which runtimes are frozen, which couplings scare the on-call

Pin behavior: characterization tests or golden outputs before any generated patch

Ground the model: fine-tune or retrieve on this system’s history, not only a public corpus

Keep a human merge gate: especially on anything that touches money, batch windows, or shared data

The promise in the paper is real enough to take seriously: intelligent guidance, less routine toil, and a path to keep old systems alive without pretending they are new. The constraint is also real. If you skip customization, skip hybrid review, or skip learning from what the team accepts and rejects, you have not applied AI to a legacy codebase. You have applied a modern autocomplete to a system it does not understand, and you will find out at the worst possible time.

Frequently Asked Questions

Why do generic AI coding tools fail on legacy systems?

Generic tools are trained on modern, reasonably documented code. Legacy systems often lack comments, run on outdated languages and frameworks, and hide business rules in tight interdependencies. Katragadda argues that out-of-the-box models miss those patterns and can recommend changes that look clean and still break a downstream batch job.

What does customizing an AI model for legacy code involve?

Customization means retraining or fine-tuning on data from the actual system so the model learns that codebase’s patterns, defects, and optimization chances. The paper treats this as a requirement, not a nice extra, because a model that only knows current frameworks will misread older control flow and naming.

What is a hybrid human-AI approach here?

Hybrid work splits labor: the model handles repetitive detection, refactor drafts, and performance hints, while people keep context, business rules, and final decisions. Katragadda is explicit that AI is unlikely to replace expertise on complex legacy systems. The human is not a fallback. The human is the owner.

How does continuous learning fit legacy modernization?

Continuous learning means the model keeps updating as the codebase, runtime data, and team habits change, instead of freezing a one-time training run. Legacy systems evolve through patches and workarounds. A static assistant will drift. A learning loop, with review, is how the paper wants guidance to stay useful.

Should you refactor before you add AI, or use AI to refactor?

The paper treats refactoring as both a preparation step and a job for AI. Some structure has to exist for a model to see modules at all. AI can then propose further cleanups. In practice that means a thin human-led pass to isolate a slice, then model-assisted cleanup inside that slice, not a big-bang rewrite prompted in one chat.

Related articles