# Prompt64 Wire Protocol v2 Each frame has a four-byte header: message type, flags, and a little-endian 16-bit payload length. Bridge payloads are limited to 768 bytes; the C64 accepts 92. Text is display-safe ASCII, with bytes `80`-`FF` reserved as literal C64 screen-code tokens (`byte & 7F`). The bridge uses those tokens for the opt-in PETSCII graphic palette. Protocol v2 is strict. The first frame must be `Hello` with `PROMPT64/2`. `HelloOk` returns major `2`, minor `0`, then a 16-bit little-endian capability mask. Capability bit 6 advertises the heartbeat watchdog, and bit 7 advertises durable approval acknowledgements. Any older or malformed greeting receives `PROMPT64/2 REQUIRED`. ## Messages | Type | Name | Payload | | --- | --- | --- | | `01` | Hello | `PROMPT64/2` | | `02` | HelloOk | major, minor, capability mask | | `03` | LeaseGet | empty | | `04` | LeaseState | 16-byte token, 16-bit lifetime seconds | | `05` | Reconnect | token, last applied sequence | | `06` | ReconnectState | token, active byte, latest sequence | | `07` | ReconnectDone | empty | | `08` | SessionRelease | empty request/acknowledgement | | `09` | Heartbeat | empty | | `0A` | HeartbeatAck | empty | | `10` | UserText | prompt | | `11` | AssistantDelta | sequence, text | | `12` | TurnDone | sequence | | `13` | ReasoningDelta | sequence, text | | `14` | TurnCancel | empty | | `15` | TurnCancelled | sequence | | `16` | ApprovalRequest | sequence, kind, summary | | `17` | ApprovalDecision | decision byte | | `18` | ActivityEvent | sequence, lifecycle byte, label | | `19` | TurnFailed | sequence, summary | | `1A` | HistoryText | speaker byte, text | | `1B` | ApprovalAck | sequence | | `20–2D` | Settings/workspace/session | control traffic described below | | `30` | DashboardGet | tab byte | | `31` | DashboardEntry | tab, stable row index, row data | | `32` | DashboardDone | tab, row count | | `33` | ActionGet | stable action index | | `34` | ActionText | editable prompt | | `35` | DiffGet | stable change index | | `36` | DiffLine | line kind, text | | `37` | DiffDone | empty | | `7F` | Error | display-safe summary | Every asynchronous current-turn frame (`11`, `12`, `13`, `15`, `16`, `18`, `19`, and `1B`) begins with a wrapping 16-bit sequence. A frame is newer when the unsigned wrapping distance from the applied sequence is between 1 and 32767. Control, history, dashboard, action, and diff frames are not sequenced. Heartbeat frames are also unsequenced and are never retained for replay. ## Leases and replay After `HelloOk`, a new client requests `LeaseGet`. The bridge permits one attached C64 per 128-bit token and at most eight detached leases. Unexpected disconnects keep provider state, activity, the current turn, attachments, and pending approvals for 120 seconds. Active work continues. The bridge retains at most 64 KiB of encoded current-turn asynchronous frames. Crossing the limit cancels the provider and emits `TurnFailed`. A reconnect supplies the token and last applied sequence; after `ReconnectState`, the bridge sends only newer retained frames and terminates replay with `ReconnectDone`. Duplicate attachments and expired/released tokens fail. `SessionRelease` cancels remaining work, closes bridge-owned provider state, invalidates the token, and is used for explicit F5/RUN-STOP navigation. During an active turn, the C64 sends a heartbeat after two seconds without inbound traffic. If no acknowledgement arrives within another two seconds, it enters the same lease reconnect and replay path as a detected socket error. TCP reopen attempts are spaced five seconds apart so the Ultimate network target and Wi-Fi interface have time to recover without a connection storm. An approval decision is complete only after the C64 receives a sequenced `ApprovalAck`. If the socket fails first, reconnect replay either supplies the retained acknowledgement or proves the decision was not received, in which case the C64 resends it. ## Settings, sessions, and history The existing control range is: - `20/21/22`: SettingsGet, SettingsSet, SettingsState. Reasoning is 0 Off, 1 Summary, or 2 Detailed. Both visible modes carry only provider-generated reasoning summaries. Value 3 is Developer; it requests Codex's developer reasoning level and carries raw provider reasoning text. - `23/24`: WorkspaceSet/WorkspaceState. Paths must resolve beneath the bridge workspace root. - `25/26/27`: SessionListGet, SessionEntry, SessionListDone. - `28/29`: SessionSelect/SessionState. `$FF` selects a new provider session. - `2A/2B`: AccessSet/AccessState. Access is 0 Read Only, 1 Ask Me to Approve, or 2 Auto Review. - `2C/2D`: HistoryGet/HistoryDone. `HistoryText` speaker is 0 user or 1 assistant; flag 1 starts an entry and flag 0 continues it. Approval kind is 0 command/network or 1 file/filesystem. Decisions are 0 accept once, 1 accept for session, 2 decline, and 3 cancel. ## Dashboard data Tab bytes are 0 STATUS, 1 ACTIVITY, 2 CHANGES, and 3 ACTIONS. ACTIONS requests fail while a turn is active. Dashboard, cancellation, and approval decisions may be sent during a turn and share one serialized bridge writer queue. STATUS includes provider, workspace, access, reasoning, turn state, Git branch, and change totals. ACTIVITY lifecycle is 0 started, 1 completed, or 2 failed. CHANGES row indexes remain stable until a new CHANGES snapshot. Diff kind is 0 context, 1 addition, 2 deletion, or 3 metadata. Git inspection uses direct subprocess arguments (never a shell or external diff), a three-second timeout, a 256 KiB combined-output ceiling, and unified one-context hunks.