socket API and protocol reference
the wire contract for any language: transport and framing, version negotiation, the method catalogue, the event catalogue, error codes, and the herdr driver contract.
the orcr server exposes everything over a Unix domain socket. the socket API is the API; the CLI and the SDK are thin clients of it. this page describes the wire contract so a client in any language can speak it directly.
this reference is rendered from
orcr api schema. runorcr api schema --jsonto get the machine-readable document (methods, params/results, event kinds, error codes, protocol version). the schema is the contract; these pages describe it in prose.
transport
- socket at
~/.orcr/orcr.sock, created with umask 077 and mode 0600. there is no TCP port; filesystem permissions are the only authentication, so only processes running as your uid can open the socket, the same approach herdr uses. - home safety: the server refuses to start (
environment_error,cause: unsafe_home) unless~/.orcris owned by the current uid and is not group- or world-writable. socket paths arelstat-validated (symlinks rejected); a stale socket is unlinked only while holding the instance lock and only if it is owned by the same uid. - single instance and auto-start: startup takes an exclusive
flockon~/.orcr/orcr.lock; the server refuses to open the store without it. a client auto-starting the server first validates any existing socket with a handshake; losers of a start race wait for readiness rather than spawning a second server. readiness is aserver.handshakeresponse carrying pid, protocol version, and store path. - failure modes are distinct errors:
server_unreachable(cannot connect),server_start_failed(spawn failed),herdr_unreachable(server fine, herdr not).
framing and envelopes
newline-delimited JSON envelopes over one multiplexed connection. a maximum frame size is enforced.
requests carry the protocol version, a client-chosen id, a method, and params:
{ "protocol": 1, "id": 7, "method": "agent.run", "params": { "path": "/review/worker", "prompt": "…" } }responses correlate by id:
{ "id": 7, "ok": true, "result": { } }
{ "id": 7, "ok": false, "error": { "code": "state_conflict", "message": "…", "details": { } } }subscription events interleave with responses on the same connection:
{ "subscription": 2, "seq": 4821, "event": { "kind": "agent.status_changed", "…": "…" } }version negotiation
the protocol version is negotiated on the first request. a mismatch returns environment_error with cause: unsupported_version. unknown fields are ignored, so the protocol evolves additively. the current orcr protocol version is 1 (distinct from herdr's own protocol version).
methods
every CLI verb maps 1:1 to a method. the full set:
| method | CLI verb | streaming |
|---|---|---|
agent.run | agent run | |
agent.ask | agent ask | |
agent.send | agent send | |
agent.logs | agent logs | |
agent.wait | agent wait | |
agent.kill | agent kill | |
agent.ls | agent ls | |
agent.attach.prepare | agent attach (prepare step) | |
agent.attach.heartbeat | agent attach (keepalive) | |
agent.attach.release | agent attach (detach) | |
loop.create | loop create | |
loop.pause | loop pause | |
loop.resume | loop resume | |
loop.rm | loop rm | |
loop.ls | loop ls | |
loop.logs | loop logs | |
loop.run.start | loop run start | |
loop.run.stop | loop run stop | |
loop.run.ls | loop run ls | |
server.handshake | (readiness probe) | |
server.status | server status | |
server.stop | server stop | |
api.schema | api schema | |
api.snapshot | api snapshot | |
events.subscribe | (SDK watch / clients) | yes |
watch.open | orcr top, SDK watch | yes |
attach is the one CLI verb that is not a single method: it is terminal-mediated, so the CLI calls agent.attach.prepare and then execs herdr agent attach locally. params and result shapes for each method are in the schema and, in prose, on the matching CLI page (for example agent and loop).
events and cursors
event rows are written in the same transaction as the store change they describe, so events.seq is a monotonic cursor with no gaps. transitions that depend on an external side effect (a pane move or close, a process signal, a spawn) use an intent/applied pair: a *_requested event is persisted before the herdr or OS call, a *_applied event after the observed fact. reconciliation emits repair events for anything it derives after a crash, so subscribers never see a state the recovery path skipped.
subscriptions accept since_seq; snapshots carry snapshot_seq. watch.open creates a snapshot plus a subscription under one server-side cursor pin, so high churn cannot expire snapshot_seq before the subscribe lands (no re-snapshot livelock). replay retention is bounded; a too-old cursor on an unpinned subscribe gets server_error (cause: cursor_expired) and re-snapshots.
event catalogue
every payload carries enough fields to update an api snapshot state incrementally.
| group | kinds |
|---|---|
| agent | agent.created, agent.status_changed, agent.turn_completed, agent.response_captured, agent.location_changed, agent.ended |
| queue | queue.promoted (queue membership is otherwise derived from agent.created / agent.ended / queue.promoted) |
| attach | attach.started, attach.ended |
| loop | loop.created, loop.fired, loop.coalesced, loop.skipped, loop.paused, loop.resumed, loop.removed, loop.ended |
| loop run | loop_run.started, loop_run.ended, loop_run.stopping |
| control | server_stopping |
error codes
responses carry a stable error code and detail. the nine codes and their exit mappings are documented in full on the error codes reference; the schema exposes them under ERROR_CODES.
the herdr driver contract
orcr's server speaks herdr's own socket API directly (JSON protocol, versioned, schema published by herdr api schema; sockets are per-session, discovered from herdr session list --json). the driver's operation set is pinned to named herdr methods with fixed shapes in an in-code contract table, whose methods and result types are checked against the installed herdr's live api schema: version drift fails the conformance check.
the pinned operations:
agent.start {name, argv, cwd?, env?, workspace_id?, focus:false}: herdr creates the tab and pane; the returned workspace/tab/pane/terminal ids are authoritative. orcr does not pre-create tabs.pane.move(destination forms for park/un-park),pane.close.pane.send-text/pane.send-keys(input delivery is two calls, never one).pane.list/agent.list(status,agent_session,terminal_idreads).workspace.create.- session enumeration: sessions are per-socket; the driver discovers them via
herdr session list --jsonand fans out over each session's socket for cross-session reads. - notification, and herdr integration-state reads (which method reports whether a provider's integration is installed).
a minimum herdr protocol version is declared and handshake-checked. see providers and integrations for why a provider needs both a herdr integration and an orcr integration.
SDK reference
the typed @orchestratr/sdk surface: the generated protocol client, the orcr.* convenience helpers, handles, scopes, watch, context, and the one error class per error code.
configuration reference
every config.json key, its default, and its validation rule, plus precedence, unknown-key handling, and the environment overrides.