What crosses between svc-gw and the app: hello, heartbeats both ways, state snapshots of envelopes with mock flagged per message, and commands carrying an idempotency key. TTS utterances are left for when a TTS exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
2.7 KiB
type
| type |
|---|
| reference |
Display boundary protocol — v0
Between a display client (app-flutter) and svc-gw. The
bus topics in schema/ stay inside the Orin; this is what crosses to the tablet.
Transport
One WebSocket, ws://<orin>:7700/, JSON text messages, each with a "t" type.
The tablet reaches the car Orin at 192.168.55.1 over USB NCM; the app binds to
that network itself (see app-flutter's initial plan).
The client always connects and owns reconnection. svc-gw refuses peers outside loopback, RFC 1918 and the tailnet's 100.64.0.0/10.
The two channels from decision 24 share the socket but keep different guarantees:
| Down (state) | Up (commands) | |
|---|---|---|
| Loss | tolerated; svc-gw drops the oldest when a client lags (64-message queue) | not tolerated; retry until acked |
| On reconnect | hello, then current state on the next tick |
resend anything unacked, same id |
Down: svc-gw → client
t |
When | Fields |
|---|---|---|
hello |
first message | proto (0), server, host, source (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) |
signals holds only what is currently known. A missing signal is unknown, a
null value is known-without-value, quality: "stale" is an old value. All three
are normal and a display must render each distinctly.
⚠ mock: true must be visible on the display surface whenever it appears in
hello or in any envelope. Not in a settings page, not in a log.
Up: client → svc-gw
t |
When | Fields |
|---|---|---|
hb |
every hb_ms |
— |
cmd |
on user action | id (unique, the idempotency key), cmd, args |
svc-gw drops a client silent for timeout_ms (5 s). The client should treat
timeout_ms without any downstream message the same way and reconnect: an asleep
tablet, or an Orin behind a replugged hub, looks connected at the link layer.
Commands
cmd |
args |
Effect |
|---|---|---|
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 |
A repeated id returns the original ack (last 256 kept, shared across
connections) and never re-runs the command.
Not yet
- TTS utterances (id, chunk sequence, terminator, expiry) — when there is a TTS.
gnssand decoded vehicle state from the bus — when the bus exists.- Any version beyond
proto: 0. A breaking change bumps it; the client checks it.