Files
buzz/mobile/lib
kenny lopez 758a050787 fix(dm-visibility): harden NIP-DV hidden-DM resurface path against reviewer-flagged defects
Address Wess/Jude review defects on the hidden-DM visibility/resurface
path. Each is an in-scope correctness fix to the mechanism this PR builds;
none change product intent or UI. The #6769 durable cross-process
convergence invariant remains an intentional out-of-scope follow-up (bug
#6316 stays open, tracked by #6769).

A. Clock-skew fence (buzz-db/event.rs): received_at was assigned by the
   relay process clock (Utc::now()) while hide_dm's hidden_at uses the DB
   clock (NOW()), so the causal resurface fence compared two clocks. Insert
   now writes NOW() and RETURNs the value, sourcing both sides from the one
   database clock. Adds a PG-gated regression bracketing received_at between
   two DB NOW() reads.

B. Mobile replay loop (dm_visibility.dart): the limit:1 snapshot replay
   could fire before subscribe() resolved, kicking refresh() -> version bump
   -> resubscribe -> identical replay, unbounded for any user with a stored
   snapshot. Dedup on snapshot event id (reset on relay/identity change and
   clear). Adds a regression.

C. Huddle invites never resurfaced (buzz-core/kind.rs): KIND_HUDDLE_STARTED
   is rendered as visible content and treated as a notifiable DM invite but
   was absent from is_human_visible_message_kind, so it never resurfaced a
   hidden DM. Added to the trigger set; other huddle lifecycle kinds stay
   excluded. Test updated.

D. Fail-open snapshot read (desktop fetch.rs, mobile channel_directory.dart):
   a transient kind:30622 read failure was treated as 'nothing hidden',
   re-exposing every hidden DM until the next good refresh. Now fails closed
   by propagating the error so the caller preserves the last rendered list.
   Adds a mobile regression.

E. Desktop in-flight invalidation race (useMembershipNotifications.ts):
   direct channelsQueryKey invalidation could be silently undone by an
   in-flight get_channels, dropping the resurface signal. Routed through the
   idle-aware trailing debounce (refreshChannelsWhenIdle) as
   useLiveChannelUpdates does, with cleanup-time cancel(). Test updated plus
   an in-flight re-arm regression.

Verified locally at this tree: cargo fmt --check, clippy (buzz-core,
buzz-db), file-size-check; buzz-core kind tests, buzz-db event tests
(incl. PG-gated), buzz-relay resurface integration tests; desktop
node --test useMembershipNotifications; mobile flutter analyze + full
channels_provider_test suite. All green.

Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <klopez4212@gmail.com>
2026-08-25 20:13:54 +01:00
..