Files
stack/packages/mosaic/framework/guides/FLEET-COMMS.md
T
code-infra-01 69efad2f9a
ci/woodpecker/pr/ci Pipeline failed
fix(#1262): adoption follow-ups - enumeration exclusion, SEND-honoring verdict suite, retire rc=2-is-normal guide text
- F5 (rev-code-02 blocker): sign test-send-message-glyph-agnostic.sh into
  test-enumeration-exclusions.txt beside its tmux siblings; the CI image
  ships no tmux, so the suite stays manually run (#1017 burndown).
- Adoption finding: the verdict suite hard-coded SEND to its sibling and
  ignored the SEND env var, so a red-first run against the shipping blob
  silently measured the patched copy instead (measured: shipping run
  printed PASS=4; with SEND honored it is PASS=3 FAIL=1, fixture 2 red,
  matching the recorded review numbers). SEND is now honored with the
  sibling as default, same contract as the glyph suite.
- F6/D19: framework FLEET-COMMS.md claimed 'rc=2 is the normal result
  when the target is an idle pi seat'. Post-fix rc=0 is normal for idle
  and busy pi seats; rc=2 on a healthy seat is a real report. Never-retry
  advice kept, softened to 'may be in the pane' for the unconfirmed arm.

Live verification on sb-it-1-dt (tmux 3.7b, pi glm-5.3 low, scratch
session): idle pi - shipping rc=2 'may be UNDELIVERED' while the seat
consumed the message and answered; patched rc=0 delivered, answered.
Busy pi mid-turn - shipping rc=2 while the pane accepted both messages
as steering input ('Steering: ...', 'Alt+Up to edit all queued
messages'); patched rc=0 delivered, both consumed and acted on after the
turn. Both D11 signatures: verdict now matches reality.
2026-08-20 11:31:44 -05:00

3.9 KiB

Fleet Comms Guide

How one seat reaches another on a host. The mechanism is the framework's; the sessions and sockets are per-host, so measure yours rather than trusting an example.

mosaic <runtime> would normally inject the addressing block from the roster. Where the composer is unavailable, or where the roster is stale, this guide is the substitute.

Measure the fleet; do not trust the roster

fleet/roster.yaml is a declaration of intent, not an observation. It routinely names a socket that was never created, lists seats that are not running, and omits seats that are — this was all three have been observed true at once on a live host. Find out what is actually up before addressing anyone:

tmux list-sessions
tmux list-panes -a -F '#{session_name}  #{pane_current_command}  #{pane_current_path}'

The pane command tells you the runtime. A pane showing bash is an idle shell with no agent attached — a send there lands in a shell prompt and is not read by anyone.

Use the default socket. Do not pass -L mosaic-fleet on the strength of the roster.

Sending

~/.config/mosaic/tools/tmux/agent-send.sh -s <dst_session> -C <class> -m "<message>"

-s also accepts session:window.pane. -f <file> sends a file body; stdin works too.

Classes

-C takes exactly one of these. Anything else exits 3.

Class Use for
terminal-log log only; never needs the agent's attention
actionable a decision, blocker, gate, or question needing an answer
human relayed from a human operator
reaction an ack or acknowledgement token
digest machine wake, coalescible

An absent class is treated as actionable by consumers, which is the fail-safe direction. Prefer naming it anyway.

Addressing preamble

The wire format is [<src> -> <dst> class=<class>] <body>. Flip it when you reply — the tool sends, it does not auto-reply.

Exit codes

rc Meaning
0 delivered or queued
1 target session not found
2 submission unconfirmed: draft still on the input line, or no positive evidence of submission
3 usage error (bad class, missing -s)

Never retry on rc=2. The message may be in the target pane, and a retry can double-send it. Confirm instead:

tmux capture-pane -p -t <session>:0.0 | tail -20

rc=0 is the normal result for both idle and busy pi seats (submission confirmed by draft transition, not by prompt glyph). rc=2 on a healthy seat is exceptional — treat it as a real report and investigate the pane.

Durable comms

tmux delivery is host-local and does not survive a pane. Anything that must outlive the session goes through the estate's durable comms protocol — a committed comms/ tree in an estate repo, with its own README. Use it for cross-host messages, verdicts, and anything a later session needs to find.

Handing work across seats

  1. A verdict handed to the requesting seat is a legitimate delivery path, and the required one for anything pr-review.sh would otherwise post (see guides/CODE-REVIEW.md).
  2. Address the seat, not the runtime. A seat name is a session name; whether it runs claude, pi or codex is not the sender's business.
  3. Say what you measured, not just what you concluded — the receiving seat cannot see your terminal.