# RVBox v1 control plane [`../protos/rvbox/v1/control.proto`](../protos/rvbox/v1/control.proto) defines the canonical control API. `rvc` uses the `Control` gRPC service over the local Unix-domain socket. The server also exposes the same unary operations through an optional JSON-RPC 2.0 HTTP adapter for local debugging and batch automation. ## Endpoints - Unix socket: enabled by default, mode `0600`, owned by the server account. - HTTP JSON-RPC: disabled unless enabled; default bind `127.0.0.1:6900`. It has no authentication by design. Binding it beyond loopback is an explicit deployment choice and requires external protection. gRPC streams command history and live events through `FollowCommand`. JSON-RPC remains simple: callers issue work, query command state, poll event/output pages after an event sequence, append stdin, close stdin, or signal a command. It does not invent a separate event-stream protocol. The JSON-RPC method names are the lower-camel protobuf operation names: `listClients`, `getClient`, `listCommands`, `getCommand`, `runCommand`, `appendStdin`, `closeStdin`, `signalCommand`, `getOutput`, and the three storage incident methods documented below. Parameters and results use protobuf JSON mapping (including base64 strings for `bytes` and UTC RFC 3339 strings for timestamps). Control response messages contain successful results only. gRPC failures use canonical non-OK status codes with structured RVBox details where needed; the JSON-RPC adapter maps the same domain errors to standard JSON-RPC error objects. `getOutput` and `getCommand` are the polling path for what gRPC exposes as follow streams. `rvc stat CLIENT` also shows the active durable client-instance ID and the most recent different instance rejected while that client is live. An operator may run `rvc client takeover CLIENT INSTANCE-ID`; this creates a one-shot 5-minute authorization for that exact pending claim. Its matching reconnect consumes the authorization and fences the old session. If the old session is no longer live, the replacement connects normally without this command. The JSON-RPC method is `authorizeClientTakeover`. Both transports enforce the same decoded field limits. A control gRPC request may be at most 16 MiB; a JSON-RPC HTTP body may be at most 24 MiB to accommodate base64 expansion of the 10 MiB script maximum. `ExecutionSpec` itself may be at most 768 KiB, which also keeps its agent dispatch below the 1 MiB envelope cap. ## CLI semantics `rvc stat` maps to `ListClients`, `GetClient`, `ListCommands`, and `GetCommand`. History pages default to 20 commands and may request at most 100. Historical output uses opaque, byte-bounded cursors and may resume within an output event; it is not numbered or paginated by lines. The server returns uncompressed output slices with event sequence, byte offset, stream, observed timestamp, and server receipt timestamp. `rvc` may render line-oriented human output, but line boundaries are not storage or pagination boundaries. `rvc run` always creates a durable command through unary `RunCommand`, which returns the UUID. Foreground mode then calls `FollowCommand` with that UUID, `after_event_seq=0`, and `include_existing=true`, streaming output until a terminal event. `--background` returns immediately after `RunCommand`. Interrupting the CLI, timing out its local wait, or losing the local control connection never cancels remote work. The explicit `rvc kill` operation is the only termination path. A foreground caller can resume `FollowCommand` after its last received event sequence without missing durable history. `FollowCommandResponse` wraps either a client-sequenced `CommandEvent` or a server-created retention marker and exposes server receipt/recording time separately from client observation time. A retention marker does not advance the resume cursor. When retained history is incomplete, the server emits the relevant marker before any terminal event on that stream, so a follower never stops on terminal while believing truncated history was complete. Mutating requests accept an optional `request_id`. `rvc` generates one per mutation and reuses it for transport retries; `--request-id` lets automation reuse it across CLI invocations. The CLI accepts that option globally and drops it for reads. For `RunCommand`, the supplied request ID is the command's `issue_uuid`. For stdin, close, signal, repair, and acknowledgement operations it deduplicates that action while `issue_uuid` or `incident_id` continues to identify the target. The server generates a request ID when omitted, preserving simple JSON-RPC use. The server stores the mutation kind, target, immutable request hash, and result under that ID. An identical retry returns the original result; reuse with any different method, target, or content returns `CONFLICT`. The record is owned by the affected command or incident for quota and retention. A retry after that owner has been reclaimed cannot repeat the action: it returns retained tombstone information where available or `NOT_FOUND`. `rvc run --queue-ttl` controls how long work may wait for server-confirmed acceptance and defaults to 15 minutes; zero means indefinite. `rvc stat` distinguishes terminal `Expired`, `Expired (awaiting reconciliation)`, and actual lifecycle with a late-after-expiry warning. It renders terminal `Rejected` with the client's structured validation/platform reason; `Failed` means the requested code actually launched. `rvc append` turns a string into `StdinWrite` with `append_newline=true` unless the caller selects raw mode; `--file` supplies raw bytes; `--attach` streams local standard input. `CloseStdin` is available separately. All stdin actions are acknowledged and idempotent. ## Query behavior Command details expose persisted request fields, effective execution metadata, lifecycle, terminal result, output availability/truncation, current resource snapshot, and `suspected_hung` diagnostics. The latter is informational and must not be shown as a terminal state. Pagination response cursors are stable within their declared ordering (newest issue time for command lists; increasing `event_seq` for events/output). Control failures are never embedded in otherwise-successful response messages. They use canonical gRPC status codes with structured RVBox details; JSON-RPC returns the corresponding JSON-RPC error object, and `rvc` maps the same domain error to a stable exit code rather than parsing text. ## Storage incidents `rvc storage incidents` lists unresolved storage incidents by default and can include resolved history. `rvc storage repair INCIDENT` attempts only a known safe repair. `rvc storage acknowledge INCIDENT --note ...` accepts documented irrecoverable loss and clears that incident from dirty health. Both mutations use the same optional `--request-id` behavior as other mutations. An acknowledgement note is required and bounded to 4 KiB. Repair or acknowledgement changes incident state; it does not delete history as part of that action; resolved history later follows the independent audit/incident quota. The JSON-RPC equivalents are `listStorageIncidents`, `repairStorageIncident`, and `acknowledgeStorageIncident`.