This document specifies Hyperion's inter-process communication framework: the message-passing
layer that every Capability invocation, every Agent-to-Capability call, and every driver
interaction (per 03 β Kernel Architecture) actually rides on. 03 β
Kernel Architecture introduces endpoint_send/endpoint_recv as the
privileged-core IPC primitive and treats it as a given; this document is the deep-dive on what sits
above and around that primitive: capability-scoped channel discovery, the wire protocol,
synchronous call/response and asynchronous one-way messaging, zero-copy bulk transfer, and
transparent extension of a single invocation across process, container, VM, and β uniquely to this
document β remote-device boundaries. It does not redesign the kernel; every mechanism below is
built from primitives 03 already defines (CapabilityToken,
Object::Endpoint, the sandboxing depth spectrum).
02 β Core Architecture Β§5 requires exactly one security model, enforced at the kernel boundary; 03 β Kernel Architecture shows this makes IPC β not a syscall table β the only way any code touches anything outside its own address space. IPC is therefore not one subsystem among many: it is the substrate every other subsystem is built on. Three pressures converge on the design here:
- Every Capability invocation is an IPC round trip. 04 β Scheduler budgets end-to-end Intent latency for interactive workspace generation; if IPC overhead is not bounded and predictable, that budget is unmeetable no matter how fast a Capability's own logic is.
- A process must not be able to discover what it cannot use. 15 β Security Architecture and 17 β Threat Model both depend on IPC endpoints being unenumerable without a capability, not merely unusable β otherwise a compromised process can map the system's shape even while unable to act on it.
- An Agent invoking a Capability must not need to know where the implementation runs. 02 β Capability states the OS, not the developer, chooses an implementation based on context and resources; 21 β Distributed Execution extends that choice across federated devices. If the caller's code differs by locality, that choice stops being free for the OS to make.
02 β Core Architecture defines a Trust Boundary as "a process, container, VM, or remote host." 03 β Kernel Architecture fully covers the first three as one depth-dialed spectrum (0 in-process, 1 process, 2 container, 3 VM), all enforced by the same local privileged core. This document is the fourth case: a remote host, where no single privileged core is in a position to enforce anything, and every message must carry its own proof of authority. The IPC Framework is the layer that makes an invocation look identical across all four cases to the code issuing it.
Agent (11) or Capability invokes another Capability by CapabilityToken (02 Β§5)
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Typed Stub β generated from the β
β Capability's 26-apis.md contract, β
β caller-side, in-process β
βββββββββββββββββββββ¬βββββββββββββββββββ
β ipc_call() / ipc_notify()
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β IPC Runtime (L1) β
β routing table: token β Route β
β (resolved at grant time, Β§Algorithms) β
βββββββββββββββ¬ββββββββββββββ¬βββββββββββββ
Local route β β Remote route
βΌ βΌ
βββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β kernel endpoint_send / β β Federation Gateway β
β endpoint_recv (03) + β β (21 β Distributed Execution) β
β region capability for β β authenticated QUIC stream β
β zero-copy bulk transfer β ββββββββββββββββ¬βββββββββββββββββ
βββββββββββββ¬βββββββββββββ β
βΌ βΌ
βββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β Target service, this β β Remote Federation Gateway β β
β Trust Boundary, depth β β remote kernel endpoint β β
β 0-3 (03) β β remote service, same schema β
βββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
The routing table is populated at capability-grant time, not resolved by name at call time: a
CapabilityToken's origin field (03 Β§Data Structures) already distinguishes which Trust Boundary
minted it, so the IPC Runtime knows at channel_open whether a token resolves to a local endpoint
or a remote gateway before a single byte moves.
An endpoint is never named by a string a process can guess or enumerate. channel_open takes a
CapabilityToken the caller must already hold; if the token is absent, malformed, or revoked, the
IPC Runtime returns the identical Fault::NoSuchCapability it would return for an endpoint that
does not exist at all. A process without a token cannot distinguish "wrong token" from "nothing is
there" β which is what makes discovery, not just access, capability-gated, the property 15 β
Security Architecture and 17 β Threat
Model require.
/// A capability-scoped, schema-typed communication endpoint. Wraps a kernel
/// Endpoint capability (03-kernel-architecture.md) with what's needed to
/// frame, route, and β if the peer is remote β federate a call.
struct Channel {
endpoint: CapabilityToken, // kernel Object::Endpoint capability (03)
schema_id: SchemaId, // wire schema this channel speaks (26-apis.md contract)
route: Route,
class: ChannelClass,
}
enum Route {
Local,
Remote { device_id: DeviceId, gateway: CapabilityToken }, // 21-distributed-execution.md
}
enum ChannelClass { Call, Notify }
/// Wire frame: the only byte-level representation that crosses a Trust
/// Boundary. Fixed header, schema-typed body, optional zero-copy attachment.
struct Frame {
magic: u32, // 0x48594950 ("HYIP")
version: u16,
schema_id: SchemaId, // resolves to a compiled schema; never reflected at runtime
flags: FrameFlags, // CALL | REPLY | NOTIFY | ERROR | HAS_REGION
request_id: u64, // correlates CALL <-> REPLY; 0 for NOTIFY
payload_len: u32,
region: Option<RegionDescriptor>, // present iff HAS_REGION
payload: Vec<u8>, // schema-encoded control fields
}
/// A capability to a shared memory region, minted by the kernel exactly like
/// any other object capability (03 Β§Data Structures). Grants MAP rights over
/// a physical range without copying its bytes into the frame.
struct RegionDescriptor {
region_cap: CapabilityToken,
offset: u64,
len: u64,
}
/// One entry in a Trust Boundary's channel routing table, resolved at grant
/// time (see Architecture, above).
struct RoutingEntry {
token: CapabilityToken,
route: Route,
latency_class: LatencyClass, // consumed by 04-scheduler.md
}Synchronous call/response (rendezvous). ipc_call opens or reuses a Channel, constructs a
CALL frame with a fresh request_id, and β local case β invokes endpoint_send then blocks on
endpoint_recv for the matching REPLY; remote case β hands the frame to the Federation Gateway,
which forwards it over an already-authenticated QUIC stream and returns the correlated reply frame
when it arrives. The caller-side stub is identical in both cases; only the Route variant resolved
at channel_open differs.
Asynchronous one-way notify. ipc_notify constructs a NOTIFY frame (no request_id
correlation, no blocking wait) and returns as soon as the frame is enqueued at the peer's endpoint.
This is the point-to-point sibling of the broadcast mechanism in 31 β Event
System: ipc_notify is 1:1, sender-knows-receiver, used for things like a
Capability telling its one calling Agent "I'm 40% done," where 31 is 1:N and
receiver-unknown-to-sender.
Zero-copy bulk transfer. For payloads above a threshold set from 04 β Scheduler's
latency budget (large Semantic Object blobs per 09 β Knowledge Graph and
28 β Storage Engine), the sender calls region_share to mint a
RegionDescriptor over its own buffer rather than serializing it into payload. Only the
descriptor β a few dozen bytes β crosses the synchronous path; the receiver calls region_map to
map the same physical pages (read-only, or copy-on-write for mutation) into its own address space.
This mirrors the shared-memory fast path 03 β Kernel
Architecture
already commits to for driver I/O; the IPC Framework extends it to any Capability payload, not just
block/network/GPU buffers.
Transparent remote resolution. At channel_open, the runtime inspects the token's origin (03
Β§Data Structures). If origin names this Trust Boundary or a local descendant, route is Local.
If it names a federated device's Trust Boundary, route is Remote, and the runtime resolves β
from a capability-scoped directory object, never a free-text lookup β which Federation Gateway
endpoint reaches it. The resolved Route is cached on the Channel; the caller's stub code,
generated once from the Capability's 26 β APIs contract, never branches on it.
channel_open(token: CapabilityToken, schema: SchemaId) -> Result<Channel, IpcFault>
channel_bind(token: CapabilityToken, schema: SchemaId, handler: ServiceFn) -> Result<(), IpcFault>
ipc_call(chan: &Channel, req: Request, timeout: Duration) -> Result<Response, IpcFault>
ipc_notify(chan: &Channel, note: Notification) -> Result<(), IpcFault>
region_share(buf: &[u8], rights: RightsMask) -> RegionDescriptor
region_map(desc: RegionDescriptor) -> Result<MappedRegion, Fault>
ipc_call and ipc_notify are implemented entirely in terms of endpoint_send / endpoint_recv
(03 Β§Interfaces / APIs) plus, for HAS_REGION frames, region_share/region_map; there is no
second, parallel syscall surface β only a typed, framed convention layered over the kernel's two
primitives.
fn ipc_call(chan: &Channel, req: Request, timeout: Duration) -> Result<Response, IpcFault> {
let request_id = next_request_id();
let (payload, region) = encode(&req, chan.schema_id)?; // schema-based, no reflection
let frame = Frame {
magic: HYIP_MAGIC, version: WIRE_VERSION, schema_id: chan.schema_id,
flags: FrameFlags::CALL | region.as_ref().map_or(FrameFlags::NONE, |_| FrameFlags::HAS_REGION),
request_id, payload_len: payload.len() as u32, region, payload,
};
match &chan.route {
Route::Local => {
endpoint_send(chan.endpoint, frame.into())?; // 03: kernel fast path
let reply = with_deadline(timeout, || endpoint_recv(chan.endpoint))?;
decode_reply(reply, request_id)
}
Route::Remote { gateway, .. } => {
// Same frame, same schema; the gateway is just another capability-
// scoped endpoint (21-distributed-execution.md), not a special case.
let reply = with_deadline(timeout, || federation_send_recv(*gateway, frame))
.map_err(IpcFault::from_remote)?;
decode_reply(reply, request_id)
}
}
}
fn ipc_notify(chan: &Channel, note: Notification) -> Result<(), IpcFault> {
let (payload, region) = encode(¬e, chan.schema_id)?;
let frame = Frame {
magic: HYIP_MAGIC, version: WIRE_VERSION, schema_id: chan.schema_id,
flags: FrameFlags::NOTIFY, request_id: 0,
payload_len: payload.len() as u32, region, payload,
};
match &chan.route {
Route::Local => endpoint_send(chan.endpoint, frame.into()).map_err(IpcFault::Kernel),
Route::Remote { gateway, .. } => federation_send(*gateway, frame).map_err(IpcFault::from_remote),
}
}Discovery denial (Β§Architecture) closes the reconnaissance path a compromised process would
otherwise use to map live endpoints. Every frame still carries the caller's own capability token in
its schema-encoded fields, not merely relies on channel identity, which preserves 03's
confused-deputy prevention at the framing
layer: a server that receives a call is handed the caller's authority explicitly, never
substituting its own ambient rights. Remote routes are additionally protected by the Federation
Gateway's mutual authentication (device identity plus a capability minted specifically for that
device pairing, per 21 β Distributed Execution) and transport
encryption; a stolen frame in transit is useless without both the channel's schema and a live,
unexpired token, and a replayed frame is rejected because the token's generation (03 Β§Data
Structures) is re-validated at the receiving end exactly as for a local cap_invoke. Per-token
channel-open rate limits (set by 04 β Scheduler resource ledgers) bound
endpoint-exhaustion denial-of-service. All channel opens and remote federation calls are logged for
18 β Explainability & Trust and 34 β Observability &
Telemetry; full threat coverage is in 17 β Threat
Model.
- Peer crash mid-call. Identical to 03's driver
crash case: the peer's capability generation bumps, and the caller's pending
endpoint_recvor federation wait returnsFault::Revokedrather than hanging. - Network partition on a remote route. The Federation Gateway surfaces
IpcFault::PeerUnreachableafter its own timeout; per 02 Β§4's "degrade, never fail closed," the caller's Capability abstraction (02 β Capability) substitutes a local or cached implementation where one exists, rather than propagating a bare failure to the Agent. - Zero-copy region fault. A stale or out-of-range region access faults the IOMMU/MMU exactly as in 03 and is contained identically, not silently corrupting the receiver.
- Schema/version mismatch. Detected at
channel_open(schema negotiation, Β§Trade-offs) or, for a frame that slips through, at decode time, returningIpcFault::SchemaMismatchrather than misinterpreting bytes. - IPC deadlock / priority inversion. A synchronous call chain (A calls B calls A) or a
low-priority server blocking a high-priority caller is addressed jointly with 04 β
Scheduler's priority inheritance, over the same rendezvous primitive 03 β
Kernel Architecture flags as a shared concern; this
document supplies the hook (
latency_classonRoutingEntry) the scheduler reads to act on it.
Local peers are restarted under the same supervisor-tree "microreboot" pattern 03 β Kernel
Architecture describes; a caller simply re-opens
its Channel against a freshly minted capability, since capability tables β not IPC state β are
the sole source of truth. Calls whose Capability contract (26 β APIs) declares
idempotency are safely retried by request_id deduplication at the server; calls that are not
idempotent surface the failure to the calling Agent for an explicit retry/undo decision, per 33 β
Rollback & Recovery. Federation Gateways maintain exponential-backoff
reconnection and, for NOTIFY-class traffic only, a bounded local queue so a brief partition does
not silently drop bulk state β bounded specifically so it cannot become an unbounded memory leak
during a long partition, at which point the oldest queued notifications are dropped with the same
"coalesce, don't accumulate" logic detailed in 31 β Event System.
Local same-core call/response targets the same order of magnitude 03 β Kernel
Architecture budgets for the underlying
rendezvous (sub-microsecond to low-single-digit-microsecond), since framing and schema
encode/decode use precomputed schema descriptors rather than runtime reflection β the cost added
above the bare kernel primitive is a fixed, small constant, not a parsing pass. Zero-copy bulk
transfer is bounded by memory bandwidth, not payload size, because only the RegionDescriptor β
not the Semantic Object blob itself β crosses the synchronous path; this is what keeps
large-document Capability invocations inside 04 β Scheduler's interactive
latency budget instead of scaling with file size. Remote-route latency is dominated by network RTT,
not framework overhead: a same-LAN federated call is budgeted in the low single-digit
milliseconds, an order of magnitude above the local path, which is why 21 β Distributed
Execution's placement decisions treat "local vs. federated" as a
real cost, not a free abstraction, even though the calling code is oblivious to it. Concrete
targets are tracked against 36 β Performance Benchmarks.
Schema-based binary framing vs. a self-describing format (JSON/CBOR). Hyperion accepts the
engineering cost of schema distribution and versioning β every SchemaId must be resolvable by
both ends, coordinated with 26 β APIs contracts and versioned like 29 β Database
Schema migrations β in exchange for encode/decode costs that don't scale
with reflection, which the performance budget above requires.
Transparent location independence vs. explicit locality awareness. Making local and federated
calls look identical to the caller serves the Golden Rule
(01 Β§2) by letting an Agent developer, and the
OS's own placement logic, ignore locality β but it means a naive Capability author could
unknowingly write a hot loop of calls that happen to resolve remotely. Hyperion resolves this by
exposing an optional latency_class hint on RoutingEntry (Β§Data Structures) that
performance-sensitive Capabilities may query without breaking the default transparency for
everyone else.
Capability-gated discovery vs. legitimate service browsing. Denying discovery by default (Β§Architecture) means there is no "list nearby printers" call to reach for; Hyperion instead models a browsable scope as its own capability-scoped directory object, so browsing is itself an audited grant rather than a carved-out exception to the discovery-denial rule.
The frame parser is fuzzed continuously (malformed headers, truncated payloads, capability
substitution inside encoded fields) independently of the kernel's own IPC surface testing (03
Β§Testing Strategy), since it is new attack surface this document introduces. Zero-copy region
lifetime is checked with property tests asserting no receiver can observe a region after its
capability's generation has been bumped (use-after-revoke). Chaos tests kill a peer mid-call and
mid-notify and assert the documented Failure Modes, not hangs. A conformance suite runs the
identical Capability-contract test corpus over a loopback local route and a real (or emulated)
federated route and asserts byte-for-byte schema equivalence β this is the actual test of the
transparency guarantee, not just a unit test of ipc_call. Latency regression tests run
continuously against the budgets in 36 β Performance Benchmarks,
and security tests specifically attempt token forgery and replay across both local and remote
routes, feeding results to 17 β Threat Model.
Next: 31 β Event System.