acpmux: a peer daemon's connection hears and lists none of this host's peers

Merged
TE
9d ago
+151-6

Fix-forward for #26823 (base restore). The review after the merge returned BLOCK on one finding: _acpmux/peer_state_changed went to every _acpmux/watch connection, Origin::Peer included. A peer handshake turns on _acpmux/watch, so every daemon peered with this one heard the name, link state and connection error of every one of this host's peers.

Leo's words, which this feature serves: "you can just not choose a project ... you just get a little green dot ... as if you were working on your own computer, but now it's remote."

Change

  • The notes skip peer connections. server/fanout.rs sends a peer-state note only to a connection that watches and is not Origin::Peer. This covers both the live note and the snapshot resent to a watcher that fell behind. The unix socket, the local app and Web watchers (the dashboard) still get them.
  • The peers lists come back empty for a peer. _acpmux/peers answered a peer-origin caller with the full list (requests.rs returned hub.peers() to anyone), and so did the peers field of _acpmux/status and the peer_* replies. Now remote_guard::after empties every reply's peers array for Origin::Peer (redact::hide_peers_from_peer). This matches _acpmux/peer_status, which already answered a peer with this machine's row only. Nothing on a peer reads these lists: the daemon's peer link never calls _acpmux/peers or reads status.peers, and the CLI callers all talk to their own daemon over the unix socket.

Test: fails before, passes after

tests/peer_state_origin.rs a_peer_connection_hears_and_lists_none_of_this_hosts_peers sets up one hub with a unix-socket watcher and an Origin::Peer watcher, then checks:

  • a live note: the local watcher hears it, the peer watcher gets nothing;
  • 600 changes on a one-thread runtime, so both watchers lag: the local one gets the snapshot and the rest, the peer one gets nothing;
  • _acpmux/peers and _acpmux/status: they list gone on the unix socket and nothing to the peer.

(results being added)

Capture

No capture: no UI change. This is daemon fan-out and reply redaction only.

Risk

Low. The change only removes data from Origin::Peer connections: the peer-state notes and the peers lists. One thing still reaches a peer: a session list may still name sessions this host mirrors from its peers. That was already the case before #26823 and is outside this fix.

Agent session: agent session

šŸ¤– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes _acpmux fan-out so a peer daemon's connection no longer hears about or lists this host's other peers. Peer-state notes were fanning out to every _acpmux/watch connection, including Origin::Peer, and _acpmux/peers plus the peers fields in _acpmux/status and peer_* replies answered peer callers with this host's full peer list.

  • Peer-state notes — the live note and the snapshot a lagging watcher gets — now only go to watchers that are not Origin::Peer; the unix socket, local app, and Web watchers keep receiving them.
  • Peer-origin callers get an empty peers array from _acpmux/peers, _acpmux/status, and the peer_* replies, matching how _acpmux/peer_status already answers with this machine's row only.
  • Adds a test covering both live and lagging note fan-out and the empty peer lists.

Risk is low: the change only removes peer-state notes and peer rows from peer connections.