++++The Record · errata
Everything we got wrong.
Every register here makes claims about somebody else's system. The only thing that
makes that defensible is a permanent, specific account of the times we were wrong — kept with the
same care as the findings, and never quietly edited away.
Errata
8
append-only; nothing is deleted
Reached the public
4
published, then withdrawn
Caught first
4
disclosed anyway, but not the same thing
Found by machinery
4
2 by a control or fault injection, 2 by a written test
Why this page is specificA retraction is the cheapest thing to fake and
the hardest thing to fake precisely. Every entry below names the exact wrong value, the
exact mechanism, and the test that now makes it unconstructable. That is checkable.
“We take accuracy seriously” is not.
Two kinds, never blurred. Errors that reached the public are marked separately
from errors caught before anyone saw them. We are not owed credit for the ones that never got out.
§ 0.2 — The record of corrections
Entries, oldest first
E-001
PUBLISHED, THEN WITHDRAWN
2026-08-04
found by our own machinery
- Claimed
93 FXRP redemptions were proven defaults — agents that took a fee and never delivered XRP.
- Actually
- Zero of them were defaults. All 91 agents examined had paid, in full, on time.
- Mechanism
- The FDC request asked whether a payment of valueUBA existed. An agent owes valueUBA − feeUBA. The amount we asked about had never existed, so the oracle truthfully attested its absence for every redemption. The attestation was correct; the question was wrong.
- Caught by
- A control test that required the verifier to REFUSE redemptions the chain already recorded as performed. It refused none of them, which meant the request could not distinguish paid from unpaid.
- Now prevented by
- amountOwed() is now the single place the obligation is computed, verified against settled redemption 43128188 whose real XRPL payment delivered exactly valueUBA − feeUBA.
E-002
PUBLISHED, THEN WITHDRAWN
2026-08-04
found by re-reading the evidence
- Claimed
Control C3 reported a 400 UBA exception against Flare, asserting availableFunds + escrowedFunds ≤ totalAvailableUBA.
- Actually
- Those figures were never defined to relate. The 400 UBA is a fee the asset manager nets off.
- Mechanism
- Two numbers from two contracts were compared because they looked comparable. Nothing in the protocol says they should be equal, so the difference was not a finding.
- Caught by
- Reading the asset manager's own accounting after the exception was published.
- Now prevented by
- The wedge is now disclosed as an observation (C5) rather than judged, and the regression is pinned by a test asserting the exact 400 UBA gap is expected.
E-003
PUBLISHED, THEN WITHDRAWN
2026-08-04
found by our own machinery
- Claimed
Control C3 asserted escrowedFunds = totalAvailable − immediatelyAvailable, and reported CLEAN every period.
- Actually
- The control could not fail. It had been printing CLEAN for reasons unrelated to the vault's health.
- Mechanism
- coreVaultAvailableAmount() derives both of its outputs from the same escrowedFunds storage slot. Corrupting that slot from 500,000,000,000 to 999,999,999,999 moved both sides of the identity together and the control stayed green — a tautology wearing the costume of a reconciliation.
- Caught by
- Deliberate fault injection on a forked chain. Nothing else would have surfaced it.
- Now prevented by
- C3 now reconciles Flare's escrowedFunds against XRPL Escrow objects — two chains that cannot move each other — and the red run fails the build if C3 survives its own fault.
E-004
CAUGHT BEFORE PUBLICATION
2026-08-04
found by re-reading the evidence
- Claimed
A draft of C3 asserted availableFunds + escrowedFunds ≤ account balance, producing a 497,844,875,522 drop shortfall against Flare.
- Actually
- There was no shortfall. The arithmetic double-counted every escrow.
- Mechanism
- XRPL escrow REMOVES XRP from account_data.Balance and holds it in Escrow ledger objects. Adding Flare's escrowed figure to a balance that already excludes it counts the same XRP twice.
- Caught by
- Checking the live XRPL account objects before publishing the exception.
- Now prevented by
- A regression test asserts the exact bad arithmetic still produces 497,844,875,522 and that the current control reports CLEAN on the same data.
E-005
CAUGHT BEFORE PUBLICATION
2026-08-05
found by re-reading the evidence
- Claimed
The status badge reported a verdict as fresh.
- Actually
- The badge could never go stale. Its computed age was −21 hours, because freshness was derived from the day under test rather than when the report ran.
- Mechanism
- CV-1 recorded a period, not a timestamp. Anchoring the period to end-of-day dated every report into the future, and a negative age passed the freshness budget trivially.
- Caught by
- Reading the emitted JSON instead of trusting that the badge rendered.
- Now prevented by
- CV-1 records generatedAt, and a future-dated report renders UNKNOWN rather than vouching indefinitely.
E-006
CAUGHT BEFORE PUBLICATION
2026-08-05
found by a test written for it
- Claimed
The red run forked Coston2 and reconciled it against the Coston2 XRPL testnet vault.
- Actually
- It would have reconciled a Coston2 fork against the REAL XRP Ledger — two unrelated systems, compared with complete confidence. The controls would have 'fired' and proven nothing.
- Mechanism
- xrpl.ts chose its XRPL cluster at module load. ESM hoists imports above the importing module's statements, so the red run setting NETWORK at the top of its own file ran too late.
- Caught by
- Grading the subjects, which forced the question of what evidence V3 actually rests on. The hoisting behaviour was then reproduced in a five-line test rather than assumed.
- Now prevented by
- Endpoints resolve per call, so the caller's network selection is honoured.
E-007
CAUGHT BEFORE PUBLICATION
2026-08-05
found by a test written for it
- Claimed
Evidence packs were anchored to a Flare block, an XRPL ledger and a cross-chain skew of 0 seconds.
- Actually
- None of the three anchors described the state in the pack. The block was read AFTER the contract reads, so it named a later height. The XRPL ledger was the newest of the last 200 transactions, not the ledger the balance and escrows were read at. The skew was hardcoded, never measured.
- Mechanism
- Each anchor was taken from whatever value was conveniently to hand rather than from the read itself. A replayer at the stated Flare block could legitimately compute a different opinion, and the stated XRPL ledger was simply unrelated to the balances beside it.
- Caught by
- Writing a regression test that asserted the anchor equals the height the state was read at. The first version of that test failed twice, and the second failure exposed a deeper form of the same bug: the recorded XRPL evidence did not carry its own ledger, so a replayer could not confirm the anchor from the pack at all.
- Now prevented by
- Reads are pinned to a block number obtained first; accountLedgerState returns the ledger and close time it used; skew is computed from them and reports -1 when it cannot be established. The pack is self-describing, and tests assert the anchor matches the recorded evidence.
E-008
PUBLISHED, THEN WITHDRAWN
2026-08-05
found by re-reading the evidence
- Claimed
223 TEE machines are registered, of which 95% carry one shared code hash — published under a freshness badge reporting the scan as current.
- Actually
- The registry held 250 machines. The published figure was 12% wrong and had been for roughly twenty-nine hours, on the headline number of an entire register.
- Mechanism
- The badge measures the AGE of a scan, and age was silently doing duty for correctness. Nothing ever compared the committed snapshot against the chain, so a scan could be hours old and already wrong while reporting itself fresh. The ratios the register actually concludes from were barely affected, which is what made it survive: the page looked right.
- Caught by
- Re-reading the live registry during an audit and comparing it by hand to the number on the page. No control caught this, and the tests were complicit rather than silent — they asserted the count equalled 223 while reading the same stale file the page did, so the whole suite agreed with the error. A test that reads the artefact under test cannot detect that the artefact is stale.
- Now prevented by
- checkDrift() reads the live registry total and classifies the gap CURRENT, IMMATERIAL, MATERIAL or UNKNOWN against a 2% materiality threshold; driftIsPublishable() blocks the publish on MATERIAL, and on UNKNOWN, because failing to check is not evidence nothing moved. A regression test pins 223-against-250 as MATERIAL. It is exposed as `pnpm --filter @therecord/reprod drift`, so the check is a command a stranger can run against us rather than a promise we make about ourselves.
The patternThree of these are the same error wearing different clothes:
a comparison between two numbers that were never defined to be equal, or that could never disagree.
That is the failure mode of assurance work, and it is invisible from the inside — every one of them
produced confident, well-formatted output that happened to be meaningless.
Only a deliberate fault distinguishes a control that holds from one that cannot fail. That is why
the red run exists, why it runs in CI, and why V3 on the
verifiability scale requires it.