Skip to content

v0.9.0-rc.29

Choose a tag to compare

@github-actions github-actions released this 30 May 13:28
· 46 commits to main since this release
v0.9.0-rc.29
62d9e8c

subscribe_to_observer_changes now fires on tombstone-driven deletes — closes the documented "fires for ALL document changes" contract on the CDC channel. Single landed PR (peat-mesh#203) closes peat-mesh#202. Pre-rc.29 AutomergeStore::delete silently removed from disk + cache without firing any of the three broadcast channels, so a CDC consumer subscribed to the documented channel saw inserts and updates from any peer but never saw deletes from any peer. Blocked the operator-visible peat observe-with-peat delete cross-CLI flow (peat-node ADR-001 Open Question §7).

Fixed

  • AutomergeStore::delete fires the same broadcast pipeline as put (peat-mesh#203, closes peat-mesh#202). delete(&self, key) now routes through a new delete_inner(key, notify, origin) private path that fires observer_tx (CDC) + change_tx (local sync-out trigger) + gossip_tx (origin-tagged), mirroring the existing put / put_with_origin channel-gating matrix exactly. The contract repair is observable: a CDC consumer subscribed to subscribe_to_observer_changes now sees Ok(None) from store.get(key) on the event when the delete originated from any source (local or remote-via-tombstone), making the "Some → insert/update, None → delete" detection pattern (peat-cli's cli/observe.rs:94-102 shape) work end-to-end.

Added

  • AutomergeStore::delete_with_origin(&self, key, origin: ChangeOrigin) (peat-mesh#203). Mirrors put_with_origin: ChangeOrigin::Local fires change_tx (sync-out trigger); ChangeOrigin::Remote(peer) suppresses it per the peat-mesh#115 ping-pong invariant and tags gossip_tx with the peer attribution for transitive-gossip drivers to skip the source. observer_tx always fires.

Changed

  • AutomergeSyncCoordinator::apply_tombstone now routes the post-tombstone document removal through delete_with_origin(.., Remote(peer)) instead of the silent delete() call. Same observable behaviour for change_tx (suppressed per peat-mesh#115); new observable behaviour for observer_tx + gossip_tx(Remote(peer)) — CDC consumers see remote-driven deletes; transitive-gossip pushers see the peer attribution.
  • AutomergeStore::subscribe_to_observer_changes doc-comment updated to reflect the post-#202 contract: explicitly lists tombstone-driven deletes among the events the channel fires, and adds the subscriber-side detection pattern (store.get returning Ok(Some(_)) → insert/update; Ok(None) → delete) inline. The contrast with subscribe_to_changes shifts from "local puts vs. all changes" to "local writes (puts and deletes) vs. all writes."
  • AutomergeStore::ttl_manager TTL eviction sites now carry inline comments naming peat-mesh#202: each store.delete call in the synchronous eviction path and the background cleanup task wakes change_tx per the rc.29 contract, so a TTL eviction wakes the sync-coordinator's local-only outbound pusher as a side-effect (the document is gone by the time the pusher runs — wakeup, not propagation). Comments give future readers an in-place diagnostic hook if they trace a steady-state wakeup rate back to TTL expiry cadence.

Added — regression tests

  • tests/observer_fires_on_delete.rs (peat-mesh#203): 4 integration pins through the public surface — delete_fires_observer_tx, delete_fires_local_change_observer_and_gossip_channels, delete_with_remote_origin_suppresses_change_tx_and_tags_gossip, delete_of_missing_key_still_fires_observer.
  • src/storage/automerge_sync.rs::tests::persistent_stream_wire_format_peat_mesh_175::tombstone_receive_fires_observer_tx: dispatch-tier in-tree pin. Seeds a doc on the receiver's store, drives a real Tombstone v2 frame through handle_incoming_sync_stream, asserts (a) the doc is removed AND (b) the observer channel wakes with the doc key. Catches a future regression where apply_tombstone reverts to the silent delete() call or bypasses the observer broadcast some other way.