Modernizing Mainframes: A Behavior-Based Approach to Verification

September 22, 2026
Open Read Mode
Close Read Mode

Introduction

Modernization projects often fail after the code is rewritten, at the point where it has to operate inside the organization built around the original system.

A rewritten program can pass tests and still produce incorrect results in cases the tests didn't cover: rounding behavior, file organization, error handling, or call semantics that other systems depend on. These issues often do not appear during development; rather, they appear after cutover, or even during production, as reconciliation discrepancies or incorrect output.

This is because the original mainframe application is not only simply a reflection of its source code. It includes the batch schedules, downstream jobs, and business processes built around its behavior over time. Reproducing the code's logic is not the same as reproducing the system's behavior.

This paper describes an approach to closing that gap. Extracting business logic from legacy code is not sufficient. The missing step is verifying against the live behavior of the running system, not just the logic that has been extracted from its code. This is the critical proof, yet it is often deferred until after the code has been produced, and is done on the entire new system or module. Defects compound and are deferred until there is too much broken to go forward and the project abandoned.

Building on business rule extraction

With the advances of LLMs, a variety of tools on the market today can read legacy source code and produce a structured, plain-language map of an application, organized from lines of business down through features and component-level rules. Known as “business rules extraction” (BRE), this is useful for planning, scoping, and sequencing a modernization program. It gives business and technical stakeholders a shared reference for what needs to move and what doesn’t. It decomposes and explains domains based on the static code itself, an effort that can answer questions about the system that few or none in the organization can.

Problems arise when this extracted rule set is treated as a complete implementation spec. BRE surfaces logic that qualifies as a business rule: it does not surface file organization, numeric encoding, subroutine call semantics, or runtime error handling. These are the implementation details that are below the abstracted concept of a  business rule. The problem is that  implementation details and exceptions are part of how the program behaves; without those details, the same conceptual process will not produce the same outcomes (e.g. balancing your ledger, properly generating invoices, ordering inventory). 

Take the sending of an invoice, for example. The action of sending an invoice is only part of making sure it is the right value.  For example, an invoice may be sent to the right third party, assembled from the right fields, but the number calculated is incorrect because the sequence of discounts is applied in the wrong order. 

Fig 1: The extent of testing behavior that exists beyond what the code says

This is a “coverage” problem, or an incomplete execution. Or put another way, a rewrite can pass every test derived from the extracted rules and still be incorrect in areas the extraction missed. The details most often missed this way are the details that determine whether a cutover is clean or requires months of correction. (A longer treatment of this argument is available in our whitepaper, Mainframe Modernization Is A Verification Problem.)

BRE-style extraction remains very useful for scoping a program and aligning stakeholders on a target architecture. The other considerable task is turning that plan into a production system, which requires a separate step: verifying the rewrite against the live behavior of the system being replaced, not only against the rules that were extracted from it. When generating code, you want it to have the high level picture (the abstract rules) without losing the particulars (the ways implementation details impact outcomes). You need to test for both, and generate code guided by both.

The approach: Analyze, Rewrite, Orchestrate

The approach at the center of this paper is straightforward: use production data — the inputs and outputs of mainframe programs — as the build specifications for the new code candidate. Then use that candidate to verify any new program or system before any of it replaces the original. While this can sound like an extra step layered on top of an already long modernization effort, in practice, it's the step that removes the largest source of risk and delay. It eliminates the work that happens after cutover, when a mismatch is a production incident that can negatively impact operations and could take days or weeks to untangle.

Imogen is a mainframe modernization platform built to automate this approach at scale. It is organized into three phases: Analyze, Rewrite, and Orchestrate. 

The full scope of the Imogen mainframe modernization platform

Analyze in hours

Before any rewriting occurs, the existing system is analyzed at the level of what it executes and how its components connect, not only at the level of business rules.

Imogen uses a deterministic parser to process the codebase and produce a structured description of the system: execution flows, the data sources each job reads from and writes to, and the dependencies between jobs, programs, and files. In a few minutes, this produces a comprehensive topology of the system as it currently runs.

The parsing takes minutes, or even seconds, depending on the size of the code base. Once parsed, it produces analyzable insight from the code within hours, which can be used to sequence the modernization work. Teams can also query the parsed system in natural language as a secondary interface to the structural analysis, for example, to find which jobs depend on a given set of tables. We’re starting with the big picture, as shared with a BRE approach before also getting the lower level, higher fidelity details.

Rewrite, with layered verification

Once the system's global or general structure is understood, Imogen continues to analyze the low level details of the system’s live running behavior. The two perspectives are used to generate a baseline candidate implementation, which is deterministically verified in two layers.

Layered tests that exhaustively test a candidate for all code possibilities locally before using actual production data to establish equivalence.

The first layer consists of characterization tests which can all be run locally at machine speed. Some tests are built deterministically: mathematically exercising all reachable code paths in the original program. Those tests are combined with tests generated by an LLM based on the structure of the code. Together, these define comprehensive tests which can be run locally, off the mainframe, to observe the correct live behavior of the system. 

These tests are used to guide LLM code generation, which uses specifically tuned agent skills, mainframe-specific libraries, and bespoke pipelines to produce a candidate implementation that must pass these live-behavior tests. The tests themselves are derived from running the original code locally, not from an estimate of which cases matter. 

The second layer uses production and non-production data captured from the mainframe itself: real input and output pairs recorded while the mainframe continues to run. For one customer, this meant capturing roughly 600 GB of real production data (under approved client controls). This becomes the evidence base every claim of equivalence would be measured against, and it expedites the process of confirming the new candidate system does the same thing by parallelizing the process. 

For example, we capture six months of data while generating the candidate, and then use that to expeditiously prove the same outcomes (e.g. the correct invoice) is generated for all the data that has been captured. The modernized code is run against the same underlying data as production, giving full confidence that the outcomes are correctly preserved. Outputs are compared byte for byte, with every divergence logged and traced to a root cause which is fed directly back into the code generation process for refinement.

Orchestrate

The final step is deploying a verified replacement without disrupting the business processes built around the original system.

Modernized workloads run in a pre-production environment alongside the existing mainframe jobs, with full integrations to the up and downstream systems. This confirms the modernized workload meets or exceeds performance targets under real operating conditions before cutover, but is much faster than a “deferred testing” strategy, as we have already run historical production data through the candidate. Teams can modernize incrementally, in the order the business prioritizes, while production continues running.

Results and organizational impact

Across the three phases: deterministic analysis established what the system actually did by looking at what the system actually does.

Layered behavioral verification confirmed the rewrite preserved the business outcomes that matter, verifying this in detail. This focus catches categories of divergence that a rules-only approach would not have surfaced.

Identifying any divergence  continuously, rather than only at the end, means the platform can automate the remediation of individual issues. 

Automation is far easier when working with an  early, trackable, and closable list. Small components are proven to work before larger units, avoiding that testing trap where all the errors manifest at the same time and stymie progress — or, in many cases, kill the project.

Conclusion

The root failure mode in mainframe modernization is not writing the wrong code. It is finding out the code is wrong after it’s been written, and untangling what it takes to fix it.  Verifying against the live behavior of the running system, in small increments where fixing is easy, and doing this continuously and from the start, is what moves that discovery earlier, from a post-cutover incident to a tracked, explainable, and closable gap during development. That is the problem Imogen was built to solve: safely, quickly, and reliably.

Background Trees

Your new legacy starts here.

We believe every organization deserves to realize their vision, free of constraints from the past. Imogen makes that possible: safely, reliably, fearlessly.

Try it for free