ADR 0003: IPC Wire Protocol
Status
Accepted.
Context
The daemon and shell need a local IPC protocol. The codebase already
has a .proto file (sysknife-proto) with message definitions for
RequestEnvelope, PreviewEnvelope, ResultEnvelope, and
TransactionRecord, and a bind_unix_listener helper. The question
is what framing and encoding to use over the Unix domain socket.
Candidates considered:
- gRPC over Unix socket — uses the proto definitions directly
with
tonic. Full service interface. Requires HTTP/2 and aserviceblock in the proto. - Length-prefixed protobuf — binary, compact. Requires a custom dispatcher (no HTTP/2). Harder to inspect without tooling.
- Length-prefixed JSON — 4-byte LE
u32length + UTF-8 JSON body. Uses the same Rust structs (sysknife-types) already tested for serialization. Human-readable, easy to debug withsocat.
Decision
Use length-prefixed JSON (option 3) for the Unix socket protocol.
Each message carries a "type" discriminant string so the dispatcher
can route without a full decode. The sysknife-types structs are reused
as-is — no additional generated code or build-time proto compilation
beyond what already exists.
The proto definitions in sysknife-proto are kept for potential future
use (e.g., a networked or gRPC-based control plane) but are not the
primary on-wire encoding for local IPC.
Consequences
- No new build-time dependencies for the daemon or shell.
- Messages are inspectable with standard tools (
socat,nc,jq). - A framing crate is not needed —
tokio::io::AsyncReadExt::read_exactis sufficient. - If a binary protocol is needed later (performance, cross-language clients), the socket path changes and both sides are updated together. There are no external clients to coordinate with.