ADR and RFC index¶
Every architecture decision record (docs/adr/) and spec-change proposal (docs/spec/rfcs/) with its status and supersession links. The page is generated from the status key under each record’s title, and CI fails when it drifts. To change a row, edit the record’s key and run python3 tools/gen_record_index.py.
RFCs are change proposals and history, not the standard. The normative specification is Protocol v1 and the annexes its §3 incorporates; an accepted RFC records why a clause reads as it does, and the clause itself lives in the specification. Where the two differ, the specification wins. ADRs carry the rationale behind the reference implementation and are not normative either.
Statuses: draft, proposed, in-comment, accepted, superseded, rejected, withdrawn. A record marked (part) still stands except for the section the other record replaced; read both.
Architecture decision records¶
Number |
Title |
Status |
Superseded by |
Supersedes |
|---|---|---|---|---|
Extract the reference implementation from the origin firmware’s |
accepted |
|||
Versioning: integer protocol version, decoupled release semver, no per-frame version field |
accepted |
|||
Retire type code 0x05 (LIST); nesting is opt.PL=1 on a purpose-specific type byte |
accepted |
|||
CRC lives in the optional append-only trailer (opt.CR), CRC-32C default |
accepted |
|||
Length is fixed-width LE selected by opt.LL (u16 / u32), capped at u32 |
accepted |
|||
The API is read / write / await + a field-write control surface — no connect/disconnect/subscribe |
accepted |
RFC-0030 (part) |
||
Normative wire format lives in reference/01 + 05, incorporated by reference from the spec |
accepted |
|||
Schema-driven array indexing: array-ness is an L4 schema property, not a wire type or |
accepted |
|||
Built-in error model: a |
accepted |
|||
The protocol error namespace is closed: applications signal failure as data, not as protocol errors |
accepted |
|||
Address-shift totality is opt-in: tail-slice loss is not guaranteed-detectable |
accepted |
|||
Memory binding is a modular spectrum; libtracer is a transparent byte router |
accepted |
|||
Protocol-v1 scope boundaries: no in-band capability negotiation; the module ABI is implementation-defined |
accepted |
|||
ROUTER cycle termination is guaranteed by |
superseded |
|||
The reference graph runtime reads/writes the last-known-value lock-free and bounds in-process dispatch cycles with a depth cap |
accepted |
ADR-0051 (part) |
||
The L0/L1 memory substrate is a CPU-mediated zero-copy scatter-gather router: namespaces mirror the layer model and templates never cross the seam |
accepted |
ADR-0047 (part) |
||
Vertex creation is an in-band, ACL-gated field-write; controllers are created from a device-known catalog and wired by a separate binding step |
accepted |
ADR-0059 (part) |
||
Access control is authorization over a pluggable subject-token; ACL-lists and capabilities are one model, not rivals |
accepted |
|||
|
accepted |
|||
Access control uses NFSv4-style ACEs with inheritance; |
accepted |
|||
The |
accepted |
ADR-0059 (part) |
||
Transport framing modes: full-TLV, header-elided (transport-native addressing), and advertise+id-match — chosen by the adapter, uniform to the bridge |
accepted |
|||
ROS 2 integration is an RMW implementation ( |
accepted |
|||
|
accepted |
|||
End-to-end zero-copy ROS 2 ( |
accepted |
|||
Subscription is consumer-initiated (a client-write into the producer’s |
accepted |
|||
A transport — and each connection within it — is a first-class |
accepted |
ADR-0059 (part) |
||
Each language gets a native core; consistency is enforced by shared conformance vectors, not by a shared C core via FFI |
accepted |
|||
WebSocket is the origin-firmware/board-to-board reliable transport now; QUIC is deferred as a per-link, gateway-and-up upgrade |
accepted |
|||
CAN transport: a dynamic identity↔path map held inside |
accepted |
|||
Direct browser-to-robot binding (rmw_tracer + browser node) is a target use case; WebTransport is its low-latency browser-facing stream transport |
accepted |
|||
Continuous cross-core performance + conformance matrix: ranged over many axes, on vector data, baseline-tracked, auto-published |
accepted |
|||
npm: ship the TypeScript side as a workspace monorepo — one cross-validated core package, per-transport subpackages, and per-layer slicing via subpath exports (not many packages) |
accepted |
|||
TypeScript client SDK: ship a conservative, vector-pinned payload-builder + frame-I/O client; defer the path-addressed request envelope until the spec pins it |
proposed |
|||
Implementing RFC-0004 (remote operation addressing): |
accepted |
|||
The |
superseded |
|||
The net side-channels ( |
accepted |
|||
The net-plane performance model: two-plane forwarding (stateless full-route vs. label-compacted), a per-connection pooled substrate, and a typed buffer-lifetime seam — with two corrections to ADR-0037 |
accepted |
ADR-0040 (part) |
ADR-0037 (part) |
|
Transparent PMR: the node draws every non-hot-path allocation from an injected |
accepted |
|||
The net plane is explicit-source-routed only: |
accepted |
|||
The terminus reads a flat arena tree, not |
accepted |
|||
The refcounted receiver seam: transports MAY hand up owning frames ( |
accepted |
ADR-0047 (part) |
||
QUIC + WebTransport arrive as an OPTIONAL module ( |
accepted |
|||
Transport-peer enumeration is stateless and synthesized from live traffic; separate paths stay separate paths; matching device identities across paths is client-side logic, never core |
accepted |
|||
Authentication is in-graph vertex operations over the existing subject seam; the identity roadmap is per-hop ed25519 raw-key TOFU plus Noise link encryption; X.509 PKI and end-to-end multi-hop identity are rejected |
accepted |
ADR-0086 (part) |
||
Firmware/OTA-class bulk transfer is ordinary auth-gated chunked writes to an app-defined vertex — no raw transport side-channels |
accepted |
|||
Compile-time dispatch where identity is per-target and the path is hot; runtime dispatch where identity is dynamic or the call is wiring-frequency |
accepted |
|||
One wire-grammar core behind a chunk-cursor: decode is rope-aware, sinks stay distinct, and the cast contract is the validating decode |
accepted |
|||
|
accepted |
|||
ACL evaluation is a pure per-target policy over typed ACEs, with the effective-ACE merge cached graph-side and invalidated by generation |
accepted |
|||
Delivery terminates at the target: no re-dispatch, no dispatch-depth cap, no termination machinery — propagation past a target is the target’s logic |
accepted |
|||
Materializing a rope-delivered frame: the decode sink node type |
accepted |
|||
Lazy rope-backed decode view: |
accepted |
|||
A parse-once |
accepted |
|||
Rope-native reply and control egress: retire the |
accepted |
|||
Opaque |
accepted |
|||
Graph-as-Composite: a parent/children vertex tree replaces the flat full-key map |
accepted |
|||
Vertex-extension storage classes: borrowed app-field declarations and a co-occurrence group-split of |
accepted |
|||
Creation and removal are writes to a creator endpoint vertex, not fields on the parent |
accepted |
|||
The last write-path heap allocation becomes poolable: the LKV copy-store draws its owned |
accepted |
|||
Per-module mount routing: routing-address |
accepted |
|||
Resolve once, then dereference: a label binding holds the resolved target — a generation-stamped |
accepted |
|||
The connection table is lock-free to read and mutex-serialized to write: an append-only chunked list, plus one control-plane lock |
accepted |
|||
The LKV publish takes no lock when nobody is awaiting, and the slot itself becomes lock-free |
accepted |
|||
Failable allocation gets its own seam: |
accepted |
ADR-0039 (part) |
||
An element write is a single-attempt CAS that answers |
accepted |
|||
A bounded seam recycles through segregated exact-size classes, and scales by giving each owner its own source rather than by locking a shared one |
accepted |
|||
Build configuration is plain C++: one config header, no macros |
accepted |
ADR-0070 (part) |
||
The LKV slot is a compile-time policy, and the host slot reclaims with hazard pointers |
accepted |
|||
Configuration is a named traits type, bound once — not a template parameter |
accepted |
ADR-0068 (part) |
||
The host transport is a separate translation unit with a shared-nothing epoll model |
accepted |
|||
One reclamation domain: graph-owned, backend-injected, type-erased |
superseded |
|||
Naming authority: the application mints, one predicate gates every boundary |
accepted |
|||
The terminus reply egress is its own injected backend |
accepted |
|||
A vertex’s edges are published, and the fan-out reads them under an edge pin |
accepted |
|||
External subscription mutations are observable, at the admission door |
accepted |
|||
The CAN advertise carries a producer generation, and reassembly is keyed by it — not by the recurring base endpoint |
accepted |
|||
ACL-cache coherence is a published-generation stamp, not a dirty flag |
accepted |
|||
Allocation-store composition defaults to per-plane (MID), injected per target |
accepted |
|||
Reclamation of a user-code seam is a build-time-closed, per-target policy |
accepted |
|||
Pre-sink ingress is held in the transport’s native flow-control window or dropped with a named counter — never parked inside the library |
accepted |
|||
The auth subject and |
accepted |
|||
One allocation seam: every core allocation draws from one injected block source, placed by one module |
accepted |
ADR-0039 (part) |
||
A remote AWAIT completes from a one-shot receiver-side waiter charged to the receiving link, and never holds that link’s receive context |
superseded |
|||
A link’s ingress drain is bounded by a compile-time budget, and a spent budget waits for the core’s idle task, never for a clock |
accepted |
|||
Identity is app level: the node key is the only identity the protocol knows, an optional opaque credential rides beside it, and anchored names are a verifier policy in an integration module |
accepted |
ADR-0045 (part) |
RFCs¶
Number |
Title |
Status |
Superseded by |
Supersedes |
|---|---|---|---|---|
Protocol-v1 wire-format consistency consolidation |
accepted |
|||
Protocol error model: the |
accepted |
|||
Concrete-path delivery for bridged wildcard subscriptions |
superseded |
|||
Remote operation addressing: path-as-route + the |
accepted |
|||
Subtree subscriptions: vertical bubbling, branch-write decomposition, write-creates |
accepted |
|||
Nesting depth is receiver-resource-bounded: the fixed cap of 32 is removed |
accepted |
|||
SUBSCRIBER delivery terminates at the target: no automatic re-dispatch to the target’s subscribers |
accepted |
|||
Vertex operations: |
accepted |
|||
Vertex removal and subscriber eviction |
accepted |
|||
Owner-writable application property fields: the field descriptor table, the reserved |
accepted |
|||
Node identity facet: a wire-readable, pre-auth |
accepted |
|||
Readable creatable-child-type catalog: the |
superseded |
|||
Creator endpoint: connection lifecycle and link liveness |
accepted |
|||
Composed branch read: a plain READ of a branch serves the folded POINT tree of its registered subtree |
accepted |
|||
Element addressing: |
draft |
|||
Packed path segments: a |
accepted |
|||
Path depth is bounded by bytes: the 32-segment |
superseded |
|||
A bus link’s connection NAME is not a routable next-hop (reject, never broadcast, on the request plane) |
accepted |
|||
The frame of reference of a wire SUBSCRIBER’s PATH target |
accepted |
|||
Delivery policy is per-subscription; |
accepted |
|||
The path segment cap is repriced: 32 → 255, derived from the wire’s own widths |
accepted |
|||
Bound paths: node-scoped vertex-ref source routing |
accepted |
RFC-0029 (part) |
||
Stream-class values: delivery classes over the rope primitive |
accepted |
|||
The ACE |
accepted |
|||
Label-switched path compression: minting a per-host path label across the wire |
superseded |
|||
The lean value path: one block per publish, copy-or-share by size, retention per vertex, sync as a trait |
accepted |
|||
One path primitive: the owner-issued |
accepted |
|||
The host API walks the graph: a graph-owned path object, creation refused by default, the reply as a remote write, |
accepted |
Numbering gaps¶
Number |
Why it is not issued |
|---|---|
RFC-0012 |
Used by the dtype/direction draft of PR #416, which was closed unmerged. |
RFC-0015 |
Used by PR #446, withdrawn under the type-agnosticism gate. |
Neither gap is reusable: each number carries history in a closed pull request, so reissuing it would make two different documents answer to one name. RFC-0014 was once listed as a third gap, but it was later issued as a real document. A new record takes the next number after the highest one in use.