# mgf-hrb — Design Decisions (ADR catalog)

> **Purpose.** The authoritative record of every load-bearing design
> decision in `mgf-hrb`, with rationale, status, and the source citation
> back into the design documents.
>
> **How to read.** Each `D-NNN` is an accepted decision. The design docs
> under [`hrb-design/`](hrb-design/) carry the *narrative* for each
> decision; this catalog carries the *index* with one paragraph of
> rationale each, so a reviewer can audit "what was decided and why"
> without re-reading the spine.
>
> **How to add.** New decisions append here with the next `D-NNN`. If
> they supersede an earlier decision, mark the earlier one **Superseded**
> and link forward. If they resolve a `FEEDBACK.md` paper, cross-link
> in both directions.

Status legend: **Accepted** — in force. **Superseded** — replaced by a
later `D-NNN` (noted inline). **Revisit** — accepted but flagged for
re-evaluation before v1.0.

---

## §1. Foundations

### D-001 — The five-level priority order

**Status:** Accepted · **Source:** `complete-design.md` §1.1

Every conflict resolves in the fixed order **Reliability · Performance ·
Fidelity · Flexibility · Simplicity**. Reliability and performance rank
*above* flexibility and simplicity — deliberately, because the system is
meant to be the standard userspace path to hardware. A slower-but-correct
path beats a faster-but-fallible one; a more complex design beats a
simpler-but-lying one. Every conscious decline of a SOLID principle in
the design points back to this order.

### D-002 — Two resource families with disjoint contracts

**Status:** Accepted · **Source:** `complete-design.md` §2.1, deepened in `mgf-hrb-family-b-deepening.md`

Hardware splits into **Family A — Claimable** (discrete: PCIe function,
USB interface, GPU, NIC) and **Family B — Apportionable** (continuous:
CPU shares, memory, NUMA, thermal). They share a *namespace* (the URN
tree) but **not** a contract: Family A has `claim`/`release` and a
claim-mode lattice; Family B has `reserve`/`adjust` and a
reservation-strength axis. Merging them into one `Resource` type with a
flag would push the split into every consumer and lose SRP at the model
layer.

### D-003 — Dependencies point only toward stability and abstraction

**Status:** Accepted · **Source:** `complete-design.md` §1.3

`mgf-hrb-model` depends on nothing. Abstractions (`mgf-hrb-kabi`,
capability/transport traits) depend only on the vocabulary. Concrete
implementations (`mgf-hrb-linux`, the socket transport, per-bus workers)
are leaves nothing above depends on. **No Linux noun may appear above
`mgf-hrb-kabi`** — lint-enforced. This is the mechanical form of
DIP + OCP and the reason a future-kernel port adds a leaf rather than
rewriting the world.

### D-004 — Zig below the socket, Python above

