RPC Envelope Specification
Authority: Primary (Normative)
Purpose: Defines envelope structure, channel subject rules, and validation for RPC.
Date: 2025-11-23 References: Protocol Architecture, ADR-010, ADR-006, ADR-002
Overview
The RPC envelope is a canonical structure carried inside MessageFrame.data. It provides type-safe semantics for requests, responses, notifications, and errors without adding new frame kinds to the protocol.
Encoded as JSON (v1) or CBOR (v2+).
Channel Subjects
RPC envelope semantics apply to rpc and event channel subjects. The MessageFrame.subject determines which envelope types are valid.
| Subject | Allowed t | Semantics |
|---|---|---|
rpc | "r", "R", "E" | Bidirectional request/response |
event | "N" | Fire-and-forget notification |
stream | — | Reserved (v2); reject per SBP |
app/* | — | Vendor-defined; not parsed as RPC envelope |
Note: rpc, event, and stream are exact-match channel subjects. Method/event dispatch happens via envelope fields (m for RPC methods, e for event names). The app/ prefix supports arbitrary sub-paths.
Receivers MUST validate envelope t against subject channel for rpc and event subjects. Mismatched envelopes MUST be dropped; receivers SHOULD log. This is non-fatal; continue processing subsequent frames.
Rationale: There is no valid subject to reply on. The sender receives a timeout, which signals failure; the receiver log provides diagnostics.
See SBP Behavior for subject format validation.
Envelope Structure
interface RpcRequest {
t: "r";
m: string; // method name
p?: unknown; // params
cid: FrameId; // request's frameId
}
interface RpcSuccess {
t: "R";
cid: FrameId; // matches request.cid
result?: unknown;
}
interface RpcError {
t: "E";
cid: FrameId; // matches request.cid
code: number;
message: string;
data?: unknown; // error details
}
interface RpcNotification {
t: "N";
e: string; // event name
d?: unknown; // no cid (fire-and-forget)
}Error Codes
RPC defines error codes in the 1100–1199 range:
| Code | Name | Semantics |
|---|---|---|
| 1100 | InvalidEnvelope | Envelope structure or encoding error |
| 1101 | UnsupportedMethod | Method not recognized by handler |
| 1102 | CorrelationMismatch | Response cid does not match any pending request |
| 1103 | Timeout | Request timed out waiting for response |
| 1104 | EnvelopeMismatch | Envelope type incompatible with subject channel |
Application errors use range 2000+ (user-defined).
See Error Code Registry for the canonical code definitions.
Encoding
JSON (v1): UTF-8 text, undefined fields omitted.
CBOR (v2+): Negotiated via handshake capability "encoding/cbor"; use if both peers support it, else JSON.
Correlation
Every frame's frameId is sender-local unique and MUST NOT be reused by receivers.
RPC correlation is explicit in the envelope:
- Requests set
cidto their request frame'sframeId - Responses copy that
cidunchanged - Runtime matches on
cid, notframeId
This preserves the frameId invariant and enables relays, proxies, and fan-out without changes to the wire format. See ADR-010.
Validation Rules
- Subject: Must match allowed
tper Channel Subjects - Request:
t: "r",mandcidrequired - Response:
t: "R"ort: "E"withcode,message,cid - Notification:
t: "N",erequired; useseventchannel
Unroutable envelope failures (e.g., unparseable payload) escalate to ErrorFrame per stack.md#error-scope-and-transport-authority. Subject-envelope mismatches are handled per Subject Namespacing.