Boundary: poweroff command (confirm + boot_id, sent once); hello carries boot_id
/ crosscheck (push) Successful in 1s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
2026-10-13 18:35:06 +09:00
parent b79820dfce
commit e6a1d7f79f
+7 -1
View File
@@ -31,7 +31,7 @@ The two channels from decision 24 share the socket but keep different guarantees
| `t` | When | Fields | | `t` | When | Fields |
|---|---|---| |---|---|---|
| `hello` | first message | `proto` (0), `server`, `host`, `source` (`bus` \| `mock` \| `none`), `mock`, `hb_ms`, `timeout_ms` | | `hello` | first message | `proto` (0), `server`, `host`, `boot_id` (the host's, changes every boot), `source` (`bus` \| `mock` \| `none`), `mock`, `hb_ms`, `timeout_ms` |
| `hb` | every `hb_ms` | `ts` (Orin epoch ms), `clients` | | `hb` | every `hb_ms` | `ts` (Orin epoch ms), `clients` |
| `state` | 5 Hz, when there is a source | `seq`, `mock`, `signals`: name → envelope (`schema/envelope.json`) | | `state` | 5 Hz, when there is a source | `seq`, `mock`, `signals`: name → envelope (`schema/envelope.json`) |
| `ack` | reply to a `cmd` | `id`, `ok`, `detail`, `dup` (true when answered from the cache) | | `ack` | reply to a `cmd` | `id`, `ok`, `detail`, `dup` (true when answered from the cache) |
@@ -66,10 +66,16 @@ tablet, or an Orin behind a replugged hub, looks connected at the link layer.
|---|---|---| |---|---|---|
| `ping` | — | `ack` with `detail: "pong"` | | `ping` | — | `ack` with `detail: "pong"` |
| `mark` | `text`, `delay_ms` (optional: how long the command waited before this send) | stamped into the open recording; fails with no session open | | `mark` | `text`, `delay_ms` (optional: how long the command waited before this send) | stamped into the open recording; fails with no session open |
| `poweroff` | `confirm: "poweroff"`, `boot_id` (from this connection's `hello`) | acks, then shuts the host down cleanly (`systemctl poweroff`) about 2 s later. Refused unless svc-gw runs with `--allow-poweroff` (the Orin's unit only), and when `boot_id` is not the current boot's |
A repeated `id` returns the original `ack` (last 256 kept, shared across A repeated `id` returns the original `ack` (last 256 kept, shared across
connections) and never re-runs the command. connections) and never re-runs the command.
`poweroff` is the exception to retry-until-acked: the ack cache does not survive
the reboot it causes, so a resend could shut the next boot down too. The client
sends it once and does not resend it; `boot_id` makes svc-gw refuse one from a
previous boot regardless.
## Not yet ## Not yet
- TTS utterances (id, chunk sequence, terminator, expiry) — when there is a TTS. - TTS utterances (id, chunk sequence, terminator, expiry) — when there is a TTS.