All packsOffline Sync EngineSolve
crdt tombstone deleted row resurrected by edit
An edit to another field shouldn't undelete a row
If a later edit to any column of a deleted row silently undoes the delete, every offline edit made against stale data becomes a potential zombie record.
What goes wrong
In a system without an explicit delete-wins rule, a device that queued an offline edit to some field of a row -- unaware the row was deleted elsewhere in the meantime -- can have that edit sync in and effectively resurrect the row, because nothing about writing to one column inherently respects a delete recorded on a different column. A record the user explicitly deleted comes back, seeded from whatever stale offline edit happened to arrive after the delete.
Why agents get it wrong
Per-field conflict resolution (each column merges independently, which is the pack's whole point for concurrent edits to different fields) makes "the delete is just another cell" a very natural, consistent-sounding design -- until you ask what happens when a different cell on the same row gets written after the delete cell, which requires deliberately deciding that reads should treat _deleted specially rather than symmetrically with every other column.
What Offline Sync Engine pre-decides
The pack encodes delete as an ordinary cell (_deleted = true) that replicates and resolves by HLC like anything else, but readers (getRow, listRows) explicitly drop any row whose _deleted cell reads true, regardless of what any other column says. Undelete requires an explicit _deleted = false write with a later HLC -- there's no implicit resurrection path, and the pack documents the exact boundary of this guarantee: it holds within the 90-day tombstone retention window, not indefinitely.
Source: ARCHITECTURE.md 'Deletes and tombstones (decided)'