Migration Status Map

What is Done & Pending

A migration honesty panel — four states, not a pass/fail. It shows which business flows the browser kernel already reproduces indistinguishably from iDempiere (maxDiff=0c), and exactly what stands between that and a full tenant cut-over.

Done — folds to the cent, or granted by architecture · Pending — data not wired · Pending — capability unbuilt · N/A — deleted by design
This is a claim about substrate and delivery, not feature parity. 1% is the DNA — the Application Dictionary + document logic, folded to the cent (Order · Invoice · Payment · GL); the rest is scaffolding the architecture deletes (~580k lines of screens, ORM, plumbing). Counts trace to the coverage-by-capability table in the paper (live Odoo 17 search_count + GardenWorld seed); deleted-tier LOC from the iDempiere source sweep.
🟢 Done · in the new experience
Folds to the cent today
Every figure reconciles to the cent against real iDempiere, in two currencies. 44 checked surfaces.
All figures reconciled to the cent against real iDempiere — every check independently falsified (a deliberately broken rule must fail it)
🟠 Pending · extraction gap
Fold proven — data not yet wired
The engine already folds these flows (passing witness each). Mechanical extractor work, not engine development.
iDempiere-side: no extraction gap — GardenWorld is resident & full. These rows are Odoo-side. Backlog → MIGRATE_INSTALL_TENANT.md §RESUME
🔴 Out of fold-scope — by data or architecture
No unbuilt fold capability remains
Every posting and report this demo's data supports already folds — gap-closure complete (2026-06-14). What's left here can't be folded: the source has no such postings, or it's program code, not declarative ERP rules.
Bottom line: none of these is an unbuilt engine gap — fold-gap closure is complete (all priorities, 2026-06-14). Per the Grand Lane, the genuine remaining work is wiring proven engines into the live screens — of the Complete → Create → Post journey, Complete (J5), Create (J4) and Post (J6) are now live on iDempiere's own surfaces — Complete/Create sign, and a completed document's GL now renders to the cent on the invoice window (Posting-Preview), with a receipt and a financial statement that fold from the books; fanning the journey across all five tenants is the active leg — UI, not folding. iDempiere-side: no interpreter gaps remain.
🔵 N/A · deleted by architecture
No port — leaves the denominator
Whole tiers the serverless model deletes — not missing features, no counterpart by design.
What the server did
Who does it now
ZK web UI · 190k LOC
the browser renders
Generated X_* ORM · 345k LOC
AD rides as data
Server-side HTML · 44k LOC
gone, no server
JDBC · OSGi · app server
nothing owns the record
Web services tier
the op-log is the wire *
* Live nowShare a sale, no server: a deliver-later sale travels device-to-device by your own channel — copy → WhatsApp / email → paste → it replays on the other phone. Working today, not a roadmap item (PR #300).
Granted in exchange — the -marked rows run nothing in their place; deleting 40% is what makes the engine offline-first, serverless, and per-device shardablelive today. Finer warm/cold tiers + checkpoint boot are proven-ahead, switched on when scale needs them.

The Holy Grail

One engine, every ERP — no server, nothing destroyed

How any ERP's before state becomes a single, foldable after state — and why "the log is the truth" stays editable and maintainable.

① Any ERP — the source (before)
Each runs its own server + database
iDempiereOdooSAPDynamics
Each carries a model, its data, and its rules / automation — and overwrites rows in place (destructive updates: the past is lost).
▼   MIGRATE — extract, don't rebuild   ▼
② Translate — the one elegant law
Model → the AD canonical dictionary · Rules → re-filed by op-log effect
DERIVEout ← f(in) · no op
VALIDATEassert(p) · gates, no op
ACTemits signed ops
Code-only remainder → a user plugin (exposed to find & resolve), never an auto-import.
▼   every change becomes one signed op   ▼
③ The truth — the spine
A signed, hash-chained op-log — append-only
op → op → op → op → op → …
Every change, kept forever. Nobody owns it; any client can verify and rebuild from it.
▼   FOLD — replay the log   ▼
④ The live state (after)
Current numbers + screens = fold(op-log)
In the browser, no server. One renderer, N dictionaries · offline · per-device.
Before — any big ERP
After — the Grail engine
Truth lives in a server row (overwritten)
A signed op-log (append-only)
Change a value = UPDATE — past lost
Change = append an op — past kept
Automation = code per ERP
3 typed lanes + user plugin
"How did this get here?" = guess
Replay the log — exact
EDITappend a new signed op → state changes now, past kept
BRANCHBlue Future — a safe fork; accept or discard
AUDITfold to any past point — exact provenance
FIXappend a reversing op — nothing destroyed
"Can we edit it? Is it maintainable?" — the op-log is git, for your ERP data. You never hand-edit history; you commit a change. To edit anything you append a signed op and the live state — a fold of the log — updates at once: the present is always editable, the past stays as the audit trail. Maintainable more, not less — every value carries its own history, reversible and replayable, with no destructive-update mysteries.