Files
stack/skills/ms-communications/SKILL.md
T
jason.woltjeandClaude Opus 5.5 21e3e908b6 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]>
2026-09-26 14:33:24 -05:00

153 lines
7.1 KiB
Markdown

---
name: ms-communications
description: Use this skill whenever sending a message to, or receiving one from, another Mosaic agent.
disable-model-invocation: false
---
# ms-communications
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 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; 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 is prepended to the message when using the `agent-send.sh` script.
Check the script for usage instructions.
```
[<src_host>:<src_session> -> <dst_host>:<dst_session>] <message>
[<src> -> <dst> class=<CLASS>] <message> # with triage class
```
- 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. Never write the bracket
line yourself.
### Both transports
1. Replying? Flip it: `[<dst> -> <src>] ...`. Answer under your own lane.
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
| Class | Meaning | Recipient behavior |
|---|---|---|
| (absent) | fail-safe default | treat as `actionable` |
| `actionable` | decision, blocker, or gate | act, then reply |
| `human` | from a human operator | deliver; respond promptly |
| `reaction` | emoji or ack | note it; no reply expected |
| `terminal-log` | log-only noise | file it; never act |
| `digest` | machine-wake, coalescible | batch; wake and continue |
Class honestly. Never downgrade a question you want answered to `terminal-log`.
## Etiquette
1. Write for a context-wiped reader. Preamble plus body must carry the ask, the
evidence (run id, issue number, path), and any deadline. The recipient has
no "as I mentioned earlier".
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, 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 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 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 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
- 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.
- rc=2 from an `agent-watch` delivery means the text reached your pane as a
draft. Go read the pane; `auto-submit-drafts.sh` flushes stable drafts.
## When not to message
- Waiting on yourself: do the next thing.
- Facts that must survive the exchange belong in the run record, the issue, or
SESSIONS.md. A message that matters gets persisted where the record lives.