RM Link v1 is JSON over WebSocket at /v1/link. The client first sends { version, deviceId, token, afterSequence }. The Host authenticates before accepting commands, fixes a replay watermark, sends durable events through that watermark, attaches the socket to the live set, and finishes with a validated handshake.ack control frame.
The acknowledgement contains:
- Host public ID and latest durable sequence
- runnable provider ID, probed version, diagnostic message, normalized capabilities, model catalog, Skill catalog, and resumable-session catalog
- configured workspace public ID and display name
It does not contain provider credentials, environment variables, Skill paths, provider thread IDs, or raw App Server initialization data. Resumable-session entries deliberately include canonical Host paths so an authenticated client can identify a workspace before resuming or starting a session there. Clients treat the link as online only after this acknowledgement, not merely when the WebSocket opens.
Commands carry a client-generated commandId. The Host persists it before execution; a duplicate never executes again. Durable events are stored in SQLite WAL mode. Reconnect supplies the highest applied sequence, and the Host replays only later events. The client also rejects any event with a sequence at or below its applied watermark.
Zod validates every handshake, acknowledgement, command, envelope, and typed payload. Unknown or invalid messages are isolated as protocol issues and do not crash the client. Client state preserves turn-to-session relationships so output and tools cannot leak into a different session view.
Implemented commands are:
- session start, resume, fork, mark-read, and Agent Slot clear
- message send (new turn or active-turn steering)
- approval resolution
- turn interruption
- provider-session catalog refresh
- replay sync request
Session start can carry either the configured workspace ID or a Host-local absolute cwd; it can also carry a model, reasoning effort, and opaque Skill ID. Host resolves a selected path with realpath, verifies that it is an existing directory, assigns a stable public workspace ID, and then passes it to the Adapter. Model and effort apply to a new turn; active-turn steering keeps the settings of the in-flight turn because App Server does not accept those overrides on turn/steer.
provider.sessions.updated replaces the client-side resumable-session catalog after an explicit refresh. command.session.resume accepts an optional Agent Slot index, but never accepts a provider thread ID; the Adapter resolves the public session ID back to the private Codex thread ID.
agent.slot.updated persists assignment and unread state for one of six fixed slots. host.snapshot contains all six reduced slots so a reconnect restores the same surface without client-side guessing.
Question answering remains schema-only and returns an explicit rejected-command event. Each accepted or rejected command is correlated back by command ID. Large artifact HTTP download and an automatic snapshot fallback remain future extensions; /v1/snapshot exposes the current reduced state for local diagnostics.