Skip to main content

Module protocol

Module protocol 

Source
Expand description

Unix-socket wire format (Wave 3, task 3.1).

§Framing (Claude’s Discretion #6)

Length-prefixed JSON: a 4-byte little-endian u32 length prefix, then that many bytes of UTF-8 JSON. The binary prefix is chosen over LSP-style Content-Length:\r\n\r\n for tightness; the trade-off (less human-readable on the wire) is acceptable because the daemon is not a debugging surface and every frame is structured JSON regardless. Frames over MAX_FRAME_BYTES are rejected before allocation, so a corrupt or hostile length prefix cannot drive an unbounded allocation.

§Two namespaces, one socket

Methods are namespaced by a <namespace>.<verb> prefix:

  • agent.*fno-agents client (spawn / ask / list / stop / rm / reconcile / status).
  • channel.* — the Phase 5 channel server (register_channel / unregister_channel / push_to_channel).

The split is namespace-only: same socket, same Unix-permission gate, different method prefixes. Namespace::of classifies a method so the daemon can route without string-matching at every call site.

§Drive (Wave 4 seam)

Interactive drive upgrades a connection to a WebSocket after the initial agent.drive request. Wave 3 lands the request/response transport only; the upgrade handshake and binary PTY frames are Wave 4. Namespace reserves no special drive variant because the upgrade is signalled by the agent.drive method, handled by the daemon, not by a distinct frame type.

Structs§

Request
A request from a client to the daemon. id correlates the response on a multiplexed connection; method is <namespace>.<verb>; params is an opaque JSON object the handler interprets.
Response
A response to a Request. Carries exactly one of result / error via ResponsePayload. The wire shape stays flat ({id, result} or {id, error}) for cross-language parity.
RpcError
Structured error in a Response.

Enums§

ErrorCode
Stable machine-readable error codes. Clients map these to exit codes; the design’s per-verb exit codes (13/14/15/18, …) are applied client-side from these. Serialized snake_case for cross-language parity.
Namespace
Method namespace, derived from the <namespace>.<verb> method prefix.
ProtocolError
Wire/transport errors.
ResponsePayload
The success-or-error payload of a Response. Making this a sum type means “exactly one of result / error” is unrepresentable-as-violated: there is no {result: None, error: None} nor {result: Some, error: Some} state to guard against. The flat {id, result | error} wire shape is preserved by Response’s hand-written Serialize/Deserialize below.

Constants§

MAX_FRAME_BYTES
Hard cap on a single frame’s JSON body. A length prefix larger than this is rejected before any allocation (Failure Modes: “reject malformed JSON-RPC frames … never crash the daemon”). 16 MiB comfortably covers the largest legitimate payload (a 64KB ask plus envelope) with headroom.

Functions§

read_frame
Read one length-prefixed frame’s raw JSON bytes. Returns ProtocolError::UnexpectedEof if the connection closes between frames (clean disconnect) or mid-frame (truncated). The caller treats a clean EOF as “client hung up”, not a daemon fault.
read_request
Read and deserialize one Request.
read_response
Read and deserialize one Response.
write_frame
Write body as one length-prefixed frame and flush. Rejects a body larger than MAX_FRAME_BYTES before writing so a buggy handler cannot emit an un-readable frame.
write_request
Serialize and write one Request.
write_response
Serialize and write one Response.