# Runa Protocol `runa-protocol` defines versioned request, response, and event data contracts for clients and the `runa-server` dispatcher. It is independent of transport and runtime implementation. `runa-server` accepts JSON Lines over stdio or, when started with `--listen`, over TCP bound to an IPv4 or IPv6 loopback address. The TCP listener is unauthenticated and is intended only for trusted local development. ## Version 2 Every request and response carries `version: 2`. Requests also carry a non-empty `request_id` used to correlate the response. A server must reject unsupported versions with `unsupported_version` rather than interpreting a request using a different contract. Events carry the protocol version and do not have a request ID. Requests have a tagged command object: ```json { "version": 2, "request_id": "req-1", "command": { "operation": "send", "parameters": { "actor_ref": "xK8_pQ2-Lm5_012345678", "message": { "kind": 2, "value": 9, "target_ref": "Hj2_9sM0-pQ4_7aBcD3eF" } } } } ``` The version 2 operations are behavior publication, rollback, lookup, source retrieval, actor spawn, send, tick, inspect, actor listing, event retrieval, stop, restart, pause, resume, cancellation, and behavior installation. Migration closures are intentionally excluded: they are host callbacks, not portable wire values. Responses echo the request ID and carry either a typed reply or a protocol error. Events use a separate versioned envelope. Actor and behavior snapshots are wire DTOs, not serialized runtime objects; implementation identities are represented by their stable display strings. Public actor identity is a 21-character URL-safe NanoID string carried in `actor_ref`; message `target_ref` is optional and omitted when absent. The server maps known service failures to the defined error codes and otherwise uses `runtime_failure` rather than claiming a more specific category. `get_events` drains and returns the events currently accumulated by this single-worker image. It is not a durable subscription or replayable event log. Both transports limit each request line to 1 MiB before parsing. Malformed JSON or an oversized line terminates that stream with an error; no protocol response is emitted when a request cannot be decoded. Stdio EOF terminates the process, while TCP EOF closes only that client connection. The TCP listener allows up to 16 simultaneous clients and serializes each dispatch through the same image. TCP response payloads are capped at 1 MiB, with at most one response queued per client. Every local client can use the full development API; loopback binding is not authentication or authorization. Remote access must not be enabled until appropriate authentication and authorization exist. The `runa-client` crate launches the stdio server locally and validates response protocol versions and request IDs. The current validation checks the protocol version, request ID, actor-reference shape, positive revisions where required, non-empty behavior names, mailbox capacity, and instruction budget. Behavior-name grammar, actor existence, current behavior revisions, mailbox capacity at send time, and all runtime invariants remain authoritative at the application-service boundary.