Parity validation · The signature move

Parity is
proven,
not promised.

Most modernization gambles surface at cutover. We move the proof earlier. Every slice runs against the legacy under shadow traffic until its behavior matches — then a parity gate decides whether it ships.

Shadow traffic Parity gates Behavior, not just output
The parity gate
01
Functional parity
The modern slice produces the same outputs as the legacy for the same inputs — including the corner cases nobody wrote down. Behavior, not just the happy path.
02
Data integrity
Every record the slice reads or writes is reconciled against the legacy. No silent drift, no rounding surprise, no orphaned row at cutover.
03
Non-functional parity
Performance, security, and accessibility hold or improve. A slice that is correct but slower, or correct but less secure, does not pass.
04
Traceability log
Every requirement traces from the legacy behavior, through the spec, to the test that proves it. The gate produces an audit trail, not a verbal assurance.
On pass promote · else iterate
The short answer

What is parity validation?

Parity validation is proving that a modernized slice behaves the same as the legacy it replaces — same outputs, same data effects, same performance and security posture — before it ever carries live traffic. ModernLift validates parity with shadow traffic and a parity gate that every slice must pass before promotion.

The reason most rewrites fail late is that they validate against the spec, and the spec was never complete. The legacy system is the real specification — including the rules nobody documented, the special case added in 2009, the rounding that one downstream report depends on. Parity validation treats the legacy as the source of truth and proves the new slice against it, in production conditions, before a single user is moved.

How we prove it

Shadow traffic, then a gate.

The modern slice earns production. It runs alongside the legacy on real traffic, gets diffed against it, and only ships once the divergences reach zero on the agreed criteria.

01
Mirror
Live requests hitting the legacy are duplicated to the modern slice. Production traffic, not synthetic load — the real distribution, the real edge cases.
02
Compare
Both responses are diffed automatically: output, side effects, and the data each path touches. The legacy is the source of truth.
03
Triage
Every divergence becomes a ticket with the exact input that caused it. Surprises become tickets, not outages.
04
Promote
When divergences reach zero on the agreed criteria, the slice clears the gate and live traffic flips behind a feature flag — rollback one toggle away.
We do not ask you to trust the new code. We show you, on your own traffic, that it does what the old code did — and only then do we move a single user.
— Proof, not promises
What the gate checks

Four checks stand between a slice and production.

Parity is not one number. A slice clears the gate only when all four hold — and a deferred queue captures anything intentionally left for a later slice, in the open, never lost.

01
Functional parity
The modern slice produces the same outputs as the legacy for the same inputs — including the corner cases nobody wrote down. Behavior, not just the happy path.
02
Data integrity
Every record the slice reads or writes is reconciled against the legacy. No silent drift, no rounding surprise, no orphaned row at cutover.
03
Non-functional parity
Performance, security, and accessibility hold or improve. A slice that is correct but slower, or correct but less secure, does not pass.
04
Traceability log
Every requirement traces from the legacy behavior, through the spec, to the test that proves it. The gate produces an audit trail, not a verbal assurance.
The deferred queue
Not every difference is a defect — sometimes the modern slice should behave better than the legacy. Those intentional divergences are logged in a deferred queue and decided on the record, so "improve" is never confused with "broke." The queue feeds the next slice.
Where parity-first is hard

The honest boundary.

Shadow comparison needs the legacy to be observable and its behavior to be deterministic enough to diff. Non-deterministic outputs, side effects that cannot be safely mirrored (a real payment, an irreversible email), and behavior driven by external state all make parity harder — sometimes requiring synthetic replay or a narrower gate. We name those cases in Discovery and design the validation around them, rather than discovering them at cutover. Knowledge without rollout is a report; rollout without parity is a gamble. We decline the gamble.

Frequently asked questions

What is parity validation?
Parity validation is proving that a modernized slice behaves the same as the legacy system it replaces — same outputs, same data effects, same performance and security posture — before it ever carries live traffic. ModernLift validates parity with shadow traffic and a parity gate that a slice must pass before promotion.
How is parity different from passing a test suite?
A test suite proves the code does what you specified. Parity proves the code does what the legacy actually did — including the undocumented behavior the original spec never captured. We treat the legacy as the source of truth and diff against it under real traffic, so the rules nobody wrote down are caught, not assumed.
What is shadow traffic?
Shadow traffic mirrors live production requests to the modern slice without affecting users. The legacy still serves the real response; the modern slice runs the same input in parallel, and the two are compared. It surfaces real-world divergence under the real distribution of inputs, before any cutover.
What happens when a slice fails its parity gate?
It does not get promoted. The divergence is logged as a ticket with the exact input that caused it, the slice goes back through the loop, and the next slice is unaffected. No regression reaches production, and the business stays on the legacy path the entire time.