Follow-up carved out of #6713 (DM resurfacing). The retryable-publish slice landed there; this issue tracks the durable, cross-process convergence work Jude's review flagged as remaining.
Problem
Accepted human-visible DM activity resurfaces recipient visibility (unhide_dm_recipients) and republishes a kind:30622 snapshot on a best-effort, post-commit basis:
- Ordinary ingest commits the message first, then resurfaces/publishes and suppresses failure while still accepting the message (
crates/buzz-relay/src/handlers/ingest.rs:3157-3244).
- Workflow send has the same post-commit, best-effort shape (
crates/buzz-relay/src/workflow_sink.rs:390-478).
- Recovery today relies on an external actor replaying the exact event; there is no persisted pending-viewer/generation/outbox or background reconciliation guaranteeing convergence after an acknowledged send.
Publication is also an unfenced read/build/replace sequence (crates/buzz-relay/src/handlers/side_effects.rs:3394-3480): a publisher paused after reading hidden {X} can resume after another process publishes {} and then write stale {X} with a newer replacement timestamp. An in-process mutex does not fix this across relay processes.
Proposed work
- Durably couple accepted DM activity to a per-viewer visibility generation / outbox (or an equivalently proven DB-backed invariant).
- Reconcile automatically (startup + background) until the published snapshot head reaches the target generation.
- Fence stale publishers across relay processes so an older canonical read cannot overwrite a newer published state.
Acceptance / tests
- Deterministic accepted → publication-failure → restart → automatic-recovery test.
- Deterministic paused-stale-publisher → newer-publication → resume test.
Ref: Jude review at head d28c8b0f4, item #1. #6713
Follow-up carved out of #6713 (DM resurfacing). The retryable-publish slice landed there; this issue tracks the durable, cross-process convergence work Jude's review flagged as remaining.
Problem
Accepted human-visible DM activity resurfaces recipient visibility (
unhide_dm_recipients) and republishes a kind:30622 snapshot on a best-effort, post-commit basis:crates/buzz-relay/src/handlers/ingest.rs:3157-3244).crates/buzz-relay/src/workflow_sink.rs:390-478).Publication is also an unfenced read/build/replace sequence (
crates/buzz-relay/src/handlers/side_effects.rs:3394-3480): a publisher paused after reading hidden{X}can resume after another process publishes{}and then write stale{X}with a newer replacement timestamp. An in-process mutex does not fix this across relay processes.Proposed work
Acceptance / tests
Ref: Jude review at head
d28c8b0f4, item #1. #6713