Base revision: cfb03f201 (main after #2032 and #2033).
This record closes the four items that the round 3 record and the ready-callback truncate record left open. One is a bug fix. The cache delete stays, with witnesses. #2030 on main made the other two unnecessary.
Gap. The round 3 record called RB2, a mutant that keeps stale automatic metadata writes through a rebuild, equivalent within legal histories. Reaching it needed a canceled earlier transaction, which the grammar did not generate.
Correction, 2026-10-06. The outcome below is wrong. A transaction begun inside an open one can still commit first, and the rebuild then reclassifies the open one's inserts. main loses last-write-wins there. See 2026-10-06-nested-begin-metadata-rebuild.md.
Outcome: made unnecessary by #2030. A first revision of this branch added a canceled lane to the metadata composition oracle. An earlier held transaction deleted key 1, the open transaction wrote against that projection, and the earlier one was canceled. The lane found that main lost an explicit metadata.row.set when the canceled delete turned the open insert into an idempotent re-insert, and the revision fixed the rebuild.
PR #2030 then allowed only the open last sync transaction to be canceled. Aborting an accepted transaction's signal now has no effect, so a rebuild can no longer reclassify an open write. The canceled lane's history no longer exists, and RB2 is equivalent again. This branch drops the lane and the rebuild change and keeps main's rebuild.
Gap. During sync entry, ops.markReady() deferred a ready callback's error until the sync function returned. A truncate committed inside the sync function threw the same error from commit(). The rest of the sync function never ran, and the Collection moved to error.
Witness. The sync reentrancy oracle runs a throwing onFirstReady callback with markReady, a truncate commit, and a truncate commit followed by markReady. The sync function must finish, the Collection must stay ready with its rows, and the error must surface when sync entry returns. The two truncate cases fail on main.
Repair. The lifecycle holds ready-effect failures while a sync function runs, whichever path makes the Collection ready, and sync entry reports the first one when it returns. This replaces markReadyDuringSyncStart and the per-entry flag that chose between two markReady calls.
Finding. The round 3 record reported 422 reads that returned a cached enriched row whose fields differed from the stored row. Those came from comparing NaN with !==. With Object.is, instrumentation found no such read across the @tanstack/db suite, with or without the delete.
Outcome: kept. A first revision removed the delete. A high-effort review then showed that the suite runs only in development builds, where the reused-row check rejects an in-place change without previousValue. In a production build that write is accepted and publishes no update, so only the commit's delete keeps reads fresh. A deferred publication also enriches late. New cases in virtual-props-cache.test.ts stub production mode for that write and read inside a deferred publication. Both fail without the delete, so it stays.
Outcome: removed by #2030. A first revision of this branch removed the set, and review then described a history where it might still matter, so the revision restored it. #2030 drops optimistic state at settlement and removed the set on main.
A high-effort review found nine items.
The simplifier pass suggested one helper for the explicit metadata write, which metadata.row.set and metadata.row.delete now share.