AI-native legacy migration

Migrate legacy systems. Prove nothing changed.

Diffless agents rewrite legacy code, then replay your real production traffic against both versions and diff every response, write and side effect. You merge with evidence, not hope.

Sample report

$ diffless replay --service ledger-core --from capture/2026-10

replayed
0
identical
0.00%
clusters
0
POST/v2/payments/settle✓
GET/accounts/{id}/statement✗ #7
GET/v2/fx/rates✓

The problem

Rewriting is the easy part. Proving it is the hard part.

✗ 01

Tests cover what someone remembered to test

Legacy suites encode a decade of assumptions and miss the behavior nobody wrote down. Passing tests prove very little about equivalence.

✗ 02

Code review doesn't scale to 200k lines

Reviewers can check intent, not every rounding mode, null path and implicit ordering across an entire codebase.

✗ 03

Big-bang cutovers fail at 3 a.m.

Without evidence, migrations ship on confidence. The first real proof arrives as an incident in production.

AI can write migration code faster than any team can verify it. Verification is the bottleneck — Diffless turns it into an artifact you can audit.

How it works

From captured traffic to provable equivalence.

Four stages, each producing an artifact your engineers can inspect.

01

Capture

A lightweight sidecar or proxy records production traffic and downstream I/O. PII is redacted at the source.

02

Translate

Agents migrate module by module along the dependency graph, preserving interfaces. Every change is a reviewable PR.

03

Replay

Both versions run in a deterministic sandbox. Time, randomness and external calls are virtualized from recordings.

04

Prove

Responses, DB state, events and logs are diffed. Divergences are clustered and root-caused with code pointers.

Equivalence report

An Equivalence Report, not a leap of faith.

Every migration PR ships with evidence: what was replayed, what matched, and exactly where and why behavior diverged.

ledger-core · java8 → java21 · PR #412Sample report — illustrative
Requests replayed
2,418,903
Identical
99.71%
Divergence clusters
14
Endpoint coverage
96.4%
  • #7Rounding mode in InterestCalculatorhigh
  • #3Journal entries emitted in different ordermedium
  • #11Null vs empty array in /customers/{id}/kyclow
  • #2Timezone offset on statement cutoffhigh
  • #9Trailing whitespace in legacy CSV exportlow
  • + 9 more clusters

Cluster #7 · Rounding mode in InterestCalculator

Fix proposed — PR #418

GET /accounts/{id}/statement · 3,112 requests affected

legacy
{
  "account_id": "AC-20931",
  "period": "2026-09",
- "accrued_interest": "1042.35",
  "currency": "EUR"
}
migrated
{
  "account_id": "AC-20931",
  "period": "2026-09",
+ "accrued_interest": "1042.36",
  "currency": "EUR"
}
Root cause

Legacy uses BigDecimal RoundingMode.HALF_EVEN; migrated code uses HALF_UP.

→ src/main/java/ledger/interest/InterestCalculator.java:118

Determinism engine

Deterministic replay is the hard problem. We solved it first.

A diff is only useful if it's noise-free. Diffless controls every source of non-determinism before comparing a single byte.

Virtual clock

Every call to now() returns the recorded timestamp. Schedulers and timeouts advance on replay time, not wall time.

Seeded randomness

RNGs, UUIDs and nonces are seeded per request so both versions see identical entropy.

Recorded external I/O

Third-party APIs, queues and caches are replayed from captures. No live dependency is ever called.

Per-request database snapshots

Each request starts from the exact state it saw in production; resulting writes are diffed row by row.

Ordering & noise normalization

Reordered lists, generated IDs and timestamps are normalized so real differences stand out.

Custom equivalence rules

Declare what “same” means per field, as code, versioned alongside the migration.

diffless/equivalence.yaml
equivalence:
  ignore: ["$.meta.request_id", "*.generated_at"]
  numeric_tolerance:
    "$.fx_rate": 1e-9
  unordered: ["$.accounts[*].tags"]

Supported migrations

The migrations sitting in your backlog.

Java 8 / 11→ Java 21GA
Spring 4 / 5→ Spring Boot 3GA
.NET Framework→ .NET 8GA
Python 2→ Python 3GA
AngularJS→ ReactBeta
COBOL / PL/I→ JavaEarly access
Monolith→ Services (strangler-fig)Early access

Security & deployment

Built for regulated environments.

✓Your VPC, on-prem or air-gapped

Deploy the full platform inside your own environment, including fully disconnected networks.

✓Nothing leaves your perimeter

Source code and captured traffic stay in infrastructure you control.

✓Bring your own model

Use frontier models through your own agreements, or self-hosted open-weight models.

✓PII redaction at capture

Sensitive fields are redacted or tokenized before anything is written to disk.

✓Full audit log

Every agent action and every replayed request is logged and attributable.

✓Read-only to production

Diffless observes production traffic and never writes to your live systems.

Pilot

Start with one service. See the report in eight weeks.

Weeks 1–2

Capture

Capture production traffic on one bounded service.

Weeks 3–6

Migrate

Agent-led migration, with your engineers reviewing every PR.

Weeks 7–8

Prove

Equivalence Report and a concrete cutover plan.

FAQ

Questions engineering leaders ask.

What if production traffic doesn't cover every code path?+

A coverage map shows untouched branches. Diffless generates targeted test inputs for them and flags anything it can't exercise, so gaps are explicit in the report.

How do you handle writes and side effects?+

Replays run against per-request database snapshots and virtualized downstream services. Nothing touches live systems.

Which models do you use?+

Diffless is model-agnostic: frontier models via API, or self-hosted models running on-prem.

Does this replace our engineers?+

No. Engineers own the decisions. Diffless removes the manual verification work and makes every divergence explicit.

What does “equivalent” mean for intentional changes?+

You declare intended behavior changes as rules. The report separates expected changes from regressions.

Legacy is not a liability. Unverified change is.

Back to top ↑