Gap
CouchSync.removeFile in src/couch/couch-sync.ts is fire-once: unlike pushFileLive (which self-enqueues into the pending queue on failure), a tombstone that fails (network down, 401 mid-outage) is silently lost. pushAll/syncNow only reconcile existing files, so the couch doc survives, the deletion never propagates to other devices, and the deleted note can resurrect on a later pull.
Fix shipped upstream (port candidate)
@agentage/memory-core@0.3.1 (agentage/memory-core#17) closed this in its port of these modules:
CouchSyncState gains deletions?: string[]; failed removeFile enqueues; flushPending retries both kinds; old-shape persisted state loads fine.
- Deletion reconciliation in
pushAll: rev cache is the oracle - path in the rev cache but absent on disk = local deletion -> tombstone + drop rev; no rev-cache entry = new remote content (pull writes it).
- 409 policy: DELETE 409 or advanced content-rev = conflict -> drop the pending deletion + rev, let the next pull re-deliver the newer remote version (edit wins over stale delete; never force-delete with the fresh rev).
- Bonus:
syncNow() now catches pull errors like tick() (returns {pushed, pulled, error?}).
Either port the diff or switch the plugin to consume the shared module from @agentage/memory-core (it now exports CouchSync behind injected FileStore/persistence/fetch seams designed to fit plugin adapters).
Tests to carry over: delete durability (fail then land), phantom-delete guard on pull-applied deletes, tombstone-409 restore, old-state-shape load.
Gap
CouchSync.removeFileinsrc/couch/couch-sync.tsis fire-once: unlikepushFileLive(which self-enqueues into the pending queue on failure), a tombstone that fails (network down, 401 mid-outage) is silently lost.pushAll/syncNowonly reconcile existing files, so the couch doc survives, the deletion never propagates to other devices, and the deleted note can resurrect on a later pull.Fix shipped upstream (port candidate)
@agentage/memory-core@0.3.1(agentage/memory-core#17) closed this in its port of these modules:CouchSyncStategainsdeletions?: string[]; failedremoveFileenqueues;flushPendingretries both kinds; old-shape persisted state loads fine.pushAll: rev cache is the oracle - path in the rev cache but absent on disk = local deletion -> tombstone + drop rev; no rev-cache entry = new remote content (pull writes it).syncNow()now catches pull errors liketick()(returns{pushed, pulled, error?}).Either port the diff or switch the plugin to consume the shared module from
@agentage/memory-core(it now exportsCouchSyncbehind injectedFileStore/persistence/fetch seams designed to fit plugin adapters).Tests to carry over: delete durability (fail then land), phantom-delete guard on pull-applied deletes, tombstone-409 restore, old-state-shape load.