docs(comms): T3 threads as the temporary development channel beside tmux
Jason, 2026-09-26: while Mosaic Stack development runs in T3, development agents message each other through T3 threads with the t3 MCP tools, until Mosaic Stack has its own internal comms. ms-communications now picks the transport by where the recipient runs, carries the T3 header and reply rules, and counts a returned turnId as the delivery receipt. docs/guides/T3-AGENT-COMMS.md is adapted to this repository: status, thread lookup by agent-name title, replies with wait off, and record locations; references to guides absent here are replaced. Suites green before commit: config 24, task 90, foundation 43, conductor 17, release 14, auth 15, discord 63. unslop-check clean on both files. Reviewed by Sage (T3 thread 1ef1e4f8). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -6,28 +6,66 @@ disable-model-invocation: false
|
||||
|
||||
# ms-communications
|
||||
|
||||
Agent-to-agent messaging: one channel, one addressing grammar, honest triage.
|
||||
Messages are transport. The durable record lives in run records, issues, and
|
||||
SESSIONS.md, never in a pane that scrolls away.
|
||||
Agent-to-agent messaging: one send path per transport, a required sender
|
||||
header, honest triage. Messages are transport. The durable record lives in run
|
||||
records, issues, and SESSIONS.md, never in a pane that scrolls away or a
|
||||
thread that lives only in T3's database.
|
||||
|
||||
## Channel
|
||||
|
||||
Pick the transport by where the recipient runs. Each has one send path.
|
||||
|
||||
| Recipient | Send path | Guide |
|
||||
|---|---|---|
|
||||
| A T3 Code thread (Mosaic development agents while development runs in T3) | `t3_send_message` / `t3_create_thread` from the `t3` MCP server | `docs/guides/T3-AGENT-COMMS.md` |
|
||||
| A tmux seat (fleet seats, pane-hosted agents) | `tools/tmux/agent-send.sh` | `tools/tmux/README.md` |
|
||||
|
||||
- T3 threads are a temporary channel. Jason, 2026-09-26: Mosaic Stack
|
||||
development agents talk through T3 agent comms for now; Mosaic Stack will
|
||||
replace it with its own internal comms. Use the T3 tools as documented and
|
||||
do not design Mosaic features against them.
|
||||
- Harness-native cross-session messaging (Claude Code's SendMessage and
|
||||
ListAgents, or any equivalent built into a harness) is not a Mosaic
|
||||
channel. Jason, 2026-09-12: Mosaic Stack develops and uses its own
|
||||
cross-harness comms; a harness feature may be used only as a stated
|
||||
stopgap when the tmux path is unreachable, and never designed against.
|
||||
- `tools/tmux/agent-send.sh` is the only send path. It prepends the preamble,
|
||||
submits reliably (bracketed paste, Enter flush, draft detection), and ships
|
||||
itself over ssh for remote targets. Never raw `tmux send-keys`; that is how
|
||||
messages die as unsubmitted drafts.
|
||||
- Your own session output is not a send path either. A reply composed as
|
||||
stopgap when both paths above are unreachable, and never designed against.
|
||||
The `t3` MCP server is not harness-native. It reaches Claude, Codex, and
|
||||
OpenCode threads alike.
|
||||
- Your own session output is not a send path. A reply composed as
|
||||
assistant prose, however well formatted, delivers nothing to the
|
||||
recipient's pane; a hand-written preamble in prose is decoration, not
|
||||
delivery. A reply exists only once `agent-send.sh` has run, and its exit
|
||||
code is the delivery receipt. No rc, no send.
|
||||
recipient; a hand-written header in prose is decoration, not delivery.
|
||||
A reply exists only once the send tool has run and returned its receipt:
|
||||
a `turnId` from the T3 tools, exit code 0 from `agent-send.sh`. No
|
||||
receipt, no send.
|
||||
|
||||
### T3 threads
|
||||
|
||||
Full mechanics, including setup checks, thread lookup, and upkeep, are in
|
||||
`docs/guides/T3-AGENT-COMMS.md`. Read it before your first T3 send. The
|
||||
parts that carry the protocol:
|
||||
|
||||
```
|
||||
[from: <sender-role> (<sender-thread-id>) -> to: <recipient-role> (<recipient-thread-id>)]
|
||||
[from: <sender-role> (<id>) -> to: <recipient-role> (<id>) class=<CLASS>] # with triage class
|
||||
```
|
||||
|
||||
- You write the header yourself as the first line of the prompt. T3 delivers
|
||||
it as a user prompt, so the header is the only sign an agent sent it.
|
||||
- Find thread IDs with `t3_list_threads` on the `mosaic-stack` project;
|
||||
threads carry the agent's name as title. Never invent an ID; write
|
||||
`thread-id: unknown` instead.
|
||||
- Always pass `idempotencyKey` (`<lane>-<purpose>-<date>`).
|
||||
- Replies and notices go out with `wait` off. Use `wait: true` only when you
|
||||
cannot continue without the answer. Two agents waiting on each other block
|
||||
until timeout.
|
||||
|
||||
### tmux seats
|
||||
|
||||
`tools/tmux/agent-send.sh` is the only tmux send path. It prepends the
|
||||
preamble, submits reliably (bracketed paste, Enter flush, draft detection),
|
||||
and ships itself over ssh for remote targets. Never raw `tmux send-keys`;
|
||||
that is how messages die as unsubmitted drafts.
|
||||
|
||||
### Preamble
|
||||
Preamble is prepended to the message when using the `agent-send.sh` script.
|
||||
Check the script for usage instructions.
|
||||
|
||||
@@ -36,22 +74,25 @@ Check the script for usage instructions.
|
||||
[<src> -> <dst> class=<CLASS>] <message> # with triage class
|
||||
```
|
||||
|
||||
- Non-Fleet seats use the default docket.
|
||||
- Non-Fleet seats use the default socket.
|
||||
- Fleet seats use the named socket: `-L mosaic-fleet` (or `MOSAIC_TMUX_SOCKET`).
|
||||
Fleet traffic stays off the user's default tmux server.
|
||||
- Address durable fleet seats exactly: `=coder0`, not a prefix that might match
|
||||
two sessions.
|
||||
- Tool spec and internals: `tools/tmux/README.md`
|
||||
|
||||
- `host` is `hostname -s` of the sender's machine; `session` is the tmux session
|
||||
name. `agent-send.sh` writes the preamble for you. Two rules carry the protocol:
|
||||
name. `agent-send.sh` writes the preamble for you. Never write the bracket
|
||||
line yourself.
|
||||
|
||||
### Both transports
|
||||
|
||||
1. Replying? Flip it: `[<dst> -> <src>] ...`. Answer under your own lane.
|
||||
The tool performs the flip: aim your send at the original sender's session
|
||||
(`agent-send.sh -s <src_session> -C <class>`) and it writes the flipped
|
||||
preamble for you. Never write the bracket line yourself.
|
||||
2. A preamble-less cross-agent message is malformed. If you receive one, ask
|
||||
the sender to resend before acting on it.
|
||||
On T3, send to the sender's thread ID with the header flipped. On tmux,
|
||||
aim `agent-send.sh -s <src_session> -C <class>` at the sender and the
|
||||
tool writes the flipped preamble.
|
||||
2. A header-less cross-agent message is malformed. If you receive one, ask
|
||||
the sender to resend before acting on it. A T3 prompt with no header and
|
||||
no claim to come from an agent is from Jason.
|
||||
|
||||
## Triage classes
|
||||
|
||||
@@ -74,22 +115,30 @@ Class honestly. Never downgrade a question you want answered to `terminal-log`.
|
||||
2. One topic per message. Two asks in one paste is how the second gets lost.
|
||||
3. Reply, even when the reply is "ACK, on it" or "cannot, reason follows".
|
||||
Silence is not an ack. A refusal with a reason is recoverable; a guess is not.
|
||||
4. No secrets. Messages land in scrollback, logs, and possibly comms daemons.
|
||||
4. No secrets. Messages land in scrollback, logs, T3's database, and possibly
|
||||
comms daemons.
|
||||
5. Waiting on a condition? Arm `agent-watch` on the condition, not a poll of a
|
||||
colleague's pane. Waiting on a seat? Message them (see ms-watch).
|
||||
colleague's pane or thread. Waiting on a seat? Message them (see ms-watch).
|
||||
6. Every T3 message starts or steers a turn in the recipient and costs tokens.
|
||||
Do not answer an ACK or a `reaction` with another ACK.
|
||||
|
||||
## Receiving
|
||||
|
||||
1. Read the preamble first. Confirm you are the `dst`. Note the `src`.
|
||||
1. Read the header first. Confirm you are the recipient. Note the sender and,
|
||||
on T3, the sender's thread ID.
|
||||
2. Triage by class (table above). `actionable` or absent: act now, or reply why not.
|
||||
3. Reply by sending: invoke `agent-send.sh` aimed at the sender's session; the
|
||||
tool writes the flipped preamble. Cite the run id or issue you acted on.
|
||||
Formatting the reply into your own output without running the tool leaves
|
||||
the sender with nothing; that is a dropped reply, not a late one.
|
||||
3. Reply by sending on the transport the message came in on: `t3_send_message`
|
||||
to the sender's thread, or `agent-send.sh` aimed at the sender's session.
|
||||
Cite the run id or issue you acted on. Formatting the reply into your own
|
||||
output without running the tool leaves the sender with nothing; that is a
|
||||
dropped reply, not a late one.
|
||||
|
||||
## Delivery mechanics
|
||||
|
||||
- Exit codes: `0` delivered or queued, `1` target not found, `2` still draft,
|
||||
- T3: a send returns `threadId`, `turnId`, and `turn.state`. A returned
|
||||
`turnId` is the receipt. A tool error or a missing token means no delivery;
|
||||
run the status check in the T3 guide and diagnose.
|
||||
- tmux exit codes: `0` delivered or queued, `1` target not found, `2` still draft,
|
||||
`3` usage error, `4` ambiguous socket (the session name exists on more than
|
||||
one tmux server; disambiguate with `-L`).
|
||||
- A refusal is evidence. Diagnose it; do not route around it with raw send-keys.
|
||||
|
||||
Reference in New Issue
Block a user