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

ADR-0001

Extract the reference implementation from the origin firmware’s io_layer

accepted

ADR-0002

Versioning: integer protocol version, decoupled release semver, no per-frame version field

accepted

ADR-0003

Retire type code 0x05 (LIST); nesting is opt.PL=1 on a purpose-specific type byte

accepted

ADR-0004

CRC lives in the optional append-only trailer (opt.CR), CRC-32C default

accepted

ADR-0005

Length is fixed-width LE selected by opt.LL (u16 / u32), capped at u32

accepted

ADR-0006

The API is read / write / await + a field-write control surface — no connect/disconnect/subscribe

accepted

RFC-0030 (part)

ADR-0007

Normative wire format lives in reference/01 + 05, incorporated by reference from the spec

accepted

ADR-0008

Schema-driven array indexing: array-ness is an L4 schema property, not a wire type or opt bit

accepted

ADR-0009

Built-in error model: a tr:: concept namespace, registered-code-or-string identity, severity + disposition in a registry

accepted

ADR-0010

The protocol error namespace is closed: applications signal failure as data, not as protocol errors

accepted

ADR-0011

Address-shift totality is opt-in: tail-slice loss is not guaranteed-detectable

accepted

ADR-0012

Memory binding is a modular spectrum; libtracer is a transparent byte router

accepted

ADR-0013

Protocol-v1 scope boundaries: no in-band capability negotiation; the module ABI is implementation-defined

accepted

ADR-0014

ROUTER cycle termination is guaranteed by hop_count; the dedup recent-set is a bounded best-effort optimization

superseded

ADR-0040, ADR-0051

ADR-0015

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)

ADR-0016

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)

ADR-0017

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)

ADR-0018

Access control is authorization over a pluggable subject-token; ACL-lists and capabilities are one model, not rivals

accepted

ADR-0019

origin_timestamp is a per-producer monotonic (hybrid-logical-clock) value, not wall-clock, so the (origin, ts) identity survives clock divergence

accepted

ADR-0020

Access control uses NFSv4-style ACEs with inheritance; admin is precisely WRITE_ACL

accepted

ADR-0021

The : field plane is the vertex’s ioctl: an optional, protocol-defined-plus-device-private control surface on one identity

accepted

ADR-0059 (part)

ADR-0022

Transport framing modes: full-TLV, header-elided (transport-native addressing), and advertise+id-match — chosen by the adapter, uniform to the bridge

accepted

ADR-0023

ROS 2 integration is an RMW implementation (rmw_tracer), not an rclcpp bridge — topics map to paths, ROS QoS to :settings, messages stay opaque

accepted

ADR-0024

mem_cuda is a CPU-opaque value-payload backend; framing stays host-side and a TLV becomes a heterogeneous host+GPU rope

accepted

ADR-0025

End-to-end zero-copy ROS 2 (rmw_tracer): loaned POD messages over shared-memory and RDMA, and “rcl over RDMA”

accepted

ADR-0026

Subscription is consumer-initiated (a client-write into the producer’s :subscribers[]); the target stays control-passive

accepted

ADR-0027

A transport — and each connection within it — is a first-class / vertex, created and configured through the same in-band API as any other vertex

accepted

ADR-0059 (part)

ADR-0028

Each language gets a native core; consistency is enforced by shared conformance vectors, not by a shared C core via FFI

accepted

ADR-0029

WebSocket is the origin-firmware/board-to-board reliable transport now; QUIC is deferred as a per-link, gateway-and-up upgrade

accepted

ADR-0030

CAN transport: a dynamic identity↔path map held inside transport_can, a structured 29-bit ID, and advertise+id-match reassembly — no roles, self-healing

accepted

ADR-0031

Direct browser-to-robot binding (rmw_tracer + browser node) is a target use case; WebTransport is its low-latency browser-facing stream transport

accepted

ADR-0032

Continuous cross-core performance + conformance matrix: ranged over many axes, on vector data, baseline-tracked, auto-published

accepted

ADR-0033

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

ADR-0034

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

ADR-0035

Implementing RFC-0004 (remote operation addressing): FWD/FIELD in tr::wire, hop-by-hop forwarding in the router, zero-copy src accumulation, the route-handle inside the transport

accepted

ADR-0036

The bridge_t class dissolves into the connection-vertex — it is not kept as a separate user-facing abstraction

superseded

ADR-0037

ADR-0037

