Files
callstack__agent-device/docs/adr/0006-daemon-rpc-protocol-version.md
2026-06-23 17:20:08 +02:00

3.2 KiB

ADR 0006: Daemon RPC Protocol Version

Status

Accepted

Context

agent-device can run a client on one machine and reach a daemon on another machine through the HTTP JSON-RPC transport, including agent-device proxy in front of a local macOS daemon. Client and remote host package versions can differ. Many version skews are safe because the client sends a stable command request envelope and the daemon executes only the requested command.

Package semver is too strict for this boundary: a 0.15 client and 0.17 remote daemon can often interoperate. At the same time, the client needs a cheap way to fail before sending command RPC when the transport protocol itself is no longer compatible.

Decision

The daemon HTTP /health payload advertises a rpcProtocolVersion integer alongside service and package version metadata. Remote clients compare this value before sending JSON-RPC requests.

Package version is diagnostic only and must not be used as a compatibility gate. Missing rpcProtocolVersion is treated as a legacy remote daemon and is allowed unless a later security or protocol decision explicitly retires legacy compatibility.

rpcProtocolVersion changes only when an older client and newer daemon, or newer client and older daemon, cannot safely communicate over the HTTP RPC boundary for existing commands. Bump it for breaking changes to:

  • HTTP route requirements for /health, /rpc, /upload, or /artifacts/*.
  • Authentication semantics required to authorize RPC, upload, or artifact requests.
  • JSON-RPC envelope shape, method naming, request id handling, or command request projection.
  • Response, error, artifact, upload, or progress-stream framing that existing clients parse.
  • Existing command request or response contracts when the old side would misinterpret the payload rather than fail clearly.

Do not bump it for additive changes:

  • New commands.
  • New optional request fields or flags that older daemons can ignore or reject with a normal command error.
  • New optional response fields that older clients can ignore.
  • Package version changes, refactors, or implementation-only daemon/proxy changes.

When a single command needs finer-grained compatibility in the future, prefer command-level feature or capability metadata over bumping the whole RPC protocol, unless the shared transport contract is also affected.

Alternatives Considered

  • Gate by package version: simple, but rejects compatible version skew and makes proxy usage brittle across frequent releases.
  • Do not check compatibility: maximizes compatibility but fails later, after the client has sent an RPC payload that a remote daemon may parse incorrectly.
  • Full schema negotiation: more precise, but too much machinery for the current JSON-RPC boundary.

Consequences

Protocol-breaking changes must update DAEMON_RPC_PROTOCOL_VERSION, tests that assert /health metadata, and at least one remote-client regression test that proves mismatched protocols fail before command RPC.

Legacy remote daemons without rpcProtocolVersion remain reachable. This keeps the first release of the proxy compatible with older HTTP daemons, but it means absence of the marker is not proof of compatibility.