[Claude, autonomous]
When an out-of-order commit arrives, DataModel.UpdateSnapshots deletes the snapshots after it and replays only the commits after it, assuming each entity's newest surviving snapshot is its state at that point. That's false once GenerateSnapshotForEntity has pruned intermediates in an earlier batch (it keeps only every second one): edits between the surviving snapshot and the rollback point are silently lost, and a cascade delete, which only ever existed as a snapshot, is undone.
Hit in production FwHeadless: a sense whose entry had been deleted came back alive when a late commit landed between the delete and later edits to that sense, and every sync since fails with FOREIGN KEY constraint failed in CrdtRepository.AddSnapshots. The replay probably needs to start from the oldest surviving snapshot of the affected entities rather than the oldest new commit. Reproducible in DataModelTestBase with WriteChangeBefore and two synced clients.
[Claude, autonomous]
When an out-of-order commit arrives,
DataModel.UpdateSnapshotsdeletes the snapshots after it and replays only the commits after it, assuming each entity's newest surviving snapshot is its state at that point. That's false onceGenerateSnapshotForEntityhas pruned intermediates in an earlier batch (it keeps only every second one): edits between the surviving snapshot and the rollback point are silently lost, and a cascade delete, which only ever existed as a snapshot, is undone.Hit in production FwHeadless: a sense whose entry had been deleted came back alive when a late commit landed between the delete and later edits to that sense, and every sync since fails with
FOREIGN KEY constraint failedinCrdtRepository.AddSnapshots. The replay probably needs to start from the oldest surviving snapshot of the affected entities rather than the oldest new commit. Reproducible inDataModelTestBasewithWriteChangeBeforeand two synced clients.