GossipView
The live, self-healing partial view of the gossip overlay for one peer.
GossipView turns a roster StateFlow into a continuously-maintained active-neighbour set (the ~k peers this node gossips deltas with and GCs against) plus an ordered spares standby list. It is the "membership/view manager" of docs/gossip-mesh-design.md Phase 2 — the runtime counterpart of the pure partialView selection function.
Derivation. On every roster change the view is reconciled against the topology policy's target view — for the default RandomKRegular, a seeded random k-out sample (k = recommendedActiveViewSize(N)) — after a per-peer jitter drawn from jitter so peers don't recompute in lockstep and storm the overlay. The policy owns selection (which peers, and any randomness); this manager owns stability: recompute is churn-minimising — healthy active neighbours are retained across recomputes and only freed slots are filled (from spares first, then fresh policy picks) — so a single join/leave does not reshuffle the whole overlay.
Liveness. One HeartbeatPartitionDetector runs per active neighbour over a shared rawIncoming fan-out (the SeamRoom-style composer the design calls for; see PerPeerSeam). When a detector reports PartitionEvent.PeerUnresponsive or PartitionEvent.PeerLost the edge is treated as down: the neighbour is dropped, the next spare is promoted immediately (reactive healing), and the view is reconciled. A failed peer is excluded from re-selection until it leaves the roster; transient blips are healed by anti-entropy (Phase 1), not by this manager re-admitting the peer (a documented v1 simplification — see gossip-mesh-design.md).
Determinism (required). All scheduling runs on the start scope's dispatcher; all randomness draws from the injected random and the topology's own seeded RNG (the same instance, with the default policy); the clock is the injected clock. State is confined to a single command-processing coroutine (an actor over commands) so there are no locks and event ordering is deterministic. Tests drive virtual time with StandardTestDispatcher + bounded advanceTimeBy/runCurrent and never advanceUntilIdle (the heartbeat timers re-arm forever).
Parameters
this peer's id; never selected into the view.
the base multi-peer seam; per-peer detectors send ping/pong through it.
the live full-membership set (includes selfId); the view's source of truth.
a fan-out of the base seam's inbound frames. The owner (e.g. GossipSeam) is the single collector of seam.incoming and re-publishes each Swatch here, so the per-peer detectors can subscribe without contending for the single-consumer seam.incoming channel (ADR-034).
a seeded RNG, seeded per-peer by the caller so peers choose independently. Drives the recompute jitter; with the default topology the same instance also seeds neighbour selection.
injected time source for the per-peer detectors; never the wall clock.
the overlay shape — which peers fill the active view. Owns all selection randomness; defaults to a RandomKRegular seeded from random.