Sync / foldkit-durable
Retention
Two kinds of row grow for the life of the database and are never collected:
one identity row per distinct opId, kept after compaction so an old retry is
recognized, and one record per effect key. Growth follows the number of distinct
operations and effects, not only retained payload size.
Compaction empties payloads but SQLite keeps their pages. vacuum() rebuilds
the file and checkpoints its write-ahead log; it holds the database while it
runs, so schedule it as maintenance. A reader on another connection can block
the log truncation, in which case vacuum fails with JournalError and a later
run finishes the job.
If you rotate or recreate the database, an operation whose identity row is gone is indistinguishable from new work. Reject work older than the retained window instead of applying it as new: keep a per-document watermark, or refuse an operation whose base cursor predates the floor.