control board: brief for piece 2, reply-from-board, with Gate C (#1503)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
@@ -97,6 +97,63 @@ because the launch gave no `--task`; the next real use is
|
||||
task instead. Fleet seats stay on the old launchers; only `agents/` seats
|
||||
register. Next piece in Jason's order: reply-from-board.
|
||||
|
||||
## Piece 2: reply-from-board
|
||||
|
||||
Approved by Jason 2026-09-12 after Gate B ("seat task update works. I want to
|
||||
keep things building"). Same shape as #1503/#1504: one piece, one yes/no gate,
|
||||
small commits with tests on `refactor`. Darkwing opens the issue and updates
|
||||
`CURRENT.md` when he picks it up.
|
||||
|
||||
### What it is
|
||||
|
||||
A reply box on the board. Jason types a message on a seat's row and the board
|
||||
delivers it to that seat's tmux pane through the repository's own channel.
|
||||
No new transport, no message store, no WebSocket.
|
||||
|
||||
- **Page**: a one-line text box and a Send button in each row's detail
|
||||
(registered rows only, see below). After Send the row shows one of two
|
||||
receipts: `delivered` with the time, or `failed` with the tool's stderr.
|
||||
Nothing else changes on the page; the next scan shows the effect (the
|
||||
seat's newest user message is the text just sent, and a `waiting` row
|
||||
turns `working`).
|
||||
- **Server**: `POST /api/reply` with `{ "agent": "<row id>", "text": "..." }`.
|
||||
The handler resolves the row's tmux session, runs
|
||||
`tools/tmux/agent-send.sh -s <session> -S "<host>:control-board" -m <text>`
|
||||
and returns the exit code, stdout and stderr. The exit code is the receipt;
|
||||
a non-zero code is a failure the page shows verbatim. `-S` labels the
|
||||
sender so the seat's preamble reads `[<host>:control-board -> …]`. Fleet
|
||||
sockets pass `-L` from the registration's `tmux.socket` when set.
|
||||
- **Which rows**: only rows whose registration (#1504) names a tmux session,
|
||||
and whose registration is not stale. Everything else shows "reply needs a
|
||||
registered seat" instead of the box. Seat name alone is not an address; the
|
||||
registration's session is.
|
||||
- **Never**: raw `tmux send-keys`, a queue, retries, a history panel, a
|
||||
broadcast, sending to more than one seat per request. The durable record of
|
||||
what was said is the seat's own session log, which the scanner already reads.
|
||||
|
||||
### Gate C (yes/no)
|
||||
|
||||
Jason answers a seat that is `waiting` from the board, without opening a
|
||||
terminal, and within one scan the row is `working` and its Task or last
|
||||
message reflects the reply. One real exchange is the pass.
|
||||
|
||||
### Tests
|
||||
|
||||
- Server: a fake `agent-send.sh` on PATH captures its argv; assert `-s`, `-S`,
|
||||
`-L` (when the registration has a socket) and the message text.
|
||||
- Refusals with exit codes surfaced: unknown row, empty text, row without
|
||||
registration, stale registration, tool exit non-zero (stderr returned).
|
||||
- Page: the box appears only on registered live rows; a failure receipt shows
|
||||
the stderr text.
|
||||
- Loopback only stays as is; no auth is added for this piece.
|
||||
|
||||
### Boundaries
|
||||
|
||||
- No change to `packages/seat` or the registration record.
|
||||
- No change to `tools/tmux/agent-send.sh`; if it refuses, the refusal is the
|
||||
finding (ms-communications rule), reported on the page and in the issue.
|
||||
- Fleet seats are out: they are not registered (Jason, 2026-09-12).
|
||||
|
||||
## How the scanner decides state
|
||||
|
||||
The scanner reads the newest pi session log for each agent, plus whether
|
||||
|
||||
Reference in New Issue
Block a user