runa/docs/protocol.md

3.0 KiB

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 1

Every request and response carries version: 1. 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:

{
  "version": 1,
  "request_id": "req-1",
  "command": {
    "operation": "send",
    "parameters": {
      "actor_id": 7,
      "message": { "kind": 2, "value": 9 }
    }
  }
}

The version 1 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. 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, positive actor/revision identifiers 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.