**Status:** Accepted · **Source:** `complete-design.md` (every Part's "Language" line)

Below the socket: enforcement, hardware, the lease engine, the hot data
plane — Zig, because reliability and performance are non-negotiable
there. Above the socket: SDK ergonomics, policy, tools — Python, because
that's where ergonomics matter and where change is frequent. The socket
is the one boundary where *four* splits coincide: language, privilege,
meaning vs. mechanism, and temperature (cold control vs. hot data). That
coincidence is the sign the boundary is in the right place.

### D-005 — Socket as the no-FFI client boundary

**Status:** Accepted · **Source:** `complete-design.md` §8.1, §5.1

Python never links Zig. The SDK speaks bytes on a Unix socket
(SOCK_SEQPACKET + SCM_RIGHTS) and serializes to/from the typed wire
format generated from the Zig model. No `cffi`, no shared library, no
shared memory across a language ABI. Memory ownership never crosses the
language boundary; errors cross as typed status codes that become Python
exceptions in the SDK. The mixed-language split costs *zero* FFI
complexity — a dividend that falls out of the transport choice made for
performance reasons.

---

## §2. The model & fidelity

### D-006 — `kind` is an open registry, not a closed enum

**Status:** Accepted · **Source:** `complete-design.md` §2.5

Adding a new hardware kind (GPU, NVMe, sensor bus) is *additive* — a new
`KindDescriptor` registered in the registry. The model, the core, the
facade — none change. This is OCP at the type layer; the set of
representable hardware is open while the code that manipulates it is
closed.

### D-007 — Completeness via typed ops *or* a raw channel — never "unreachable"

**Status:** Accepted · **Source:** `complete-design.md` §2.6, §3.8 (G1)

Every `kind` declares either a typed op for an operation OR a raw
channel through which it is reachable. There is no third category of
"unreachable." A `kind` that could have an unreachable capability fails
review. The raw channel is the safety net that lets the system be
*complete* on day one with few typed ops, and typed ops can be promoted
from hot raw uses over time — without ever having been incomplete.

### D-008 — Per-field fidelity tags (`live` / `cached` / `inferred` / `unknown`)

**Status:** Accepted · **Source:** `complete-design.md` §2.8 (G2)

Every descriptor carries per-field trustworthiness. A field marked
`unknown` is the system refusing to lie. `cached` is bound to an
invalidation event, so cache cannot be read stale. **An accurate
"I don't know" outranks a fast wrong answer** (priority order, applied
to the boundary between what we know and what we guess).

### D-009 — `Quarantined` is a first-class state (added by Part 12)

**Status:** Accepted · **Source:** `complete-design.md` §2.7 (the `quarantined` variant); `mgf-hrb-survivability-review.md` §2.4

A resource whose state is *uncertain* — a reset that timed out, a
fault that may have left it dirty, found bound-but-unclaimed after a
worker restart — goes to `Quarantined{reason, since}`. Never granted,
recovered only via verified reset, reported truthfully as
unavailable-with-reason. This single addition closes the
"after a timeout/lie, then what?" gap on the downward boundary, and is
the analog of how the lease engine handles the upward boundary.

### D-010 — URN stability ladder (topological / intrinsic / synthetic-pinned)

**Status:** Accepted · **Source:** `complete-design.md` §2.4

The descriptor carries both the URN and an `identity_class` saying which
rung the stability sits on. Honesty about identity stability is itself a
fidelity guarantee — we never imply more stability than the hardware
provides. (USB devices' `(bus, port_chain)` is **topological**; their
`serial_number` is **intrinsic** *when present*; the runtime
re-enumeration question is solved by an identity-continuity comparator
— see `mgf-hrb-usb-worker.md`.)

---

## §3. The arbitration core

### D-011 — Lease, never bare lock

**Status:** Accepted · **Source:** `complete-design.md` §3.2 (G3)

Every grant of access is a lease bound to liveness. A lease exists only
while its holder is provably alive; instant connection death reclaims
the lease and safe-resets the resource. Locks leak on crash; leases
cannot. Ghost ownership is structurally impossible (not "cleaned up
after the fact"). This is reliability by construction.

### D-012 — Acquire hardware *before* committing the lease

**Status:** Accepted · **Source:** `complete-design.md` §3.4

The grant sequence reserves table capacity, *then* touches hardware,
*then* commits the lease via an infallible append. If hardware-acquire
fails, no lease is committed — the ownership table can never claim a
device the backend doesn't hold. We pay a tiny latency cost (acquire
before commit) to never lie. Priority order applied: reliability >
performance, explicitly.

### D-013 — Single-writer per subtree, lock-free reads

**Status:** Accepted · **Source:** `complete-design.md` §3.9

The ownership table is guarded by a single-writer discipline per
subtree, not one global lock. Claims on `hw:/pci/**` and `hw:/usb/**`
proceed in parallel because they touch disjoint partitions. Reads
(observe/inspect/list) are lock-free — readers never block writers and
never block each other. The guard is held only for table mutation
(microseconds), never across hardware I/O (milliseconds).

### D-014 — Core is mechanism; policy is meaning

**Status:** Accepted · **Source:** `complete-design.md` §3.1, §8.4

The core knows *how* to revoke a lease; `mgf-hrb-policy` decides
*whether*. The core enforces the policy's decision; it does not choose
it. The mechanism/meaning split aligns with the Zig/Python split: the
opinion-laden, frequently-changing part lives where it's easy to change
(Python); the must-never-break part lives where it's hard to break
(Zig).

---

## §4. Capabilities & security

### D-015 — Capabilities, not identities

**Status:** Accepted · **Source:** `complete-design.md` §4.1

Authority is an unforgeable, specific, attenuable, revocable grant — not
a role or a uid. A capability names *what may be done to which scope*
and is checkable by following one chain to one audited root. The shift
from *who* to *what-may-be-done* is the whole security philosophy, and
it's exactly what the future capability-based kernel will be built on.

### D-016 — Rights segregated to match the claim lattice and ISP

**Status:** Accepted · **Source:** `complete-design.md` §4.3

Rights are `{observe, claim_shared, claim_exclusive, steal, reserve,
raw, grant}` — not a single "access" bit. Most importantly, **`raw` is
its own right**: controlling a device (claim) is not the same authority
as poking its registers directly. The split lets policy hand out the
safe 90% freely and gate the dangerous 10% tightly.

### D-017 — Attenuation only ever shrinks

**Status:** Accepted · **Source:** `complete-design.md` §4.4

A child capability can only narrow its parent's scope, drop rights, or
add constraints — never widen. The invariant is checkable by following
lineage. Least-privilege becomes the *easy* path, not the
disciplined-effort path: you delegate exactly what's needed because
that's what attenuation naturally produces.

### D-018 — One audited root capability, kernel-issued on the future OS

**Status:** Accepted · **Source:** `complete-design.md` §4.8

Every capability descends from one root held by a tiny audited
trust-anchor component. The chain has exactly one source; auditing
"can X do Y?" is following one chain. On the future OS, the kernel
*is* the trust anchor and the bootstrap problem dissolves into the
kernel's init.

### D-019 — Reference-handle (fd-backed) capabilities by default

**Status:** Accepted · **Source:** `complete-design.md` §4.7

The capability is an opaque handle the broker owns; the client holds an
fd that *references* it. Possession is proof; tampering is impossible
because there is nothing meaningful to tamper with on the client side.
Cryptographic capabilities are reserved for cases where capabilities
must travel beyond a single trust domain. Hot grant path stays
crypto-free.

---

## §5. Runtime & transport

### D-020 — Three transport planes: control / data / direct

**Status:** Accepted · **Source:** `complete-design.md` §5.1

Cold control: Unix SOCK_SEQPACKET + SCM_RIGHTS. Hot data: lock-free SPSC
shared-memory ring. Hottest use: the passed fd itself, broker absent
from the use path (G4). Each transport is matched to its frequency; the
broker mediates the *grant*, not the *use*. The three-plane split is
what makes "blazing performance" a binary layout rather than a slogan.

### D-021 — SOCK_SEQPACKET, not STREAM or DGRAM

**Status:** Accepted · **Source:** `complete-design.md` §5.2

Message boundaries + reliable, ordered, connection-oriented delivery +
SCM_RIGHTS for capability/fd transfer. Connection death is the primary
liveness signal — the kernel tells us, no polling. Linux's awkward way
of expressing *ordered message-passing with capability transfer*; on
the future kernel this becomes *the* IPC primitive.

### D-022 — Lock-free SPSC ring with cache-line separated head/tail

**Status:** Accepted · **Source:** `complete-design.md` §5.3

The data-plane ABI: producer writes `head`, consumer writes `tail`, on
separate cache lines to avoid false sharing. One atomic load + one
atomic store + zero syscalls + zero allocations per item in steady
state. Bench: ~822M items/sec on two real threads. Fidelity-honest under
overrun: a dropped region is signaled by a `seq` discontinuity plus an
`overrun` event — we never silently lose.

### D-023 — Two-signal liveness: connection-death + heartbeat

**Status:** Accepted · **Source:** `complete-design.md` §5.5

Connection-death is the strong, instant, kernel-sourced signal for
client *crash*. Heartbeat is the backstop for *hang* (client alive but
wedged). Together they make "provably alive" actually provable. On the
future kernel, lease ownership is a process property and the heartbeat
backstop is mostly retired (Feature 2 in `kernel-design-brief.md`).

### D-024 — Crash-only: nothing authoritative lives only in volatile memory

**Status:** Accepted · **Source:** `complete-design.md` §3.7, §5.6, §7.4

Every component is built to be killed and resurrected at any instant.
Soft state lives in private memory; hard state is reconstructable from
authoritative sources (the kernel for what hardware exists/is acquired,
the live connection set for who's holding what). A restarted worker
re-derives truth, never trusts lost in-memory state, quarantines
anything uncertain. The reliability gradient: use-of-already-owned-hardware
survives everything short of hardware failure.

---

## §6. The kernel seam

### D-025 — Nine abstract operations as the seam contract

**Status:** Accepted · **Source:** `complete-design.md` §6.1, §6.2

`enumerate`, `query_topology`, `watch`, `acquire`, `release`, `reset`,
`map_region`, `raw_channel`, `enforce_cap?`. Operations, not mechanisms.
No Linux noun crosses upward. The seam is narrow on purpose — easy to
implement a second time (the future kernel), easy to prove correct.

### D-026 — `enforce_cap` is nullable; capability enforcement may be in-kernel

**Status:** Accepted · **Source:** `complete-design.md` §6.2

The hook is `null` on Linux (the kernel can't enforce our capabilities,
so userspace does). On the future kernel, the hook is implemented and
capability enforcement moves into the kernel — strictly stronger
enforcement, same contract. Same nullable-default pattern as
"Unsupported" elsewhere: the contract is complete; an implementation
may not yet satisfy all of it, and says so honestly.

### D-027 — Substitutability is *tested*, not trusted

**Status:** Accepted · **Source:** `complete-design.md` §6.3, §6.4

LSP for the seam is a written behavioral contract — pre/postconditions,
failure semantics — and a conformance suite runnable against any
backend. The suite runs against `mgf-hrb-linux`, a deterministic fake,
and (when built) the future `mgf-hrb-youros`. When it goes green
against the future kernel, the entire userspace lifts over unchanged.

### D-028 — Compile-time backend selection, no runtime pluggability

**Status:** Accepted · **Source:** `complete-design.md` §6.6

You build for one kernel; the backend is chosen at build time. Runtime
auto-detection / plugin loading adds failure modes and attack surface
for a flexibility nobody needs. OCP is satisfied by "add a backend
crate and rebuild," not by runtime polymorphism. A conscious decline of
the OCP-via-polymorphism pattern in favor of reliability + performance.

### D-029 — Deadline on every seam operation (added by Part 12)

**Status:** Accepted · **Source:** `mgf-hrb-survivability-review.md` §2.2; `kabi.zig` survivability comment block

Every operation that can touch hardware must complete, error, or be
abandonable within a caller-supplied deadline. `Err.Timeout` is a typed
outcome; a timed-out resource transitions to `Quarantined`. Closes the
"frozen device hangs the broker" gap categorically rather than
case-by-case. On the future kernel this is a native primitive (Feature 9
in `kernel-design-brief.md`).

---

## §7. Process model

### D-030 — Per-bus worker processes behind one facade

**Status:** Accepted · **Source:** `complete-design.md` §7.1, §7.3

Facade routes by URN scope and supervises; it owns no hardware and no
ownership table. Each worker owns one bus subtree (`hw:/pci/**`,
`hw:/usb/**`) — its own core, its own kabi backend, its own privileged
helper. Workers share nothing mutable; a wedged USB worker can't crash
PCIe arbitration. The cost of multiple processes is paid openly for
failure isolation.

### D-031 — Privileged helper as a separate process, hard boundary

**Status:** Accepted · **Source:** `mgf-hrb-privileged-core-hardening.md`; revises `complete-design.md` §7.5

The "tiny privileged core" is a *separate process per worker* (Option
B), not an in-process seccomp thread (Option A). The unprivileged
worker (parser, lease engine, cap verification) and the privileged
helper (holds the elevated `/dev/vfio` fd, executes typed kabi ops)
share *no* memory. A memory-safety exploit in the parser cannot reach
the privileged fd. The cost is one IPC hop, only on the *control* path
— never the use path. On the future kernel, this collapses back to a
single process with thread-capabilities (Feature 7 in
`kernel-design-brief.md`).

### D-032 — Workers seeded with attenuated authority

**Status:** Accepted · **Source:** `complete-design.md` §7.6

At startup the trust anchor attenuates the root capability per worker —
the PCIe worker physically cannot issue authority over USB resources
because its seed capability doesn't reach there. Capability attenuation
+ process isolation are independent containment mechanisms; an attacker
must defeat both to cross a bus boundary.

### D-033 — Re-derive on restart, do not persist (added by Part 12)

**Status:** Accepted · **Source:** `complete-design.md` §3.7, §7.2; `mgf-hrb-survivability-review.md` §4.3, §4.5

The respawned worker re-enumerates the kernel + re-establishes leases
from surviving client connections. The reconstructed table is the
*intersection* of what the hardware says is bound and what live clients
can prove they hold. Anything bound but unclaimed is **quarantined**.
This makes worker restart crash-consistent: post-restart truth is
provably correct, derived from two authoritative sources. Persisting
would risk persisting *corruption*.

---

## §8. Client surface (Python SDK)

### D-034 — Role-interfaces decomposed by ISP

**Status:** Accepted · **Source:** `complete-design.md` §8.2

`Observer` → `Claimant` → `RawAccessor` (Family A); `Reserver`
(Family B). A reporter granted only `observe` is handed an `Observer`
and *literally cannot call* `claim` — the type-shape and the capability
agree. Defense in depth at the API surface: compile-time shape +
runtime capability.

### D-035 — Single-source type generation across the language boundary

**Status:** Accepted · **Source:** `complete-design.md` §8.5

Python mirrors of model types are *generated* from the canonical Zig
definitions, never hand-maintained. Drift becomes impossible: one
definition, two projections. Same applies to the wire format — serialise
(Python) and deserialise (Zig) cannot disagree about layout. Fidelity
doctrine applied to the language boundary.

### D-036 — `Quarantined{reason, since}` as a first-class resource state

**Status:** Accepted · **Source:** `mgf-hrb-survivability-review.md` §2.4 / §6.2; `complete-design.md` §2.7.1 (folded from Part 12 on 2026-05-24)

A device whose condition is no longer known to be safe enters
`Quarantined` rather than collapsing to `free` (would risk leaking
prior-tenant state) or `faulted` (too strong; device may recover).
Triggers: timed-out backend op (D-029), reset-succeeded-but-verification-
failed (G2 honesty), revoke-tear-down pending clean-verification,
backend-acquired-but-no-surviving-client after worker restart.
Quarantine is never granted, reported truthfully (G2), recovered only
via a verified clean reset (escalating reset / cool-down /
operator alert — meaning lives in `mgf-hrb-policy`). This is the
downward-boundary analog of how the lease engine handles the upward
boundary: every state is accounted for, including "we don't trust
this device right now."

### D-037 — `revoke(token, reason)` tears down the IOMMU/mapping below the fd

**Status:** Accepted · **Source:** `mgf-hrb-survivability-review.md` §3.4 / §6.2; `complete-design.md` §3.5 / §6.2 / §6.3 (folded from Part 12 on 2026-05-24)

Adds `revoke` as a required seam op. Implementation tears down the
IOMMU mapping / unmaps the region rather than racing to close the
holder's fd: the fd stays valid (no use-after-revoke window the broker
must chase), and access *through* the fd faults instantly because the
mapping is gone. Deadline-bounded and post-condition-verified. After
`revoke`, the resource transitions to `Quarantined` (D-036) until a
verified clean reset moves it back to `free`. This is the single op
that reconciles G4 (broker absent from the use path) with S1/S3
(instant revocation) and doubles as the preemption primitive (§3.5).
On Linux: implemented through the privileged helper (D-031). On the
future kernel: collapses to a capability-revocation primitive
(kernel-feature 4 family).

---

## §9. Open questions deferred for measurement

Recorded here so they're visible in the catalog rather than hidden in
the docs. Each is design-stable but parameter-undecided.

### Q-1 — RCU vs. seqlock for ownership-table reads

**Status:** Revisit · **Source:** `complete-design.md` §3.9, §9.7 #2

The read path is lock-free; the *primitive* (RCU-style vs. seqlock) is
decided by benchmark when the perf pass demands it. Not blocking
correctness; benchmark first.

### Q-2 — Ring slot sizing (fixed vs. size-classed)

**Status:** Revisit · **Source:** `complete-design.md` §9.7 #1

Tune against real event-rate measurements. Fixed slot is the default;
size-classed if a future workload demands it.

### Q-3 — Capability representation default

**Status:** Revisit · **Source:** `complete-design.md` §9.7 #3

Reference-handle (default) is settled for Linux (D-019). Confirm the
crypto form's exact scheme only when distribution is real.

### Q-4 — `mgf-hrb-cpu` reservation enable trigger

**Status:** Revisit · **Source:** `mgf-hrb-family-b-deepening.md` §7

Report-only first (built); reservation enabled when the
capacity-invariant enforcement engine is hardened to lease-engine
reliability standards. Not before.

---

## Index by source

| Document | Decisions |
|---|---|
| `mgf-hrb-complete-design.md` Part 1 | D-001..D-003 |
| `mgf-hrb-complete-design.md` Part 2 | D-006..D-010 |
| `mgf-hrb-complete-design.md` Part 3 | D-011..D-014 |
| `mgf-hrb-complete-design.md` Part 4 | D-015..D-019 |
| `mgf-hrb-complete-design.md` Part 5 | D-020..D-024 |
| `mgf-hrb-complete-design.md` Part 6 | D-025..D-028 |
| `mgf-hrb-complete-design.md` Part 7 | D-030, D-032 |
| `mgf-hrb-complete-design.md` Part 8 | D-034, D-035 |
| `mgf-hrb-complete-design.md` (cross-part) | D-004, D-005 |
| `mgf-hrb-survivability-review.md` | D-009 (cross), D-029, D-033 (cross), D-036, D-037 |
| `mgf-hrb-privileged-core-hardening.md` | D-031 |

---

## See also

- [INDEX.md](INDEX.md) — project entry point.
- [FEEDBACK.md](FEEDBACK.md) — the design-conversation log; decisions here resolve papers there.
- [`hrb-design/`](hrb-design/) — the narrative each decision came from.
