From e6a1d7f79f44dd5cb33bd472dc2941995fbb36a3 Mon Sep 17 00:00:00 2001 From: Mikkeli Date: Tue, 13 Oct 2026 18:35:06 +0900 Subject: [PATCH] Boundary: poweroff command (confirm + boot_id, sent once); hello carries boot_id Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz --- docs/BOUNDARY.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/BOUNDARY.md b/docs/BOUNDARY.md index 2ad2af6..faf0bf6 100644 --- a/docs/BOUNDARY.md +++ b/docs/BOUNDARY.md @@ -31,7 +31,7 @@ The two channels from decision 24 share the socket but keep different guarantees | `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` | | `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) | @@ -66,10 +66,16 @@ tablet, or an Orin behind a replugged hub, looks connected at the link layer. |---|---|---| | `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 | +| `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 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 - TTS utterances (id, chunk sequence, terminator, expiry) — when there is a TTS.