The net side-channels (bridge_t and fwd_router_t’s children-table) dissolve into the vertex tree — transport-vertex as composite, connection-vertex as leaf, root as terminus resolver

accepted

ADR-0038 (part), ADR-0040 (part)

ADR-0036

ADR-0038

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)

ADR-0039

Transparent PMR: the node draws every non-hot-path allocation from an injected std::pmr::memory_resource, unifying with the L0 mem_backend_t seam — and “zero-heap” means the steady-state forward hop, not init

accepted

ADR-0065 (part), ADR-0083 (part)

ADR-0040

The net plane is explicit-source-routed only: bridge_t and the ROUTER-flood mechanism are retired; 0x0D ROUTER stays a reserved-but-unimplemented wire code

accepted

ADR-0014, ADR-0037 (part), ADR-0038 (part)

ADR-0041

The terminus reads a flat arena tree, not tlv_t — wire::decode_into, the borrowed-span contract, span-aliased path_key, and trailer-sliced stores

accepted

ADR-0042

The refcounted receiver seam: transports MAY hand up owning frames (view_t), buffers come from a host-injected mem_backend_t, and big WRITE payloads may store as frame subviews

accepted

ADR-0047 (part)

ADR-0043

QUIC + WebTransport arrive as an OPTIONAL module (LIBTRACER_WITH_QUIC, msquic) — the core stays dependency-free; browsers reach the graph over WebTransport

accepted

ADR-0044

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

ADR-0045

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)

ADR-0046

Firmware/OTA-class bulk transfer is ordinary auth-gated chunked writes to an app-defined vertex — no raw transport side-channels

accepted

ADR-0047

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

ADR-0016 (part), ADR-0042 (part)

ADR-0048

One wire-grammar core behind a chunk-cursor: decode is rope-aware, sinks stay distinct, and the cast contract is the validating decode

accepted

ADR-0049

field_write is the single SUBSCRIBER admission door: sugar, wire, and firmware subscriptions take one code path with uniform gate and latch

accepted

ADR-0050

ACL evaluation is a pure per-target policy over typed ACEs, with the effective-ACE merge cached graph-side and invalidated by generation

accepted

ADR-0051

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

ADR-0014, ADR-0015 (part)

ADR-0052

Materializing a rope-delivered frame: the decode sink node type

accepted

ADR-0053

Lazy rope-backed decode view: tlv_view_t and partial-path routing

accepted

ADR-0054

A parse-once path_t constructor: retire the *path_t::parse(...) deref idiom

accepted

ADR-0055

Rope-native reply and control egress: retire the on_frame_rope flatten

accepted

ADR-0056

Opaque vertex_handle_t and an infallible register_vertex: retire the raw-pointer graph API

accepted

ADR-0057

Graph-as-Composite: a parent/children vertex tree replaces the flat full-key map

accepted

ADR-0058

Vertex-extension storage classes: borrowed app-field declarations and a co-occurrence group-split of vertex_ext_t

accepted

ADR-0059

Creation and removal are writes to a creator endpoint vertex, not fields on the parent

accepted

ADR-0017 (part), ADR-0021 (part), ADR-0027 (part), RFC-0013

ADR-0060

The last write-path heap allocation becomes poolable: the LKV copy-store draws its owned segment from a graph-injected value_backend_ (mem_backend_t)

accepted

ADR-0061

Per-module mount routing: routing-address == vertex-path, realized as a strip-K structural descent in the L5 demux over a per-module-scoped registry — refining ADR-0037/0038

accepted

ADR-0062

Resolve once, then dereference: a label binding holds the resolved target — a generation-stamped vertex_handle_t or a transport_t* — not a path and a link NAME

accepted

ADR-0063

The connection table is lock-free to read and mutex-serialized to write: an append-only chunked list, plus one control-plane lock

accepted

ADR-0064

The LKV publish takes no lock when nobody is awaiting, and the slot itself becomes lock-free

accepted

ADR-0065

Failable allocation gets its own seam: tr::mem::block_source_t, because std::pmr cannot carry a failure signal on the profile that ships

accepted

ADR-0039 (part)

ADR-0066

An element write is a single-attempt CAS that answers BACKPRESSURE, never a retry loop and never a silent overwrite

accepted

ADR-0067

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

ADR-0068

Build configuration is plain C++: one config header, no macros

accepted

ADR-0070 (part)

ADR-0069

The LKV slot is a compile-time policy, and the host slot reclaims with hazard pointers

accepted

ADR-0070

