mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
Replace the per-need-event fetch (which pulled the whole need set just to read metadata — an O(db) regression on large syncs) with a second reconcile pass over the residual, per the "settle, then diff, then explain what didn't converge" idea. Pass 1 is the plain content sync again (drain needs, publish haves) — zero deletion overhead. Pass 2+ re-reconciles; the leftover diff is exactly the deletion mismatches, and only that (tiny) set is fetched: - residual need (relay has it, we still lack it after --down) = we deleted it → publish our covering deletion up so the relay drops it; - residual have (we have it, relay still lacks it after --up) = the relay deleted it → pull the relay's covering kind-5 down and apply locally (vanish is NOT auto-applied on pull — account-wide blast radius). Loops until a round resolves nothing (converges + self-verifies). So `amy sync` makes the relay honor our deletions; `--up` makes us honor the relay's; `--up --down` converges both ways. Cost is one cheap reconcile + the residual regardless of database size — the large-DB bottleneck is gone by construction, not by heuristics. quartz: deletionsCovering is now source-agnostic (takes a query lambda) so the same coverage rule runs against the local store (up) or the relay (down); the IEventStore overload is the local convenience. Tests: DeletionSyncTest gains the down-direction end-to-end (relay deleted → local removes) alongside the up-direction and the per-form unit cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgL1WTV4Hkp2uuXcUHCHGt