Under a long live-sync history, writes stalled behind "database is locked"
refusals, durable leases lapsed, and the App stopped answering for tens of
seconds at a time.
- import_jobs is bounded: finished (completed/cancelled) sync jobs are
pruned to the newest 20 per (user, source), with their issues and skip
counts, in bounded batches at startup and every 10 minutes. History jobs
and every unfinished job are kept.
- Job lookups are SQL (find_jobs / latest_job) instead of reading the whole
table, served by new indexes in schema migration 63. GET
/api/v1/import-jobs keeps its shape and order.
- The durable write queue runs claim, settle and maintenance in its own pool
and lease renewal in a dedicated one, so bulk work cannot starve a lease.
The single writer and its line are unchanged.
- abandon, resume, enqueue, pause, cancel, shutdown and startup resume make
their database calls off the loop; the file watcher resolves changed
paths off the loop; revoke reads and writes its grant off the loop.
- The WAL cadence checkpoint is requested from the write path and run by one
checkpointer thread instead of inline on the writing thread.
- The durable drain is supervised: an unexpected exit is reported with its
stack and the drain restarts with capped backoff under a new lease owner.
memory-processing and memhub status show write_drain and
write_drain_error. Contained per-job failures are reported with stacks.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>