Configuration is a named traits type, bound once — not a template parameter

accepted

ADR-0068 (part)

ADR-0071

The host transport is a separate translation unit with a shared-nothing epoll model

accepted

ADR-0072

One reclamation domain: graph-owned, backend-injected, type-erased

superseded

ADR-0073

Naming authority: the application mints, one predicate gates every boundary

accepted

ADR-0074

The terminus reply egress is its own injected backend

accepted

ADR-0075

A vertex’s edges are published, and the fan-out reads them under an edge pin

accepted

ADR-0076

External subscription mutations are observable, at the admission door

accepted

ADR-0077

The CAN advertise carries a producer generation, and reassembly is keyed by it — not by the recurring base endpoint

accepted

ADR-0078

ACL-cache coherence is a published-generation stamp, not a dirty flag

accepted

ADR-0079

Allocation-store composition defaults to per-plane (MID), injected per target

accepted

ADR-0080

Reclamation of a user-code seam is a build-time-closed, per-target policy

accepted

ADR-0081

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

ADR-0082

The auth subject and peer_named are two different claims — who wrote this, versus where the peer appears in the graph — and the peer_named default stays false

accepted

ADR-0083

One allocation seam: every core allocation draws from one injected block source, placed by one module

accepted

ADR-0039 (part)

ADR-0084

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

RFC-0030

ADR-0085

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

ADR-0086

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

RFC-0001

Protocol-v1 wire-format consistency consolidation

accepted

RFC-0002

Protocol error model: the tr:: concept namespace

accepted

RFC-0003

Concrete-path delivery for bridged wildcard subscriptions

superseded

RFC-0004

Remote operation addressing: path-as-route + the FWD/FIELD frames

accepted

RFC-0029 (part), RFC-0030 (part)

RFC-0005

Subtree subscriptions: vertical bubbling, branch-write decomposition, write-creates

accepted

RFC-0006

Nesting depth is receiver-resource-bounded: the fixed cap of 32 is removed

accepted

RFC-0007

SUBSCRIBER delivery terminates at the target: no automatic re-dispatch to the target’s subscribers

accepted

RFC-0008

Vertex operations: assign and propagate; structural selective propagation; value-agnostic per-vertex delivery_mode

accepted

RFC-0009

Vertex removal and subscriber eviction

accepted

RFC-0010

Owner-writable application property fields: the field descriptor table, the reserved settings.app namespace, and owner-defined :schema

accepted

RFC-0011

Node identity facet: a wire-readable, pre-auth :identity field serving the ADR-0045 ed25519 TOFU public key at every vertex

accepted

RFC-0013

Readable creatable-child-type catalog: the :children.schema read

superseded

ADR-0059

RFC-0014

Creator endpoint: connection lifecycle and link liveness

accepted

RFC-0016

Composed branch read: a plain READ of a branch serves the folded POINT tree of its registered subtree

accepted

RFC-0017

Element addressing: [n] on the value plane, and per-element delivery

draft

RFC-0018

Packed path segments: a PATH body becomes length-prefixed records

accepted

RFC-0019

Path depth is bounded by bytes: the 32-segment PATH cap is deleted

superseded

RFC-0023

RFC-0020

A bus link’s connection NAME is not a routable next-hop (reject, never broadcast, on the request plane)

accepted

RFC-0021

The frame of reference of a wire SUBSCRIBER’s PATH target

accepted

RFC-0022

Delivery policy is per-subscription; settings_t dissolves

accepted

RFC-0023

The path segment cap is repriced: 32 → 255, derived from the wire’s own widths

accepted

RFC-0019

RFC-0024

Bound paths: node-scoped vertex-ref source routing

accepted

RFC-0029 (part)

RFC-0025

Stream-class values: delivery classes over the rope primitive

accepted

RFC-0026

The ACE access_mask canonical wire width is u32

accepted

RFC-0027

Label-switched path compression: minting a per-host path label across the wire

superseded

RFC-0029

RFC-0028

The lean value path: one block per publish, copy-or-share by size, retention per vertex, sync as a trait

accepted

RFC-0029

One path primitive: the owner-issued (index, generation) pair, carried per hop, local = forwarded

accepted

RFC-0004 (part), RFC-0024 (part), RFC-0027

RFC-0030

The host API walks the graph: a graph-owned path object, creation refused by default, the reply as a remote write, AWAIT and REPLY retired

accepted

ADR-0006 (part), ADR-0084, RFC-0004 (part)

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.