Ledger health audit, October 2026¶
Status: to fix. An audit of be-ledger's data and code: whether the ledger matches the money
it moved, and what stands between it and an excellent ledger. The queries ran 8–13 October
2026, read-only, against prod-ledger and its read replica, the data warehouse and Elastic. The
numbers are as of those dates and may have changed since; read the current state before acting
on any item.
One interactive view is attached to this page:
- Ledger health audit: the verdict, a
scorecard, each open data item with its numbers, and 52 code issues, each with what happens,
the evidence, the code, how to fix it and how to verify the fix, and the checks behind the
numbers.
Verdict¶
Mostly yes, the ledger matches the money it moved. Since 1 March 2026 every balance follows from
the journal: 0 breaks in 104.8M journal rows. 18.81M debit card transactions from April to
5 October 2026 match Lithic's settlement report to the cent. Apart from Galileo-era rows, every
journal row that moved money from April to September 2026 has a be-transactions record.
It is not yet an excellent ledger. Prod publishes a transfer's debit event before the transfer
commits, so a rolled-back transfer still reaches statements, audit and the warehouse. The
database enforces no uniqueness, no references and no double entry, corrections are written
straight into the money tables with no record of them, and three callers can skip a debit on
retry.
Open data items¶
Amounts are in USD.
| Item | Size | Amount | What fixing it takes |
|---|---|---|---|
| Event copies that differ from the journal | 1,595 phantom events since February 2026, 13 lost and 2 doubled events, and 2 journal rows missing in the warehouse | −1,722,060.87 of debits that never happened | Deploy be-ledger master to prod, then remove the phantom events from be-accountstatements, be-auditing and the warehouse |
| Stale holds | 54 holds on 47 accounts keep money unavailable; 727 on 702 accounts are released in the balance but still open on the flow | −1,226.57 unavailable; 20,610.06 that a normal release would credit a second time | Correct the flows only, so no money is released twice |
| Balances with no opening entry | 348,378 accounts opened before April 2025, and 1,111 opened in April 2025 | +40,585,634.28 held before the first journal row; +6,434,523.47 beyond it on 66,927 accounts; +55,186.63 on the April 2025 accounts | Record opening balances, then correct what they do not explain |
| Credit-card transactions charged differently from Lithic | 43 transactions on 39 accounts, January to April 2026 | 1,642.59 charged less than Lithic settled | Decide with be-credit; a ledger correction alone would leave LoanPro wrong |
| Flows on the empty account id | 845 flows, the newest from November 2025 | +20,739.61 on no customer's balance | Move the 30 credited flows to the accounts their journal rows name; trace the owners of the other 815 |
| Visa stand-in transactions | 5 transactions on 5 accounts, 25 July and 31 August 2026 | The ledger holds 0, as Lithic's transaction record does; Lithic's settlement report settles 287.73 of credits and a 1.99 purchase | Ask Lithic which of its two records is right |
| Balance breaks before March 2026 | 23 rows on 17 accounts, November 2025 to February 2026 | Net −701.98 | Find the cause and correct them |
| Accounts with no balance row | 66 accounts, created 3 February 2026 | None | Give each a zero balance row: an authorisation on one is approved for any amount |
Code issues¶
52 in all: 3 Critical, 12 High, 17 Medium and 20 Low. The Critical ones:
- CL-1: an authorisation on an account with no balance row is approved for any amount. Not
seen in prod. - CL-2: be-pspfunding and be-phoneplan can skip a debit when a message is retried. Not
measured; it needs their databases. - CL-3: be-mtu marks failed top-ups as done. Not measured; it needs its database.
The first step is deploying be-ledger master to prod, which stops new phantom events.