"Fixed price" is the phrase that closes the deal. It sounds like the buyer finally got the upper hand — a number on a contract, a vendor who eats the risk of scope creep, a budget line the CFO can defend to the board. On a mainframe modernization, it is usually the opposite. Fixed price is not the buyer's protection. It is the mechanism that turns every requirement the vendor didn't discover during the sales cycle into a paid amendment, on schedule, for years.
The machine works because of an asymmetry that exists on day one and never goes away: the vendor wrote the bid, and the vendor controls what counts as "in scope." The buyer wrote an RFP describing a system they may not fully understand themselves — that's often the whole reason they're modernizing — and signed off on a proposal that translates that description into line items. Any gap between what the mainframe actually does and what the proposal describes becomes billable the moment someone notices it. And on a decades-old COBOL estate, gaps are not the exception. They are the terrain.
Why the gaps are guaranteed, not incidental
A production COBOL system that has run a business for thirty or forty years accumulates behavior nobody wrote down: fee waivers coded as special-case branches after a specific customer complained in a year nobody remembers, rounding rules that only fire on the last day of a fiscal quarter, batch jobs that silently correct data entered wrong by a screen that was retired in the 1990s. None of this is in a requirements document, because it was never a requirement — it accreted. A discovery phase measured in weeks cannot surface it. Only reading the actual code, and comparing actual outputs against actual production data, can.
A vendor who bids fixed price against an estate they have not yet parsed line-by-line is making one of two bets: that the undiscovered behavior is small enough to absorb, or that it isn't, and the change-order pipeline will cover the difference. The second bet is the more common one, because it's the more profitable one. A rescue project that keeps discovering "new" requirements after signature is not failing at estimation. In many cases it is executing the estimation exactly as designed.
The mechanics of the machine
The pattern has a predictable shape once you've seen it a few times:
- The bid is scoped to the RFP, not the code. The proposal describes the system in terms of business capabilities ("process claims," "calculate benefits") rather than verified, line-level behavior. This is fast to write and impossible to hold anyone accountable to later, because "process claims" can mean almost anything.
- Discovery is thin, and structured to end on schedule. A time-boxed discovery phase produces a document, not a parity baseline. Nobody has actually run the legacy system and the new one side by side on real transactions yet, so nobody actually knows what's missing.
- Divergence surfaces during testing, one behavior at a time. A batch run doesn't match. An edge case in interest calculation is wrong. Each one is technically true: it wasn't in the SOW, because the SOW was never built from ground truth.
- Each divergence becomes a change order. Not a fix — a negotiation. The vendor is not obligated to eat the cost of a requirement it didn't know about, and the buyer is not in a position to argue, because they don't have an independent record of what the legacy system actually does either.
- The original fixed price becomes the floor, not the ceiling. Multi-year public-sector modernizations that blow past their original budgets by a large multiple are common enough that procurement offices and audit bodies write reports about the pattern rather than treating any single instance as an outlier.
None of this requires bad faith on any individual's part. A project manager approving a change order for a legitimately undiscovered edge case is doing their job. The problem is structural: the incentive to under-discover at bid time and over-discover at execution time is built into how the contract is priced, and nobody on either side has to be dishonest for it to play out that way every time.
What actually closes the loop
The fix is not a better contract clause. Buyers have tried tighter SOWs, capped change-order pools, penalty clauses for schedule slip — and vendors who operate this way price around all of them, because the underlying information asymmetry is untouched. The vendor still knows more about what the legacy system does than the buyer does, at the moment the price is set.
The only thing that closes the gap is moving the discovery work to before the price is set, and making its output something the buyer can independently verify rather than take on faith. That means: run the converted system and the legacy system against the same real transactions, byte-for-byte, before a dollar of the main engagement moves — not as an early milestone inside the fixed-price contract, but as a precondition to signing it. If a vendor can show you a parity report on your actual data before you commit, the "we discovered new scope" conversation mostly disappears, because the scope was measured, not estimated. If a vendor tells you that level of proof isn't possible before contract — that it has to happen "during Phase 1" — ask why the discovery that determines your total exposure is scheduled to happen after your signature, not before it.
A fixed price that was set before anyone verified what the system does isn't a commitment. It's an opening bid with a change-order pipeline already built in behind it.