Link Contract
What Florete requires from an underlying L1/L2 medium
Draft contract
This is the requirements catalog a radio/hardware vendor needs to carry Florete links. It is being validated against ad hoc WiFi and the experiments; requirements marked TBD get numbers from there. When stable, this page is intended to graduate into a top-level vendor-facing integration section.
The full picture — how these requirements sit in the artifact chain and who consumes what — is in the Design Sketch. The catalog numbers requirements R1–R10, grouped into two contracts and their envelope:
- Data-plane link contract (R1–R7) — what the medium must provide so a link vertex can run on it. Applies to every medium.
- Ctrl-plane resource contract (R8–R9) — how the medium's resource decisions couple to the Coordinator's RRA extension. Thin for contention MACs (no scheduler to talk to, but power/channel decisions still apply), full for scheduled MACs. See Radio MACs.
- R10 — the host interface — not a third contract but the envelope: the one concrete, negotiated interface through which the medium-side obligations of both contracts are delivered.
Requirements
Data-plane link contract (R1–R7)
| # | Requirement | Consumed by | Status |
|---|---|---|---|
| R1 | Per-neighbor datagram service (point-to-point star). Bidirectional datagram delivery to each radio neighbor, individually addressable. One link vertex serves a star of pairwise links over a single medium adapter — the same pattern as C0's UDP link vertex over one socket; no per-neighbor vertices or processes. What the medium must not impose: a multipoint bus abstraction, or link-layer multi-hop forwarding (as in 802.11s, or NR sidelink's Rel-17/18 U2N/U2U relays) — multipoint and routing belong to the mesh layer. How neighbors are addressed is the identity question below. | link vertex | Mandatory |
| R2 | Bounded residual loss. QUIC congestion control reads loss as congestion, so a lossy medium must carry an ARQ below the Florete transport; residual loss, reordering, and delay variance must stay below thresholds TBD (E1, E3). The ARQ may live below R10, in the vendor's radio driver (preferred), or in the link vertex. | mesh transport (QUIC) | Mandatory; placement negotiable |
| R3 | Link-layer mutual authentication — mTLS baseline. Baseline: Florete runs its own mTLS (QUIC over the medium's ARQ-backed datagram service), so the medium owes nothing beyond R1/R2. Radio-provided link security is an optional extension: if present, it must satisfy an extension contract (to be designed) — in particular, keys must derive from Florete's X.509/SPIFFE identity framework, not form a parallel credential system. | link vertex transport | Mandatory (baseline needs no medium support); radio-security extension optional |
| R4 | MTU floor. Datagrams of at least ~1300 bytes end-to-end (QUIC Initial needs ≥1200B payload plus link overhead), or link-level fragmentation. Exact floor TBD (E2). | mesh transport | Mandatory |
| R5 | Link telemetry. Per-link observations exposed to the node: rate/capacity, quality, queue depth, loss counters. This is observed state — category 5 (Observations) in the Coordinator's state taxonomy — reported by agents as telemetry and consumed by the Coordinator's link-budget, topology, and RRA computations. The mandatory minimal set is determined by E5: top-down from those computations, bottom-up from what commodity WiFi exposes. | Coordinator (TCE/PCE/RRA), Monitoring | Mandatory; minimal set TBD (E5) |
| R6 | Neighbor discovery. Detect appearance/disappearance of radio neighbors, feeding dynamic link formation and ultimately the Portal Discover method. Scope in B2: enrolled peers only — discovery finds nodes the operator already enrolled (mTLS against operator-signed state gates every link); dynamic admission of unknown nodes is the future Introductor's job, and federation (connecting to a foreign node without admitting it) is further still. Baseline direction: discovery implemented in software over R1's datagram service (see Link identity & discovery below); medium-native discovery is an optional accelerator. | Discovery, Introductor (future) | Open design (E6) |
| R7 | Link liveness — software baseline, hardware assist optional. Florete runs its own BFD-class in-band liveness over every link regardless of the medium: radio health cannot prove the data path works (the far-end link vertex may have faulted while its radio module is fine). The medium owes nothing here; a fast hardware link-down/degradation signal is an optional extension that accelerates failover. | node fast-path | Baseline: no medium requirement; HW signal optional |
Ctrl-plane resource contract (R8–R9)
| # | Requirement | Consumed by | Status |
|---|---|---|---|
| R8 | Time synchronization. Two clock domains, never merged: the medium's slot clock (µs-class, vendor-side, scheduled MACs only) and the rete's network clock (ms-class, host-side). The medium exposes its slot clock through R10 — a frame counter and RX timestamps — and accepts slow-path sync provisioning (time sources, activation epochs); host time never disciplines slot phase. Design: Time Synchronization. | Time service, scheduled MACs | Conditional (scheduled MACs); design sketched, numbers with a vendor integration |
| R9 | Resource-allocation interface — local fast-path, Coordinator-hostable slow path. Every MAC must accept the RRA's semi-persistent resource decisions through R10's control path. For contention MACs that is the thin form: apply settings — TX power caps, channel, duty cycle. Scheduled MACs additionally expose their allocator interface (grants, slot maps, timescales), split per the timescale hierarchy: the fast path (per-slot selection) must run locally in the radio driver/module, choosing among semi-persistently provisioned options — no fast-timescale dependency on any remote controller; the slow path (provisioning those options) must be hostable by the rete's Coordinator — logically centralized, but relocatable and partition-tolerant. What fails the contract: a MAC that pins scheduling authority to fixed infrastructure at per-slot timescale, so that losing the controller stops the medium (the LTE eNB/UE asymmetry). See Radio MACs. | Coordinator (RRA), node fast-path | Mandatory — thin (contention) / full (scheduled) |
R10 — the host interface (the envelope)
R10 is the documented, stable host-side interface — usable from embedded Linux — through which the medium-side obligations of R1–R9 are delivered:
- Data path: carries R1's per-neighbor datagram service (R2 and R4 are that service's properties).
- Control path: carries telemetry (R5), discovery primitives (R6), and resource commands with timing (R8–R9).
WiFi reference: UDP sockets (data) + nl80211 (control). A product's NMS/management plane (SNMP, web UI, CLI) is not an R10 control path: R5 telemetry and R8–R9 commands must be machine-consumable at ctrl timescale through the negotiated interface — NMS access may at most serve bootstrap and validation (the WiFi analog: nl80211, not the router's web interface). The kernel/userspace split of the radio driver, FPGA offload, and userspace fragmentation/ARQ are the vendor's choice as long as the interface holds. The concrete definition is negotiated per vendor; Florete proposes a reference shape that minimizes medium-adapter work (open question below). Status: mandatory — R10 is the surface the vendor and the Florete project actually negotiate; everything above it is Florete-side, everything below it vendor-side.
The interface floor: the vendor owns the fast-path MAC
R10 has a hard floor, set by a division of labor rather than preference: the timing-critical fast-path MAC is unconditionally on the vendor side of the interface. That fast path is medium-access arbitration (slot timing for scheduled MACs; carrier-sense and backoff for contention) together with any sub-millisecond link-layer / HARQ retransmit — work with µs–sub-ms deadlines that belongs in hardware/firmware (often an FPGA), where Radio MACs already places it. Florete's medium adapter is ordinary userspace software on commodity boards; it runs no per-slot loop and reconstructs no medium access.
Everything above that line is Florete-side and non-real-time: per-neighbor addressing/demux, discovery logic, telemetry, applying slow-path RRA — and the upper MAC, including coarse (ms-scale) ARQ where the medium's residual loss needs trimming. R2's placement stays negotiable only within this rule: a fast HARQ-class retransmit, if needed to meet R2's thresholds, is itself timing-critical and stays below the line.
So of the three host-interface shapes a modem can expose:
- PHY-only (FAPI-like) — declined. The whole per-slot MAC would fall above the interface, into software that cannot meet its deadlines. Such a radio becomes integrable only once the vendor (or a third party) adds the fast-path MAC first.
- MAC-level per-neighbor datagrams — the canonical, preferred shape: the fast path is already below the line, the adapter is thin. This is R1 directly.
- Framed broadcast modem — admissible, provided the modem still owns medium-access timing in hardware; Florete then supplies addressing and ARQ above the interface (a thicker, but still non-real-time, adapter). A modem that arbitrates nothing (pure keyed ALOHA) fails for the same reason PHY-only does.
Additional properties
- Asymmetric and unidirectional links — supported by the architecture (the vertex graph is a directed graph, not a DAG; see C1 reasoning); implementation is out of B2 scope — B2 only preserves the ability, making no design decision that would foreclose it.
- Half-duplex — expected to work within bounds being measured (E3: turnaround/epoch limits).
- Operational floor — the minimum link rate and maximum delay at which a Florete link is practically operational is TBD (E4).
- Directional/beam-steering radios — the per-neighbor pairwise model (R1) maps naturally to beams; contract evolution for beam resources is sketched in Radio MACs > Evolution.
Link identity & discovery
R1 and R6 share an underlying question: how are radio neighbors named, and how do they find each other? Open design; current sketch:
What the wire must name: the attachment point. A fully addressless medium — the link vertex just emits mesh-vertex QUIC into the radio and receives whatever arrives, as if into a broadcast — is conceptually possible but impractical: the radio driver keeps per-peer state (ARQ, TX tuning to reported SNR, scheduled-MAC grants), so it needs a label. And the label must name the peer's network attachment point, not the peer itself: a node may attach to the same medium through two radio modules (e.g. upper- and lower-hemisphere antennas with overlap) — one mesh-vertex, two attachment points, and the radios need per-attachment state, so a label derived from the mesh-vertex alone cannot distinguish them. In Florete terms the attachment point is the link-vertex (one per medium adapter, per the one-adapter rule); in B2's degenerate single-radio case, naming the attachment point collapses to naming the peer. Conversely, links still need no wire names: parallel physical channels (beams) between the same attachment-point pair are MAC-internal, and Florete's link names live only in config and paths.
Identity & addressing — two integration options for the attachment-point label:
- Identity-derived addressing (clean-slate radios, preferred where the vendor controls the addressing design): derive the label from the link-vertex's canonical name — the
vertex/<node>/<name>SPIFFE form, which names every vertex, SVID-less for link-vertices: the label is a routing hint, never a trust source, so it needs no cryptographic backing (the mTLS SAN stays authoritative, ADR-0007). This is design-consistent — a label derived from a name in the trust domain, resolved by lookup — and it removes a parallel namespace. Note the mgmt plane already speaks in attachment points:allowed_linksnames the link-vertex on both ends of every peering, so for configured links the label is derivable from config; for discovered links, the discovery beacon carries it. - Native link addressing (e.g. 802.11 MAC addresses — note each radio module brings its own, so multi-radio nodes are handled for free): the link vertex maintains the mapping link address ↔ peer link-vertex (and its mesh-vertex). Authenticated by the mTLS handshake, the mapping is a routing cache, never a trust source. It exists for media whose addressing is already fixed.
A note on names and SVIDs: giving link-vertices canonical names does not make them principals. Names are free; an SVID is issued only where a vertex actually acts as a principal (publishes or connects in some layer) — which link-vertices don't in the standard topology. SVID-lessness is an optimization, not a rule: a link-vertex that ever uses another vertex (the non-DAG case — e.g. a unidirectional link obtaining its return channel through the mesh) becomes a principal there and gains an SVID like any other. This is now codified in Identity & Naming.
Derivation properties, and collisions. The derivation must be a cryptographic-grade hash: collision-resistant, and therefore non-invertible — the peer's name cannot be recovered from the label, so the link vertex still keeps a label ↔ peer mapping. The difference from native addressing is the mapping's nature: every entry is verifiable by re-derivation (a verified cache, filled from config for declared links and from discovery for dynamic ones — never authoritative). Provisioning is unified through R10's control path — a set_address(bytes) primitive, so radio modules ship with nothing hard-coded. Collisions: label length makes accidental collision negligible; a deliberate collision (an attacker or a malfunctioning node choosing an occupied label) cannot forge identity — the SAN stays authoritative, mTLS distinguishes the peers — but it can disrupt demultiplexing and per-attachment state, a DoS-class nuisance analogous to MAC-address spoofing. Detection is easy (two mTLS identities behind one label); the response — per-pair fallback to assigned addressing, a mapping override, re-derivation with a salt — is an open design question below.
Foundations — why a derived label is architecturally sound. The HLD already makes addressing "a private implementation detail of a particular layer": no addresses leak through Portal APIs, and for small scopes names alone suffice. In RINA terms1, what a medium needs is a point-of-attachment (PoA) label, private to its layer; the classical architecture (Saltzer2) binds name → PoA through a directory filled by enrollment — ARP-style resolution, or our static UDP links table where the operator pre-fills it. (That is why the question never surfaced before: UDP/IP arrived with an address space and directory conventions included.) Saltzer's chain — service → node → attachment point → route — maps onto Florete as workload identity → mesh-vertex → link-vertex → path, which is exactly why the label derives from the link-vertex: it is the attachment point. And the mapping recurses: a vertex's attachment points are the lower-layer vertices it uses — an interrete mesh-vertex's attachment points are the rete mesh-vertices beneath it, exactly as a rete mesh-vertex's are its link-vertices. That generalized vertex-as-attachment-point statement is now part of the HLD. Identity-derived addressing collapses the directory into a derivation function. That is legitimate here precisely because the link layer does no multi-hop routing (R1): nothing routes or aggregates on PoA labels, so they need no topological structure, and a flat label — a hash of the canonical name — serves the label's only remaining jobs, demultiplexing and per-attachment state. Where a medium brings its own address space (802.11), the directory reappears as the link vertex's mapping — Saltzer's binding done late, filled by discovery, authenticated by mTLS. Do the higher recursion boundaries need such labels too? No — see the Attachment Labels note.
Discovery. Baseline sketch — software-only, over R1:
- A node periodically beacons a connection initiation (mTLS ClientHello) on a broadcast/newcomer channel; everyone listens; initiator/responder roles alternate on a schedule — or by Coordinator decision once the node has joined the rete.
- Scheduled MACs: the same idea over a dedicated contention/newcomer slot plus an announce beacon so newcomers can find it — the beacon design (payload, who beacons, the join sequence) is elaborated in Slot Clock. Hard timing stays in hardware — the radio module only transmits software-queued payloads at the right moment and never parses mTLS; the auth logic stays in software.
- Who drives it: establishing a connection is the mesh-vertex's act — it is the principal, and its Connect through the link layer is what produces the ClientHello. The radio-specific mechanics (beacon cadence, retry and reconnect policy) should sink into the link vertex, so the mesh-vertex sees only plain connect/accept. The underlying machinery — connection attempts, disconnect detection, reconnects — enters with the mesh-vertex connection service in C1; where it lives (mesh- vs. link-vertex) is a design question to settle there, before B2 layers radio policies on top.
- Who participates: beaconing and answering consume radio resources, so discovery participation is itself a controlled quantity — mgmt bounds declare which link-vertices may beacon/answer, ctrl decisions activate them (an RRA-adjacent decision). The far-future generalization is the distributed Coordinator placing its Introductor service on chosen nodes; the mgmt/ctrl fields give the same effect today. And to restate the B2 admission stance: discovery finds enrolled peers only — dynamic admission of unknown nodes, and federation (talking to a foreign node without admitting it), are explicitly future.
This is a research topic, not a settled mechanism: E6 prototypes the beaconing baseline on ad hoc WiFi.
Integration shape
A custom radio integrates through its host interface (R10) — never by consuming Florete APIs. FlorIO and the connection-manager adapter API are open source but internal to Florete for now: unstable and Florete-specific (see C1 Data Plane); R10 exists precisely so the vendor boundary is a plain host interface and the vendor needs to know little about Florete internals. On the Florete side, the radio is served by a link vertex, whose medium adapter — the counterpart of C0's single udp adapter — speaks R10: attachment-point addressing, discovery beaconing, applying RRA decisions, and the ARQ-bearing link protocol when the radio driver doesn't provide it (R2). Stack, bottom-up: radio module (hardware) driven by the vendor's radio driver (fast-path scheduler for scheduled MACs; exposes R10) → link vertex with its medium adapter → mesh vertex. Node-side responsibilities are detailed in Radio MACs > Node-side RRA placement.
Open questions
- The radio-security extension contract (R3): key derivation from the SPIFFE/X.509 framework, rekeying and replay semantics, acceptance criteria.
- Collision response for derived labels: per-pair fallback to assigned addressing, mapping override, or salted re-derivation — and who decides (link vertex locally vs. a ctrl decision).
- Link identity & discovery: discovery under scheduled MACs and (later) beam sweeping.
- Discovery-participation vocabulary: the mgmt bound and ctrl decision shapes for "which link-vertices beacon/answer."
- Connect/reconnect ownership — mesh-vertex calls Connect, but who runs retries and reconnect policy (link vertex, per the sketch above)? To settle in C1, when the mesh-vertex connection service lands.
- How medium-level neighbor discovery relates to the Portal Discover method and Introductor admission.
- R10 definition: negotiated per vendor, with a Florete-proposed reference shape that minimizes medium-adapter work — what is that shape (data-path framing, control-path vocabulary)? One shared vocabulary across vendors, or per-vendor? (The vocabulary layering above R10 is settled — see Design Sketch.)
Footnotes
-
John Day, Patterns in Network Architecture: A Return to Fundamentals (2008) — in RINA every layer names its members internally; an address is a layer-internal synonym used for operation inside the layer, never exposed upward. ↩
-
J. Saltzer, RFC 1498 — On the Naming and Binding of Network Destinations — the canonical chain service name → node → point of attachment → route, each step resolved by a binding that some directory must maintain. ↩