mirror of
https://github.com/ruvnet/RuView
synced 2026-08-11 20:41:44 +00:00
docs: ADR-298..317 — 20 child ADRs of the perception-substrate program
Phase 1 (certificate spine, initial implementation planned): ADR-298 calibration certificate, ADR-299 OOD KNOWN/DEGRADED/UNKNOWN gating, ADR-301 evidence engine, ADR-302 authenticated sensor identity, ADR-303 canonical spatial ontology, ADR-314 multi-domain benchmark scorecard, ADR-315 capability certificates, ADR-316 witness chain. Phase 2 (Proposed): ADR-300 ground truth, ADR-304 tracking, ADR-307 802.11bf-native, ADR-308 fusion, ADR-313 fleet, ADR-317 HAL. Phase 3 (Proposed): ADR-305 placement, ADR-306 active sensing, ADR-309 spatial memory, ADR-310 counterfactual, ADR-311 info-gain, ADR-312 RF twin. Each references ADR-297 and cross-references its dependencies; phase-1 ADRs carry implementation intent, phase-2/3 are design-intent Proposed. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
This commit is contained in:
@@ -0,0 +1,149 @@
|
|||||||
|
# ADR-298: Automatic domain calibration — signed, versioned, invalidatable room fingerprint
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: calibration, provenance, drift, evidence, honesty, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 1 of the perception-substrate program (ADR-297) and the
|
||||||
|
first brick of that program's "certificate spine" (ADR-297 phase 1). It depends
|
||||||
|
on the canonical spatial ontology (ADR-303) to name *which space* it
|
||||||
|
characterizes, on authenticated sensor identity (ADR-302) to bind a fingerprint
|
||||||
|
to *which signed device* produced it, and on the witness chain (ADR-316) to
|
||||||
|
anchor the resulting artifact. Its output is consumed directly by
|
||||||
|
out-of-distribution detection (ADR-299).
|
||||||
|
|
||||||
|
WiFi sensing is only reproducible inside the environment it was tuned for.
|
||||||
|
Multipath, furniture geometry, transceiver placement, and AP channel all shape
|
||||||
|
the CSI distribution, so a model that reads a room correctly one week can drift
|
||||||
|
silently the next. RuView already has the raw ingredients for room-aware
|
||||||
|
sensing but not a single portable, signed, expiring artifact that says "this is
|
||||||
|
the room, here is when it was measured, and here is the evidence that it is
|
||||||
|
still the same room."
|
||||||
|
|
||||||
|
Existing scaffolding to build on, not rebuild (`v2/crates/wifi-densepose-calibration`):
|
||||||
|
|
||||||
|
- `enrollment` / `anchor` — guided human anchors with an adaptive quality gate.
|
||||||
|
- `bank` / `specialist` / `runtime` — a versioned bank of small specialist
|
||||||
|
models and a confidence-gated mixture runtime (`RoomState`), including the
|
||||||
|
crate's existing honest `STALE` degradation when the ADR-135 empty-room
|
||||||
|
baseline drifts.
|
||||||
|
- `geometry` / `geometry_embedding` — transceiver-geometry record and its
|
||||||
|
fixed-length conditioning featurization (ADR-152).
|
||||||
|
|
||||||
|
What is missing is (a) an *automatic* observe-only characterization phase that
|
||||||
|
does not require a human enrollment ritual, (b) empty-vs-occupied baseline
|
||||||
|
separation as a first-class pair, (c) a signed, versioned, comparable
|
||||||
|
`CalibrationCertificate` artifact, and (d) explicit invalidation on drift rather
|
||||||
|
than a soft `STALE` flag buried in the runtime.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Keep calibration internal to the runtime (status quo).** Rejected: the
|
||||||
|
room characterization exists only as in-process state; it cannot be signed,
|
||||||
|
shipped, compared across time, or presented as evidence to ADR-299/ADR-315.
|
||||||
|
2. **Build a new calibration crate.** Rejected: `wifi-densepose-calibration`
|
||||||
|
already owns enrollment, the specialist bank, geometry embedding, and the
|
||||||
|
baseline-drift concept. A parallel crate would fork the room model.
|
||||||
|
3. **Extend `wifi-densepose-calibration` with an automatic characterization
|
||||||
|
phase and a signed certificate artifact.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Extend `v2/crates/wifi-densepose-calibration` with an `autocal` characterization
|
||||||
|
phase and a `certificate` artifact module. The target UX is:
|
||||||
|
|
||||||
|
> install → observe (~10 min) → room fingerprint → calibration certificate →
|
||||||
|
> sensing.
|
||||||
|
|
||||||
|
### 1. Automatic characterization (`autocal`)
|
||||||
|
|
||||||
|
- An observe-only pass (default ~10 minutes, configurable) that collects CSI
|
||||||
|
without requiring guided human anchors, reusing the `anchor` quality gate to
|
||||||
|
reject frames it cannot trust. It layers on the existing ADR-135 empty-room
|
||||||
|
baseline rather than replacing it.
|
||||||
|
- Produces a `RoomFingerprint`: a bounded, fixed-length statistical summary of
|
||||||
|
the room's CSI distribution (subcarrier amplitude/phase moments, multipath
|
||||||
|
structure, occupancy-band energy), plus the `geometry_embedding` when a
|
||||||
|
geometry record is present. The fingerprint is the distance-comparable object
|
||||||
|
ADR-299 measures against; its schema is versioned.
|
||||||
|
|
||||||
|
### 2. Empty / occupied baseline pair
|
||||||
|
|
||||||
|
- Characterization establishes a paired baseline: an **empty** distribution
|
||||||
|
(no occupant motion) and an **occupied** distribution (motion present),
|
||||||
|
separated by the existing occupancy signal rather than a manual label. Both
|
||||||
|
are stored on the fingerprint so downstream OOD gating can distinguish "the
|
||||||
|
empty room changed" (furniture/geometry drift) from "occupancy statistics
|
||||||
|
changed" (different subject dynamics).
|
||||||
|
|
||||||
|
### 3. `CalibrationCertificate` artifact
|
||||||
|
|
||||||
|
- A serializable `CalibrationCertificate` binding: the `RoomFingerprint`; a
|
||||||
|
space identifier from the ADR-303 ontology; the signing sensor identity from
|
||||||
|
ADR-302; `captured_at_unix_s`; a monotonic `version`; a schema version; the
|
||||||
|
calibration `tier`; and an `EvidenceLevel` (L0–L5, ADR-282) — an automatic
|
||||||
|
characterization on real captured CSI is at most L1/L2 and is labelled as
|
||||||
|
such, never L3+.
|
||||||
|
- The certificate is **signed** using RuField provenance/signature types
|
||||||
|
(ADR-260/262/277/279) and anchored in the witness chain (ADR-316). Signature
|
||||||
|
and witness anchoring are mandatory: an unsigned certificate is not a valid
|
||||||
|
certificate.
|
||||||
|
- Two certificates for the same space are **comparable**: `distance(a, b)`
|
||||||
|
returns a bounded fingerprint distance, which is the primitive ADR-299 uses
|
||||||
|
to gate KNOWN → DEGRADED → UNKNOWN.
|
||||||
|
|
||||||
|
### 4. Invalidation and continuous drift compensation
|
||||||
|
|
||||||
|
- A certificate carries an explicit validity policy: it is invalidated when
|
||||||
|
fingerprint distance against live traffic exceeds a threshold, when the AP
|
||||||
|
channel or transceiver geometry changes, when the signing device identity
|
||||||
|
changes, or on age expiry. Invalidation is an explicit state transition that
|
||||||
|
emits a witness record (ADR-316), not a silent `STALE` flag.
|
||||||
|
- Continuous drift compensation runs as a bounded online update of the
|
||||||
|
fingerprint within a **compatibility envelope**: small drift is absorbed and
|
||||||
|
logged; drift beyond the envelope invalidates the certificate and forces
|
||||||
|
re-characterization. Compensation never silently rewrites a signed
|
||||||
|
certificate — it produces a new version, preserving the append-only history.
|
||||||
|
|
||||||
|
### Provenance and honesty discipline
|
||||||
|
|
||||||
|
- No accuracy number is claimed by this ADR; it delivers the artifact and the
|
||||||
|
distance/invalidation machinery. Any certificate produced from generated CSI
|
||||||
|
is L0/`Synthetic` by construction; the constructor rejects labelling
|
||||||
|
synthetic characterization as measured (ADR-279 invariant 6, ADR-282 ladder).
|
||||||
|
- Certificates never leave the edge except through the governed control plane
|
||||||
|
(ADR-277); a room fingerprint is treated as potentially sensitive spatial
|
||||||
|
data, not free telemetry.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Room characterization becomes a portable, signed, versioned artifact that
|
||||||
|
ADR-299 (OOD), ADR-315 (capability certificates), and ADR-314 (benchmark)
|
||||||
|
can consume without re-deriving room state.
|
||||||
|
- The automatic observe-only path lowers deployment friction (no mandatory
|
||||||
|
enrollment ritual) but yields a weaker evidence level than guided enrollment;
|
||||||
|
the certificate states which path produced it so consumers can weight it.
|
||||||
|
- Explicit invalidation means RuView will sometimes refuse to sense a changed
|
||||||
|
room until re-characterization. That refusal is the intended honest behavior,
|
||||||
|
surfaced by ADR-299, not a regression.
|
||||||
|
- The existing enrollment/bank/runtime path is preserved; `autocal` is an
|
||||||
|
additional entry point that produces the same `RoomFingerprint` object the
|
||||||
|
guided path can also emit.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test -p wifi-densepose-calibration` — fingerprint determinism from
|
||||||
|
fixed synthetic CSI; empty/occupied separation on synthetic occupancy;
|
||||||
|
certificate signing/verification round-trip and tamper rejection;
|
||||||
|
`distance()` monotonicity on progressively perturbed fixtures; invalidation
|
||||||
|
transitions (channel change, geometry change, age, drift-envelope breach)
|
||||||
|
each emit the expected witness record; constructor rejects synthetic→measured
|
||||||
|
mislabeling.
|
||||||
|
- Cross-ADR: an ADR-299 test consumes a certificate and asserts the gating
|
||||||
|
state transitions on a drifted fingerprint.
|
||||||
|
- Real-silicon characterization (ESP32 capture over a real 10-minute window)
|
||||||
|
remains a follow-up requiring hardware evidence per CLAUDE.md; a successful
|
||||||
|
build or synthetic run is not hardware evidence.
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# ADR-299: Out-of-distribution detection — KNOWN / DEGRADED / UNKNOWN gating
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: ood, calibration, uncertainty, quality, evidence, honesty, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 2 of the perception-substrate program (ADR-297) and part
|
||||||
|
of the phase-1 certificate spine. It sits directly downstream of automatic
|
||||||
|
domain calibration (ADR-298): the `CalibrationCertificate` and its
|
||||||
|
`RoomFingerprint` are the reference distribution this ADR measures against. It
|
||||||
|
reuses fusion-layer quality scoring (ADR-137) as one of its inputs and feeds
|
||||||
|
its state into the evidence engine (ADR-301) and capability certificates
|
||||||
|
(ADR-315).
|
||||||
|
|
||||||
|
The central unsolved problem of WiFi sensing is cross-domain generalization: a
|
||||||
|
model trained (or calibrated) in one room degrades unpredictably in another, or
|
||||||
|
in the same room after furniture moves, the AP changes channel, or the radio
|
||||||
|
hardware is swapped. A model that keeps returning confident classifications
|
||||||
|
under these conditions is the single most misleading failure mode in the field,
|
||||||
|
and it is the failure the strategic assessment (ADR-297) named explicitly.
|
||||||
|
Confidence alone is insufficient: a softmax head is perfectly capable of being
|
||||||
|
confidently wrong on out-of-distribution input. RuView must be able to say
|
||||||
|
"I do not recognize this situation" instead of guessing.
|
||||||
|
|
||||||
|
Today RuView has partial signals but no unified gate:
|
||||||
|
|
||||||
|
- ADR-298 produces a comparable `RoomFingerprint` and a `distance()` metric.
|
||||||
|
- ADR-137 `QualityScore` carries fusion coherence, evidence references, and
|
||||||
|
contradiction flags per fused frame.
|
||||||
|
- Model heads emit confidence/uncertainty, but nothing combines domain
|
||||||
|
distance, signal quality, calibration compatibility, and uncertainty into a
|
||||||
|
single decision, and nothing forces a model to stop emitting confident labels
|
||||||
|
when it leaves its calibrated domain.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Threshold on model confidence alone.** Rejected: confidently-wrong OOD
|
||||||
|
predictions are exactly the failure mode; confidence is necessary but not
|
||||||
|
sufficient.
|
||||||
|
2. **A per-model bespoke OOD check inside each task head.** Rejected:
|
||||||
|
duplicates logic, cannot be audited uniformly, and does not compose with the
|
||||||
|
calibration certificate or the evidence engine.
|
||||||
|
3. **A shared OOD gate that every inference passes through, fusing four signals
|
||||||
|
against the ADR-298 certificate.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Add an out-of-distribution gate — implemented in a shared crate consumed by the
|
||||||
|
task-head runtime (`wifi-densepose-calibration::runtime` and the model serving
|
||||||
|
path) — that attaches a `DomainState` to **every** inference.
|
||||||
|
|
||||||
|
### 1. Four inputs, one decision
|
||||||
|
|
||||||
|
Each inference carries four measured quantities:
|
||||||
|
|
||||||
|
1. **Domain distance** — fingerprint distance (ADR-298 `distance()`) between
|
||||||
|
live traffic and the active `CalibrationCertificate`, split into the
|
||||||
|
empty-baseline and occupied-baseline components so geometry drift and
|
||||||
|
occupancy-statistics drift are distinguishable.
|
||||||
|
2. **Signal quality** — reuse the ADR-137 quality scoring signals (fusion
|
||||||
|
coherence, contradiction flags) plus per-frame SNR/validity.
|
||||||
|
3. **Calibration compatibility** — is a valid, non-invalidated certificate
|
||||||
|
present for this space (ADR-303) and this signed device (ADR-302)? An
|
||||||
|
expired, invalidated, or device-mismatched certificate is itself a
|
||||||
|
compatibility failure.
|
||||||
|
4. **Uncertainty** — the model head's own predictive uncertainty.
|
||||||
|
|
||||||
|
### 2. State machine: KNOWN → DEGRADED → UNKNOWN
|
||||||
|
|
||||||
|
- **KNOWN** — domain distance within the certificate's compatibility envelope,
|
||||||
|
quality above threshold, certificate valid and compatible, uncertainty low.
|
||||||
|
Confident classifications are returned.
|
||||||
|
- **DEGRADED** — one or more signals crossed a soft threshold (e.g. moderate
|
||||||
|
fingerprint drift within the envelope, elevated uncertainty, a tolerated
|
||||||
|
ADR-137 contradiction flag). Classifications are returned but flagged
|
||||||
|
degraded with the specific reason; downstream consumers must treat them as
|
||||||
|
lower-evidence.
|
||||||
|
- **UNKNOWN** — the room changed materially (empty-baseline drift beyond the
|
||||||
|
envelope, AP channel change, transceiver-geometry change, hardware/device
|
||||||
|
change, or an invalidated/absent certificate). RuView **stops returning
|
||||||
|
confident classifications** and returns UNKNOWN with the triggering cause.
|
||||||
|
This is the required behavior, not an error.
|
||||||
|
|
||||||
|
State transitions are hysteretic (separate enter/exit thresholds) so the gate
|
||||||
|
does not flap on noise. The state, the four input values, and the triggering
|
||||||
|
cause are all reported — never a bare label.
|
||||||
|
|
||||||
|
### 3. Certificate-bound, honest by construction
|
||||||
|
|
||||||
|
- The gate is meaningless without a certificate: with no valid ADR-298
|
||||||
|
certificate for the current space/device, the default state is UNKNOWN, not
|
||||||
|
KNOWN. Absence of evidence is treated as absence of capability.
|
||||||
|
- The `DomainState` and its inputs are emitted to the evidence engine
|
||||||
|
(ADR-301) as part of every inference record, and are an input to the ADR-315
|
||||||
|
capability certificate (a model's capability is bounded by the domain it can
|
||||||
|
hold KNOWN in).
|
||||||
|
- No accuracy number is claimed here; the ADR delivers the gating machinery.
|
||||||
|
The gate's own thresholds are calibration parameters, reported with each
|
||||||
|
decision.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView gains a uniform, auditable answer to "should I trust this inference?"
|
||||||
|
that combines domain, quality, calibration, and uncertainty rather than
|
||||||
|
confidence alone.
|
||||||
|
- Deployments will see more DEGRADED/UNKNOWN results than a
|
||||||
|
confidence-only system, especially right after a room changes. That increase
|
||||||
|
is the product working: it is the difference between honest RF perception and
|
||||||
|
confidently-wrong output.
|
||||||
|
- Every task head that opts into the substrate must route through the gate;
|
||||||
|
heads that bypass it cannot claim a KNOWN state or earn an ADR-315
|
||||||
|
certificate.
|
||||||
|
- The gate couples model serving to the presence of a live calibration
|
||||||
|
certificate, making ADR-298 a hard dependency of confident inference — the
|
||||||
|
intended coupling.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test` on the OOD crate — state-machine transitions on synthetic
|
||||||
|
fixtures: in-envelope drift stays KNOWN; soft-threshold breach → DEGRADED;
|
||||||
|
empty-baseline drift beyond envelope, channel change, geometry change,
|
||||||
|
device mismatch, and invalidated/absent certificate each → UNKNOWN;
|
||||||
|
hysteresis prevents flapping under injected noise; missing certificate
|
||||||
|
defaults to UNKNOWN.
|
||||||
|
- Cross-ADR: consumes an ADR-298 certificate and asserts a drifted fingerprint
|
||||||
|
drives the expected transition; asserts the `DomainState` is present on every
|
||||||
|
emitted inference record consumed by ADR-301.
|
||||||
|
- No confident classification is emitted in the UNKNOWN state in any test —
|
||||||
|
enforced as an assertion, not a convention.
|
||||||
|
- Real-silicon OOD behavior (moving furniture / changing AP channel on a live
|
||||||
|
ESP32 capture and observing the transition) remains a follow-up requiring
|
||||||
|
hardware evidence per CLAUDE.md.
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
# ADR-300: Ground-truth synchronization — reference sensors as a formal validation plane
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 2)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: ground-truth, validation, fusion, evidence, benchmark, honesty, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 3 of the perception-substrate program (ADR-297), authored
|
||||||
|
as **Proposed** in phase 2: it is design intent and a validation plan, not
|
||||||
|
implemented by the phase-1 swarm. It sits on top of the phase-1 certificate
|
||||||
|
spine and feeds the evidence engine (ADR-301) and the real benchmark service
|
||||||
|
(ADR-314). It generalizes the vitals ground-truth rig (ADR-290) from a single
|
||||||
|
measurand to a modality-agnostic plane.
|
||||||
|
|
||||||
|
RuView's evidence discipline (CLAUDE.md; ADR-282 ladder) requires MEASURED
|
||||||
|
accuracy claims to be backed by an independent reference. ADR-290 built exactly
|
||||||
|
this for vitals: reference-series ingest, time alignment (cross-correlation
|
||||||
|
lag + optional clock-drift fit), and agreement statistics (MAE/RMSE/bias/
|
||||||
|
Bland–Altman/within-tolerance), with an `EvidenceGrade` that is only
|
||||||
|
constructible as `Measured` when a real reference, non-zero paired samples,
|
||||||
|
minimum coverage, and a reproducer are present. That machinery is measurand- and
|
||||||
|
device-shaped: it knows about heart rate and breathing rate.
|
||||||
|
|
||||||
|
The substrate needs the same discipline for *every* phenomenon RuView senses —
|
||||||
|
presence, count, localization, pose, posture, activity — and for reference
|
||||||
|
sources of many modalities (cameras, mmWave, pressure mats, wearables, pulse
|
||||||
|
oximeters, microphones, manual labels). The critical design decision is that
|
||||||
|
these reference sensors form a **validation plane**, not additional inference
|
||||||
|
inputs.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Fuse reference sensors as extra inference inputs.** Rejected on principle:
|
||||||
|
folding cameras/mmWave into the estimator would make RuView's RF claims
|
||||||
|
unfalsifiable — the reference would be training the thing it is meant to
|
||||||
|
check, and a camera-fed result is no longer a camera-free RF result. It
|
||||||
|
would also violate the ADR-282 layering (RuView is probabilistic
|
||||||
|
exteroception, never ground truth) and the honesty rule against presenting
|
||||||
|
fused-with-camera output as WiFi sensing.
|
||||||
|
2. **One-off rigs per measurand (extend ADR-290 ad hoc each time).** Rejected:
|
||||||
|
duplicates alignment/agreement code per phenomenon and never yields a shared
|
||||||
|
validation surface for the benchmark.
|
||||||
|
3. **A first-class, modality-agnostic `GroundTruth` API that is strictly a
|
||||||
|
validation plane.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Introduce a `GroundTruth` API — a modality-agnostic validation plane that
|
||||||
|
compares RF inference against independent observation and never feeds it.
|
||||||
|
|
||||||
|
### 1. Modality-agnostic reference ingest
|
||||||
|
|
||||||
|
- A `ReferenceObservation` generalizing ADR-290's `ReferenceSeries`: a
|
||||||
|
timestamped, typed observation of a `Phenomenon` (presence, count,
|
||||||
|
localization, pose keypoints, posture, activity, heart rate, breathing rate)
|
||||||
|
from a `ReferenceModality` (camera, mmWave, pressure, wearable, pulse
|
||||||
|
oximeter, microphone, manual label), with device/source metadata and the
|
||||||
|
measurement principle recorded.
|
||||||
|
- Untrusted reference files are validated at the boundary (row-numbered
|
||||||
|
rejections, non-monotonic timestamps are errors), reusing ADR-290's ingest
|
||||||
|
discipline. Camera/mmWave references arrive as exported label/keypoint
|
||||||
|
streams, not live model feeds.
|
||||||
|
|
||||||
|
### 2. Synchronization
|
||||||
|
|
||||||
|
- Generalize ADR-290's time alignment (bounded-lag normalized cross-correlation
|
||||||
|
+ optional linear clock-drift fit) to arbitrary measurands on a common
|
||||||
|
resampled grid, with no interpolation across gaps beyond a configurable
|
||||||
|
limit. Alignment parameters are always reported, never silently applied.
|
||||||
|
- Spatial synchronization where relevant: reference observations are expressed
|
||||||
|
in the ADR-303 spatial ontology so an RF localization/pose result and a
|
||||||
|
camera/mmWave observation are compared in one coordinate frame.
|
||||||
|
|
||||||
|
### 3. Agreement as validation, not fusion
|
||||||
|
|
||||||
|
- A modality-appropriate `AgreementReport` per phenomenon: continuous
|
||||||
|
measurands reuse ADR-290's MAE/RMSE/bias/Bland–Altman/within-tolerance;
|
||||||
|
categorical/detection phenomena (presence, activity) report confusion-matrix
|
||||||
|
metrics; spatial phenomena report localization error percentiles and pose
|
||||||
|
PCK **with the mandatory mean-pose baseline and leakage-free split**
|
||||||
|
(CLAUDE.md; ADR-288).
|
||||||
|
- Session scope is mandatory metadata (subject count, motion state, LOS/NLOS/
|
||||||
|
through-wall, distance band) — a report without scope cannot be constructed,
|
||||||
|
as in ADR-290.
|
||||||
|
|
||||||
|
### 4. Evidence and isolation guarantees
|
||||||
|
|
||||||
|
- The plane is one-directional by type: the inference path has no read access
|
||||||
|
to `GroundTruth` at runtime. A build/test-time isolation check (and the type
|
||||||
|
boundary) prevents a reference observation from becoming an estimator input.
|
||||||
|
- Reports carry an `EvidenceLevel` (ADR-282) and an `EvidenceGrade`
|
||||||
|
constructible as `Measured` only with a real reference, paired samples,
|
||||||
|
coverage, and a reproducer (ADR-290 rule). Reports feed the ADR-301 evidence
|
||||||
|
engine and are the substrate ADR-314 scores against.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Every phenomenon RuView senses gets the same MEASURED-vs-independent-observer
|
||||||
|
discipline vitals already has, in one shared surface.
|
||||||
|
- Keeping references strictly as validation preserves the falsifiability and
|
||||||
|
the camera-free identity of RF results; it costs the (tempting) accuracy a
|
||||||
|
camera-fused estimator would show, which is the correct trade.
|
||||||
|
- Reference capture is an operational burden (a camera/mmWave rig per validated
|
||||||
|
session); acceptable because it is a validation activity, not a runtime
|
||||||
|
requirement, and it is what turns CLAIMED into MEASURED.
|
||||||
|
- Because this is Proposed (phase 2), the API shape may be revised once the
|
||||||
|
phase-1 spine (ADR-298/299/301/303) lands and the benchmark (ADR-314)
|
||||||
|
exercises it.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests (planned): modality-agnostic ingest rejection cases; alignment
|
||||||
|
recovery of known synthetic offsets/drifts across measurands; agreement math
|
||||||
|
per phenomenon against hand-computed fixtures; pose PCK path requires a
|
||||||
|
mean-pose baseline and rejects leaky splits; evidence-grade constructibility;
|
||||||
|
the isolation check fails a build that wires a reference into the inference
|
||||||
|
path.
|
||||||
|
- Cross-ADR: an ADR-314 benchmark scenario consumes `GroundTruth` reports as
|
||||||
|
its scored reference; ADR-301 ingests the agreement reports as evidence
|
||||||
|
records.
|
||||||
|
- Real-session validation (RF capture synchronized with a real camera/mmWave/
|
||||||
|
pressure/wearable reference) is the phase-2 exit and requires hardware
|
||||||
|
evidence per CLAUDE.md; a synthetic run is not hardware evidence.
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
# ADR-301: Evidence engine — MLflow for physical sensing
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: evidence, provenance, ledger, accuracy, drift, benchmark, honesty, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 4 of the perception-substrate program (ADR-297) and a
|
||||||
|
central pillar of the phase-1 certificate spine. It consumes the domain state
|
||||||
|
from out-of-distribution detection (ADR-299) and the calibration age from the
|
||||||
|
calibration certificate (ADR-298), it is the store that capability certificates
|
||||||
|
(ADR-315) are minted from, and it is the accuracy source the real benchmark
|
||||||
|
service (ADR-314) reads. In phase 2 it ingests agreement reports from the
|
||||||
|
ground-truth plane (ADR-300).
|
||||||
|
|
||||||
|
The strategic assessment (ADR-297) judged this primitive **more commercially
|
||||||
|
important than another pose architecture**: what unblocks OEM and integrator
|
||||||
|
conversations is not a higher headline number but a defensible, auditable record
|
||||||
|
of how a model actually performs, per room, per device, per subject, over time.
|
||||||
|
MLflow made ML experiments trackable; physical sensing needs the equivalent for
|
||||||
|
deployed accuracy, drift, and evidence level — an append-only ledger, not a
|
||||||
|
dashboard that overwrites yesterday's number.
|
||||||
|
|
||||||
|
RuView already has the constituent evidence types; what is missing is the ledger
|
||||||
|
that unifies them per deployment context:
|
||||||
|
|
||||||
|
- RuField provenance/signature types (ADR-260/262/277/279) — the signed,
|
||||||
|
provenance-bearing record types to reuse rather than reinvent.
|
||||||
|
- The AetherArena witness-ledger pattern (ADR-149) — an append-only,
|
||||||
|
witness-anchored ledger of scored results, the structural template here.
|
||||||
|
- `frame::EvidenceLevel` L0–L5 (ADR-282) — the mandatory evidence tag every
|
||||||
|
record carries.
|
||||||
|
- ADR-299 `DomainState`, ADR-137 `QualityScore`, ADR-298 certificate version
|
||||||
|
and age — the per-inference signals to accumulate.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Log accuracy to flat files / metrics dashboards.** Rejected: mutable,
|
||||||
|
un-signed, un-scoped, and not comparable over time — the exact gap.
|
||||||
|
2. **Reuse a general experiment tracker (MLflow itself).** Rejected: it is
|
||||||
|
experiment-time, not deployment-time; it has no notion of room/device/
|
||||||
|
subject context, calibration age, evidence level, or signed provenance, and
|
||||||
|
it would add an external service dependency contrary to the substrate's
|
||||||
|
edge-first, dependency-light direction.
|
||||||
|
3. **A native append-only evidence ledger reusing RuField record types and the
|
||||||
|
AetherArena ledger pattern.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Build an **evidence engine**: a per-`(room, device, subject)` append-only
|
||||||
|
accuracy ledger that every model automatically writes to.
|
||||||
|
|
||||||
|
### 1. The evidence record
|
||||||
|
|
||||||
|
- An `EvidenceRecord` keyed by context — space id (ADR-303), signed device id
|
||||||
|
(ADR-302), and subject id where consented and available — carrying: model
|
||||||
|
version; calibration certificate version and **age** (ADR-298); the ADR-299
|
||||||
|
`DomainState` (KNOWN/DEGRADED/UNKNOWN) and its four inputs; the ADR-137
|
||||||
|
quality signals; predictive uncertainty; and, when a reference is present
|
||||||
|
(ADR-300), the agreement result (accuracy, false-positive rate). Each record
|
||||||
|
carries exactly one `EvidenceLevel` (L0–L5, ADR-282).
|
||||||
|
- Records are **append-only** and signed with RuField signature types
|
||||||
|
(ADR-260/262/277/279); the ledger is anchored in the witness chain (ADR-316),
|
||||||
|
following the AetherArena witness-ledger pattern (ADR-149). No record is ever
|
||||||
|
mutated in place — a correction is a new record.
|
||||||
|
|
||||||
|
### 2. Per-context accuracy accounting
|
||||||
|
|
||||||
|
- The engine maintains, per `(room, device, subject)` context: measured
|
||||||
|
accuracy (only where an ADR-300 reference backs it — otherwise the record is
|
||||||
|
CLAIMED/SYNTHETIC, never MEASURED), false-positive rate, drift trajectory
|
||||||
|
(fingerprint distance over time from ADR-298), the fraction of inferences in
|
||||||
|
each domain state, calibration age distribution, and model-version history.
|
||||||
|
- Aggregation is a pure function over the append-only log at a queried time —
|
||||||
|
the ledger is the source of truth; summaries are derived, never authoritative
|
||||||
|
(mirroring CLAUDE.md's "source over summaries" rule).
|
||||||
|
|
||||||
|
### 3. Honesty enforced in the record
|
||||||
|
|
||||||
|
- The engine cannot upgrade an evidence level; a level is set by the record's
|
||||||
|
provenance at write time (synthetic input → L0/`Synthetic`; no reference →
|
||||||
|
CLAIMED; reference + reproducer → MEASURED), reusing the ADR-282/ADR-288/
|
||||||
|
ADR-290 constructor discipline. A benchmark or certificate reading the ledger
|
||||||
|
gets the honest level, not an optimistic rollup.
|
||||||
|
- No benchmark numbers are invented by this ADR; it delivers the ledger and the
|
||||||
|
accounting. Empty contexts report "no evidence," which downstream (ADR-315)
|
||||||
|
must treat as no capability.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView gains a single auditable answer to "how well does this model actually
|
||||||
|
work, here, on this device, for this subject, and how fresh is the
|
||||||
|
calibration?" — the artifact OEM/integrator diligence actually asks for.
|
||||||
|
- ADR-315 capability certificates become derivable (a certificate is a signed
|
||||||
|
attestation over a slice of the ledger) and ADR-314 gains a real accuracy
|
||||||
|
source per PR instead of self-reported numbers.
|
||||||
|
- The append-only, signed design has storage and key-management cost; bounded
|
||||||
|
by per-context retention policy and by reusing the existing RuField/witness
|
||||||
|
infrastructure rather than a new store.
|
||||||
|
- Some contexts will show sparse or unflattering evidence. Surfacing that is the
|
||||||
|
point; the engine must never paper over a thin context with a global average.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test` on the evidence-engine crate — append-only invariant (no
|
||||||
|
in-place mutation; corrections are new records); per-context aggregation math
|
||||||
|
against fixtures; evidence-level is set by provenance and cannot be upgraded;
|
||||||
|
signature round-trip and tamper rejection; witness anchoring; empty-context
|
||||||
|
queries return "no evidence" not a fabricated number.
|
||||||
|
- Cross-ADR: ingests ADR-299 `DomainState` and (phase 2) ADR-300 agreement
|
||||||
|
reports; an ADR-315 test mints a certificate from a ledger slice and an
|
||||||
|
ADR-314 test reads accuracy from the ledger.
|
||||||
|
- Real-deployment evidence (a populated ledger from live ESP32 captures with
|
||||||
|
ADR-300 references) is the maturity milestone and requires hardware evidence
|
||||||
|
per CLAUDE.md; a synthetic ledger is L0 by construction.
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
# ADR-302: Authenticated sensor identity — RF chain of custody
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: security, identity, provenance, sensor-ingest, attestation, phase-1
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** (perception substrate program) and owns
|
||||||
|
primitive #5, *authenticated sensor identity*. In the ADR-297 dependency DAG it
|
||||||
|
is a spine root that, together with **ADR-303** (canonical spatial ontology),
|
||||||
|
feeds **ADR-298** (calibration certificate) and **ADR-316** (witness chain).
|
||||||
|
|
||||||
|
RuView's inference outputs are only as trustworthy as the measurements that
|
||||||
|
produced them, yet today a measurement's origin is essentially assertional. The
|
||||||
|
UDP data plane accepts frames from any reachable host: **ADR-293** shipped step
|
||||||
|
one — a loopback-default bind (`--udp-bind`) and an optional source
|
||||||
|
IP/CIDR allowlist — and explicitly deferred to a follow-up ADR "per-device
|
||||||
|
provisioned keys, MAC/AEAD, device identifiers, monotonic sequence numbers,
|
||||||
|
freshness window, and replay rejection." **This ADR is that step two.** ADR-293
|
||||||
|
correctly documented that an IP allowlist does not stop LAN spoofing; a
|
||||||
|
cryptographic device identity is what closes that gap.
|
||||||
|
|
||||||
|
Foundations already exist in the tree and must be reused rather than rebuilt:
|
||||||
|
|
||||||
|
- `wifi-densepose-rufield` provides `DeviceId`, `Signature`, `SignatureBlock`,
|
||||||
|
`FrameProvenance`, `ProvenanceClass`, and `SignatureVerifyError` — the type
|
||||||
|
vocabulary for a signed frame.
|
||||||
|
- `wifi-densepose-bfld` provides `CapabilityAttestation` and
|
||||||
|
`PrivacyAttestationProof` (BFLD attestation, ADR-141) — the device-side
|
||||||
|
attestation surface.
|
||||||
|
- **ADR-292** defines the source-provenance state machine and freshness
|
||||||
|
(`SpatialStateFreshness`); a monotonic sequence and freshness window slot
|
||||||
|
into that machine rather than duplicating it.
|
||||||
|
|
||||||
|
The gap is not new primitives but an **end-to-end chain of custody**: a frame
|
||||||
|
must be traceable as `device → signed measurement → sequence → timestamp →
|
||||||
|
calibration → inference → signed event`, with every link verified at the
|
||||||
|
ingest boundary per CLAUDE.md ("validate untrusted input at every network,
|
||||||
|
hardware, and FFI boundary; default to least authority").
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Stop at ADR-293 (bind + IP allowlist).** Rejected: ADR-293 itself names
|
||||||
|
this insufficient on a trusted LAN; any on-subnet host can still spoof a
|
||||||
|
device.
|
||||||
|
2. **TLS/DTLS transport authentication only.** Rejected: authenticates the
|
||||||
|
*channel*, not the *measurement*. It does not survive store-and-forward,
|
||||||
|
does not bind a sequence number into the signed object, and gives the
|
||||||
|
downstream evidence/witness layers nothing to re-verify offline.
|
||||||
|
3. **Per-device signing keys with a signed measurement envelope, monotonic
|
||||||
|
sequence, and freshness window, reusing the RuField/BFLD types.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Introduce an **authenticated frame envelope** carried through the sensing
|
||||||
|
server, built from existing RuField/BFLD types.
|
||||||
|
|
||||||
|
### 1. Per-device provisioned identity
|
||||||
|
|
||||||
|
- Each radio (ESP32-S3/C6 node or adapter) is provisioned with a keypair; the
|
||||||
|
device holds the private key, the server holds the enrolled public key bound
|
||||||
|
to a `DeviceId`. Provisioning is an explicit, authorized enrollment step — a
|
||||||
|
device is untrusted until an operator enrolls its public key. Private keys are
|
||||||
|
never logged or committed (CLAUDE.md credential rule); the ESP32 side follows
|
||||||
|
`firmware/esp32-csi-node` key-handling notes.
|
||||||
|
- The enrollment record binds `DeviceId → public key → capabilities`
|
||||||
|
(via `CapabilityAttestation`, ADR-141), so a device can only assert
|
||||||
|
measurements for phenomena it is attested to sense. This is what **ADR-315**
|
||||||
|
(capability certificate) later consumes.
|
||||||
|
|
||||||
|
### 2. Signed measurement envelope
|
||||||
|
|
||||||
|
- A frame on the wire becomes a `SignatureBlock` over the canonical
|
||||||
|
serialization of `{DeviceId, sequence, timestamp, measurement-hash}`. The
|
||||||
|
measurement itself (CSI/CIR payload) is covered by the hash so tampering is
|
||||||
|
detectable without embedding the whole payload twice.
|
||||||
|
- Verification uses `Signature`/`SignatureVerifyError` from
|
||||||
|
`wifi-densepose-rufield`. A frame that fails signature verification is
|
||||||
|
dropped and counted, exactly as ADR-293 drops disallowed sources — an `Err`
|
||||||
|
at the boundary, never a warning that proceeds.
|
||||||
|
|
||||||
|
### 3. Monotonic sequence + freshness (replay defense)
|
||||||
|
|
||||||
|
- Each device maintains a strictly monotonic per-device sequence number. The
|
||||||
|
server tracks the last accepted sequence per `DeviceId`; a non-increasing
|
||||||
|
sequence is rejected as a replay.
|
||||||
|
- A freshness window bounds `timestamp` against the server clock skew budget;
|
||||||
|
stale frames are rejected. This reuses ADR-292's `SpatialStateFreshness`
|
||||||
|
rather than inventing a parallel notion of staleness, and composes with
|
||||||
|
ADR-294's stale-node handling.
|
||||||
|
|
||||||
|
### 4. Chain of custody into the event
|
||||||
|
|
||||||
|
- On successful verification the frame's `FrameProvenance` records the verified
|
||||||
|
`DeviceId`, sequence, and timestamp. Calibration (ADR-298) and inference
|
||||||
|
annotate their transforms, and the emitted spatial event (ADR-303 ontology)
|
||||||
|
carries a signed provenance lineage. `ProvenanceClass` still enforces the
|
||||||
|
synthetic/measured invariant from ADR-282/ADR-279 (invariant 6): a measured
|
||||||
|
chain of custody can never be aliased to synthetic and vice-versa.
|
||||||
|
- This end-to-end signed lineage is the substrate the **ADR-316** witness chain
|
||||||
|
serializes and the **ADR-315** capability certificate points at as evidence.
|
||||||
|
|
||||||
|
### Compatibility
|
||||||
|
|
||||||
|
- The envelope is **opt-in per deployment** and negotiated at enrollment. An
|
||||||
|
un-enrolled single-node desktop deployment keeps working unauthenticated
|
||||||
|
behind ADR-293's loopback default; a routable, multi-node, or fleet
|
||||||
|
deployment (ADR-313) requires enrolled identities. The startup security log
|
||||||
|
(ADR-293) is extended to state whether frame authentication is active.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- LAN spoofing and replay — the residual risks ADR-293 named plainly — are
|
||||||
|
closed for enrolled deployments. The measurement, not merely the channel, is
|
||||||
|
authenticated, so the guarantee survives store-and-forward into the witness
|
||||||
|
chain.
|
||||||
|
- Enrollment/key-management is now an operational responsibility (provisioning,
|
||||||
|
rotation, revocation). This is documented as a deployment step; key rotation
|
||||||
|
and revocation lists are specified here but their fleet distribution is
|
||||||
|
owned by ADR-313.
|
||||||
|
- Signature verification adds per-frame CPU cost at ingest; bounded and
|
||||||
|
measured in validation below. It is a deliberate cost for a verifiable chain
|
||||||
|
of custody.
|
||||||
|
- A schema addition to the frame contract; un-enrolled deployments are
|
||||||
|
unaffected, and the migration accessor mirrors ADR-294's approach.
|
||||||
|
- **No spoof-resistance claim is MEASURED until validated on real silicon**
|
||||||
|
(CLAUDE.md hardware rule): a passing unit/integration suite demonstrates the
|
||||||
|
logic, not the fielded device path.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests (`cargo test -p wifi-densepose-sensing-server`,
|
||||||
|
`-p wifi-densepose-rufield`): valid envelope accepted; bad signature
|
||||||
|
rejected and counted; non-monotonic sequence rejected as replay; out-of-
|
||||||
|
window timestamp rejected; un-enrolled `DeviceId` rejected; measured/synthetic
|
||||||
|
provenance aliasing rejected (ADR-279 invariant 6).
|
||||||
|
- Integration test: a captured/synthesized multi-frame stream produces a
|
||||||
|
verifiable `device → … → signed event` lineage that ADR-316 can serialize and
|
||||||
|
re-verify offline.
|
||||||
|
- Benchmark (`cargo bench`): per-frame verification cost, to bound ingest
|
||||||
|
overhead.
|
||||||
|
- **Real-silicon evidence required** before any deployment-grade
|
||||||
|
authentication claim: a captured boot/runtime log from an enrolled ESP32 node
|
||||||
|
signing frames end-to-end. A successful build or simulator run is not
|
||||||
|
hardware evidence.
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
# ADR-303: Canonical spatial ontology — one Site→…→Event model for every surface
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: ontology, worldgraph, schema, mqtt, matter, rufield, phase-1
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #6, *canonical spatial
|
||||||
|
ontology*. In the ADR-297 DAG it is a spine root alongside **ADR-302**
|
||||||
|
(authenticated identity) and feeds every downstream primitive that must speak
|
||||||
|
about *where* and *what*: **ADR-298** (calibration), **ADR-304** (tracking,
|
||||||
|
consumes `Track`/`Person`), **ADR-316** (witness chain), and every external
|
||||||
|
surface named in the ADR-297 consequences (MQTT, REST, WebSocket, RuField,
|
||||||
|
Matter, agents).
|
||||||
|
|
||||||
|
RuView currently expresses "where something is" in several overlapping,
|
||||||
|
per-surface schemas: the MQTT/Home-Assistant mapper has its own node/room
|
||||||
|
shapes (**ADR-294** just introduced `NodeInference`/`RoomInference` to
|
||||||
|
disambiguate node vs. room state); the `worldgraph` crate models a spatial
|
||||||
|
graph; RuField carries `SemanticProvenance`; Matter/HomeKit has its own area
|
||||||
|
model. The same physical fact — "a person is in the kitchen" — is re-encoded
|
||||||
|
differently on each surface, and the review called for "one canonical
|
||||||
|
`NodeInference`/`RoomInference` contract" (ADR-294 consequences). Without a
|
||||||
|
single semantic model, every new surface multiplies the translation matrix and
|
||||||
|
each translation is a place where provenance and evidence level (ADR-282) can
|
||||||
|
be silently dropped.
|
||||||
|
|
||||||
|
Substantial scaffolding already exists and must be **reused/extended, not
|
||||||
|
rebuilt**. `v2/crates/worldgraph/wifi-densepose-worldgraph` already defines:
|
||||||
|
|
||||||
|
- `WorldNode` variants including `Room { area_id, name, bounds_enu, floor }`,
|
||||||
|
`Zone { parent_room, … }`, `Wall { rf_attenuation_db }`, and `Doorway`.
|
||||||
|
- `WorldEdge` variants including `Observes { quality, last_seen_unix_ms }`,
|
||||||
|
`LocatedIn { since_unix_ms }`, `AdjacentTo { via_doorway }`, and `Supports`.
|
||||||
|
- `WorldGraph`, `WorldGraphSnapshot`, `WorldId`, `SemanticProvenance`,
|
||||||
|
`PersonPosition`, and a HomeCore `area_id` linkage join key (ADR-127).
|
||||||
|
|
||||||
|
The `worldgraph` crate is therefore the natural home for the canonical model.
|
||||||
|
What is missing is (a) the full `Site → Building → Floor → Space → Zone`
|
||||||
|
containment spine above `Room`, (b) first-class `Sensor`, `Object`,
|
||||||
|
`Observation`, `Track`, and `Event` node types, (c) one canonical serialization
|
||||||
|
that every surface consumes, and (d) a documented migration path from the
|
||||||
|
existing per-surface schemas.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Leave each surface with its own schema; add adapters pairwise.** Rejected:
|
||||||
|
O(surfaces²) translations, and provenance/evidence loss at each hop.
|
||||||
|
2. **Invent a new top-level ontology crate.** Rejected: `worldgraph` already
|
||||||
|
models rooms, zones, walls, doorways, observation edges, and HomeCore
|
||||||
|
linkage; a parallel crate would fork the world model.
|
||||||
|
3. **Extend `worldgraph` into the canonical ontology and make every surface a
|
||||||
|
projection of it.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Adopt **one canonical spatial ontology**, hosted in the `worldgraph` crate,
|
||||||
|
that every RuView surface reads from and writes to.
|
||||||
|
|
||||||
|
### 1. The containment spine and entity types
|
||||||
|
|
||||||
|
Define the full node taxonomy as an extension of the existing `WorldNode`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Site ▸ Building ▸ Floor ▸ Space ▸ Zone
|
||||||
|
└─▸ { Sensor, Person, Object,
|
||||||
|
Observation, Track, Event }
|
||||||
|
```
|
||||||
|
|
||||||
|
- `Site`, `Building`, `Floor`, `Space` are new containment `WorldNode`
|
||||||
|
variants above the existing `Room` (mapped to `Space`, keeping its `area_id`
|
||||||
|
and `bounds_enu`) and `Zone`. `Wall`/`Doorway` remain as topological
|
||||||
|
elements. Containment reuses the existing `LocatedIn`/`AdjacentTo` edge
|
||||||
|
vocabulary; a new `PartOf` edge expresses the pure hierarchy
|
||||||
|
(Zone `PartOf` Space `PartOf` Floor …).
|
||||||
|
- `Sensor` is the entity **ADR-302** authenticates (`DeviceId` as its stable
|
||||||
|
identity) and **ADR-317** (HAL, phase 2) describes the hardware of. `Person`,
|
||||||
|
`Object`, `Observation`, `Track`, and `Event` are first-class nodes.
|
||||||
|
`Observes`/`LocatedIn` edges already carry quality and dwell timestamps.
|
||||||
|
- `Track` and `Person` are defined **here** as the ontology contract that
|
||||||
|
**ADR-304** (persistent tracking) produces and updates. `Observation` is what
|
||||||
|
an authenticated frame (ADR-302) becomes after calibration (ADR-298), and
|
||||||
|
`Event` is the governed output that ADR-315 certifies and ADR-316 witnesses.
|
||||||
|
|
||||||
|
### 2. Canonical serialization
|
||||||
|
|
||||||
|
- A single, versioned serialization (serde-based, stable field names) is the
|
||||||
|
one wire/at-rest representation. Every surface — MQTT/Home-Assistant, REST,
|
||||||
|
WebSocket, RuField observations, Matter/HomeKit, agent queries — is a
|
||||||
|
**projection** of this model, not an independent schema. `NodeInference` and
|
||||||
|
`RoomInference` (ADR-294) become projections of `Sensor→Observes` and the
|
||||||
|
`Space`-level fused inference respectively, so ADR-294's node/room separation
|
||||||
|
is preserved by construction rather than re-encoded per surface.
|
||||||
|
- Every node and edge carries `SemanticProvenance` and exactly one
|
||||||
|
`EvidenceLevel` (L0–L5, ADR-282 policy): the evidence ladder travels *with*
|
||||||
|
the fact across every projection, so no surface can silently upgrade or drop
|
||||||
|
it.
|
||||||
|
|
||||||
|
### 3. Migration path
|
||||||
|
|
||||||
|
- Each existing per-surface schema gets a documented, tested bidirectional
|
||||||
|
mapping to/from the canonical model, plus a migration accessor for consumers
|
||||||
|
reading the old shape (mirroring ADR-294's migration accessor). Surfaces are
|
||||||
|
cut over one at a time; a surface is "canonical" once its projection is the
|
||||||
|
only encoder it uses. Until cutover, the mapping layer is authoritative and
|
||||||
|
round-trip-tested so no fact is lost in translation.
|
||||||
|
- The `worldgraph` HomeCore `area_id` linkage (ADR-127) remains the join key
|
||||||
|
between the ontology's `Space` and external area registries.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- The translation matrix collapses from O(surfaces²) to O(surfaces): each
|
||||||
|
surface implements one projection. New surfaces (ROS 2, OpenUSD, OPC UA per
|
||||||
|
ADR-282's roadmap) plug in as additional projections.
|
||||||
|
- Provenance and evidence level are carried uniformly; a fact cannot cross a
|
||||||
|
surface boundary and lose its lineage or its L-level.
|
||||||
|
- A schema change reaching every surface; managed by the versioned
|
||||||
|
serialization and per-surface migration accessors. Single-node deployments
|
||||||
|
keep working (one `Sensor`, one `Space`).
|
||||||
|
- The ontology is a *representation*, not an inference engine: it says nothing
|
||||||
|
about *how* a `Track` or `Event` is produced — that is owned by ADR-304,
|
||||||
|
ADR-298, ADR-299, and the model layer. This ADR does not itself make any
|
||||||
|
accuracy claim to grade.
|
||||||
|
- Extending `worldgraph` grows one crate's surface rather than forking a second
|
||||||
|
world model; the geo/worldmodel sub-crates continue to build on the same node
|
||||||
|
vocabulary.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests (`cargo test -p wifi-densepose-worldgraph`): containment-spine
|
||||||
|
construction and invariants (a `Zone` is `PartOf` exactly one `Space`, a
|
||||||
|
`Space` on exactly one `Floor`, etc.); round-trip serialization of every node
|
||||||
|
and edge type; every node/edge carries exactly one `EvidenceLevel`.
|
||||||
|
- Migration tests: each per-surface schema maps to the canonical model and back
|
||||||
|
with no loss of provenance or evidence level; `NodeInference`/`RoomInference`
|
||||||
|
(ADR-294) project and re-project identically.
|
||||||
|
- Contract test: a single canonical `Event` renders correctly through the MQTT,
|
||||||
|
REST, and WebSocket projections from one source of truth.
|
||||||
|
- No accuracy numbers are claimed; this ADR delivers the shared representation
|
||||||
|
the rest of the phase-1 spine writes into.
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# ADR-304: Persistent identity & tracking — privacy-preserving probabilistic tracks
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 2)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: tracking, identity, privacy, fusion, worldgraph, phase-2
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #7, *persistent identity
|
||||||
|
& tracking*. In the ADR-297 DAG it is a phase-2 primitive sitting on the
|
||||||
|
phase-1 spine: it **consumes the ADR-303 ontology** (producing and updating the
|
||||||
|
`Track` and `Person` node types defined there), it relies on **ADR-302**
|
||||||
|
authenticated identity so that the observations it associates have a verified
|
||||||
|
origin, and its outputs are governed `Event`s that ADR-315/ADR-316 can certify
|
||||||
|
and witness.
|
||||||
|
|
||||||
|
The product need is to reason about *persistent entities* — "person_7 entered
|
||||||
|
the kitchen, then the hallway, then the bedroom" — across radios, modalities,
|
||||||
|
rooms, and time. The hard constraint is that this must happen **without
|
||||||
|
establishing civil identity**. RuView is camera-free (ADR-282), and a
|
||||||
|
persistent pseudonymous track must never become, or be joinable to, a real-
|
||||||
|
world named individual. This is a privacy property to be enforced *by
|
||||||
|
construction*, not a policy footnote.
|
||||||
|
|
||||||
|
Substantial scaffolding already exists in
|
||||||
|
`v2/crates/wifi-densepose-mat/src/tracking` and must be **reused/extended, not
|
||||||
|
rebuilt**:
|
||||||
|
|
||||||
|
- `SurvivorTracker`, `TrackedSurvivor`, `TrackId`, `TrackerConfig`,
|
||||||
|
`TrackLifecycle`, and `TrackState` — a multi-target tracker with lifecycle
|
||||||
|
(tentative/active/lost/terminal) and a `TrackId` backed by a UUID
|
||||||
|
(`as_uuid`).
|
||||||
|
- `KalmanState` with `predict`/`update`, `position`, `velocity`,
|
||||||
|
`position_uncertainty`, and `mahalanobis_distance_sq` — the motion model and
|
||||||
|
gating distance.
|
||||||
|
- `CsiFingerprint`, `DetectionObservation`, `AssociationResult`, and the
|
||||||
|
`can_reidentify`/`matches`/`mark_rescued`/`rescue` re-identification surface —
|
||||||
|
the appearance/fingerprint channel for track continuity.
|
||||||
|
|
||||||
|
What is missing is (a) continuity **across radios, modalities, and rooms** (the
|
||||||
|
tracker today reasons within a node/room context), (b) a **persistent** entity
|
||||||
|
that survives track loss and hand-off between spaces, and (c) an explicit
|
||||||
|
**privacy boundary** that guarantees no civil-identity binding.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Per-room independent trackers, no cross-room identity.** Rejected: cannot
|
||||||
|
express "person_7 moved kitchen → hallway → bedroom"; loses the entity at
|
||||||
|
every room boundary.
|
||||||
|
2. **Global identity keyed on a strong biometric fingerprint.** Rejected: a
|
||||||
|
fingerprint strong enough to re-identify across long gaps trends toward a
|
||||||
|
civil-identity-grade biometric — exactly what the privacy constraint
|
||||||
|
forbids.
|
||||||
|
3. **Probabilistic persistent tracks with bounded, decaying pseudonymous
|
||||||
|
association, built on the existing MAT tracker.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Extend `wifi-densepose-mat/tracking` into a **cross-domain persistent track
|
||||||
|
layer** that produces ADR-303 `Track`/`Person` nodes.
|
||||||
|
|
||||||
|
### 1. Persistent probabilistic entity
|
||||||
|
|
||||||
|
- A persistent entity is a pseudonymous `Person` node (ADR-303) with a stable
|
||||||
|
synthetic id (e.g. `person_7`) backed by the existing `TrackId`/UUID. It
|
||||||
|
aggregates one or more `SurvivorTracker` tracks over time and space and holds
|
||||||
|
a **probabilistic** continuity belief — association is never asserted as
|
||||||
|
certain, and every hand-off carries a confidence.
|
||||||
|
- Continuity across a track-loss gap reuses the existing re-identification
|
||||||
|
surface (`can_reidentify`, `CsiFingerprint`, `AssociationResult`), extended
|
||||||
|
with a **time- and distance-decayed** association prior so that confidence in
|
||||||
|
"same entity" falls with the size of the gap. Beyond a bounded horizon the
|
||||||
|
association is dropped and a new pseudonym is minted rather than forcing a
|
||||||
|
join — under-linking is the privacy-safe failure mode.
|
||||||
|
|
||||||
|
### 2. Cross-radio / cross-modality / cross-room continuity
|
||||||
|
|
||||||
|
- Association operates over the ADR-303 ontology graph: `Observes` edges from
|
||||||
|
multiple `Sensor`s and `AdjacentTo`/`Doorway` topology constrain plausible
|
||||||
|
hand-offs (a person can only move between adjacent spaces). The existing
|
||||||
|
`mahalanobis_distance_sq` gating extends to a fused observation across
|
||||||
|
modalities rather than a single node's detections.
|
||||||
|
- Fusion here is track-level association; the underlying multi-modality fusion
|
||||||
|
(radar/mmWave per ADR-063, multistatic per ADR-029, and real sensor fusion
|
||||||
|
per ADR-308) supplies the observations. This ADR depends on those for the raw
|
||||||
|
cross-modality evidence and does not re-implement sensor fusion.
|
||||||
|
|
||||||
|
### 3. Privacy boundary (by construction)
|
||||||
|
|
||||||
|
- **No civil-identity binding.** The persistent id is a synthetic pseudonym
|
||||||
|
with no field, edge, or join key to any name, account, phone, MAC, or other
|
||||||
|
civil identifier. The type carries no such field, so binding is impossible in
|
||||||
|
the schema, not merely discouraged.
|
||||||
|
- The `CsiFingerprint` used for re-identification is **bounded and decaying**:
|
||||||
|
it is scoped to short-horizon continuity, is not persisted as a long-term
|
||||||
|
biometric template, and expires. This keeps re-identification useful for
|
||||||
|
"same person across the hallway" while structurally unable to serve "this is
|
||||||
|
the same person who visited last month."
|
||||||
|
- Every `Track`/`Person`/`Event` produced carries `SemanticProvenance` and an
|
||||||
|
`EvidenceLevel` (ADR-282), and honors the ADR-277/ADR-280 edge governance and
|
||||||
|
ADR-141 attestation — a pseudonymous track is still governed P-class data.
|
||||||
|
Tracking accuracy is a per-domain claim to be tagged MEASURED/CLAIMED/
|
||||||
|
SYNTHETIC with a reproducer; **this ADR claims no accuracy number.**
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView can express persistent, cross-room trajectories for automation and
|
||||||
|
analytics while remaining camera-free and civil-identity-free.
|
||||||
|
- The privacy-safe failure mode is **under-linking** (mint a fresh pseudonym
|
||||||
|
when unsure), which will fragment a trajectory across long gaps or sparse
|
||||||
|
coverage. This is a deliberate trade: a fragmented pseudonym is safe, a
|
||||||
|
wrong civil-identity join is not.
|
||||||
|
- Extends an existing tracker rather than forking one; single-room single-radio
|
||||||
|
deployments keep the current behavior (one entity = one track).
|
||||||
|
- Cross-modality quality depends on ADR-308/ADR-063/ADR-029 landing; until then
|
||||||
|
continuity is WiFi-primary and its limits are stated, not hidden.
|
||||||
|
- Being phase 2, this ADR is design intent; it will be revised as the ADR-303
|
||||||
|
ontology and ADR-302 identity spine finalize.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests (`cargo test -p wifi-densepose-mat`): decayed association prior
|
||||||
|
(confidence falls with gap; drops beyond horizon → new pseudonym);
|
||||||
|
topology-constrained hand-off (no association across non-adjacent spaces);
|
||||||
|
schema check that a `Person`/`Track` carries no civil-identifier field.
|
||||||
|
- Integration test against a synthetic multi-room, multi-radio scenario:
|
||||||
|
a scripted walk kitchen → hallway → bedroom yields one persistent pseudonym
|
||||||
|
with per-hand-off confidence, and a deliberately ambiguous crossing produces
|
||||||
|
two pseudonyms rather than a false join.
|
||||||
|
- Evidence discipline: any tracking-continuity accuracy is reported only with
|
||||||
|
the ADR-288 leakage-free protocol and an evidence tag; no number is asserted
|
||||||
|
here.
|
||||||
|
- Privacy review: confirm no persisted long-term biometric template and no
|
||||||
|
civil-identity join path, as an explicit checklist item before any pilot.
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
# ADR-305: Sensor placement optimizer — floorplan + inventory → recommended positions
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 3)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: placement, planning, rf-twin, coverage, worldgraph, phase-3
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #8, *sensor placement
|
||||||
|
optimizer*. In the ADR-297 DAG it is a phase-3, research-forward primitive that
|
||||||
|
sits on top of the fused world state and is tightly coupled to **ADR-312**
|
||||||
|
(digital RF twin): the twin provides the propagation simulation this optimizer
|
||||||
|
plans against. It reads the **ADR-303** canonical ontology for the physical
|
||||||
|
scene and, after install, compares its predictions against ADR-299 observability
|
||||||
|
and the ADR-315 capability certificate.
|
||||||
|
|
||||||
|
The problem it solves is the single most common cause of a bad RuView
|
||||||
|
deployment: sensors placed by guesswork. Whether a room can be reliably sensed
|
||||||
|
depends on AP/sensor geometry relative to walls, Fresnel-zone clearance,
|
||||||
|
multipath structure, and where people actually move. Today an installer has no
|
||||||
|
principled way to answer "where do I put the two nodes I have so the kitchen is
|
||||||
|
observable?" — and no way, after install, to know whether reality matched the
|
||||||
|
plan. This is a genuine **differentiator**: it turns RuView from "sense
|
||||||
|
whatever the given placement happens to allow" into "recommend the placement
|
||||||
|
that makes the requested sensing feasible."
|
||||||
|
|
||||||
|
Relevant existing assets to build on rather than duplicate:
|
||||||
|
|
||||||
|
- The `worldgraph` crate models the physical scene the optimizer plans over:
|
||||||
|
`Room`/`Space` with `bounds_enu`, `Wall { rf_attenuation_db }` (drywall ≈ 3
|
||||||
|
dB, brick ≈ 12 dB), `Doorway`, and `Zone` — enough geometry and coarse RF
|
||||||
|
attenuation to seed a coverage model, plus `Sensor` nodes (ADR-303) for
|
||||||
|
candidate positions.
|
||||||
|
- **ADR-312** (RF twin, phase 3) is the propagation/multipath simulator; this
|
||||||
|
optimizer is a *consumer* of the twin, not a second simulator.
|
||||||
|
- **ADR-299** (OOD/observability) and **ADR-315** (capability certificate)
|
||||||
|
define what "reliably sense the requested phenomenon" means, so the optimizer
|
||||||
|
can optimize against the same observability metric the runtime later gates on.
|
||||||
|
- **ADR-029** (multistatic) and **ADR-063** (mmWave fusion) inform which link
|
||||||
|
geometries are useful for which phenomena.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Static placement guidelines in docs (e.g. "one node per room, opposite
|
||||||
|
the door").** Rejected: ignores the specific floorplan, wall materials, and
|
||||||
|
the actual hardware inventory; gives no uncertainty and no post-install
|
||||||
|
feedback.
|
||||||
|
2. **Full electromagnetic solver per site.** Rejected for the default path:
|
||||||
|
too heavy for an installer workflow and overkill relative to the coarse
|
||||||
|
`rf_attenuation_db` scene RuView actually has; reserved as an optional
|
||||||
|
high-fidelity backend inside ADR-312.
|
||||||
|
3. **A coverage optimizer that consumes the ADR-312 RF twin over the ADR-303
|
||||||
|
scene, then validates predicted vs. measured observability after install.**
|
||||||
|
Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Define a **placement optimizer** that takes a floor plan (ADR-303 scene) and a
|
||||||
|
hardware inventory and recommends sensor positions, then closes the loop after
|
||||||
|
install.
|
||||||
|
|
||||||
|
### 1. Inputs
|
||||||
|
|
||||||
|
- The ADR-303 canonical scene: `Space`/`Zone` bounds, `Wall` segments with
|
||||||
|
`rf_attenuation_db`, `Doorway` topology, and any already-placed `Sensor`
|
||||||
|
nodes.
|
||||||
|
- A hardware inventory: the count and type of available radios (ESP32-S3/C6
|
||||||
|
nodes, mmWave, adapters) with their capability envelopes (what each can
|
||||||
|
sense, per ADR-315 / ADR-317 HAL descriptors).
|
||||||
|
- A sensing objective: which phenomenon must be observable in which
|
||||||
|
`Space`/`Zone` (presence, vitals, pose), expressed against the ADR-299
|
||||||
|
observability metric.
|
||||||
|
|
||||||
|
### 2. Prediction
|
||||||
|
|
||||||
|
- For a candidate placement, query the **ADR-312 RF twin** for simulated RF
|
||||||
|
coverage: path loss through `Wall` attenuation, **Fresnel-zone clearance**
|
||||||
|
between link endpoints, and coarse **multipath** structure. From that derive
|
||||||
|
an **expected observability** and an **uncertainty** for each objective in
|
||||||
|
each space — reusing the same observability definition ADR-299 gates on so the
|
||||||
|
plan and the runtime speak one language.
|
||||||
|
- Search over candidate positions (the inventory bounds the count; the scene
|
||||||
|
bounds the geometry) to recommend the placement that maximizes objective
|
||||||
|
observability, reporting expected observability **and its uncertainty** per
|
||||||
|
space — never a single confident number for a simulated result.
|
||||||
|
|
||||||
|
### 3. Post-install loop
|
||||||
|
|
||||||
|
- After install, compare **predicted vs. measured** observability using the
|
||||||
|
ADR-299 runtime observability signal from the freshly enrolled (ADR-302),
|
||||||
|
calibrated (ADR-298) sensors. Where measurement disagrees with prediction,
|
||||||
|
recommend adjustments (move, re-aim, add a node) and feed the residual back
|
||||||
|
to improve the ADR-312 twin's scene parameters (e.g. a wall's effective
|
||||||
|
attenuation).
|
||||||
|
|
||||||
|
### Evidence discipline
|
||||||
|
|
||||||
|
- Predicted coverage is a **simulation** (evidence level L0 per ADR-282) and is
|
||||||
|
labelled `SYNTHETIC`; it is a *recommendation*, never a sensing claim.
|
||||||
|
- The predicted-vs-measured comparison is the only place a `MEASURED` statement
|
||||||
|
appears, and only with a reproducer and real-silicon observability data
|
||||||
|
(CLAUDE.md hardware rule). The optimizer never presents a simulated coverage
|
||||||
|
map as evidence that a room *is* being sensed.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Installers get a principled, floorplan-specific placement plan and, crucially,
|
||||||
|
a post-install check that says whether reality matched the plan — a
|
||||||
|
differentiating capability over guess-and-check deployment.
|
||||||
|
- Quality is bounded by the fidelity of the ADR-312 RF twin and the coarseness
|
||||||
|
of the `worldgraph` scene (2D walls, coarse attenuation). The optimizer
|
||||||
|
reports uncertainty rather than overstating a coarse model; higher fidelity
|
||||||
|
is an ADR-312 concern.
|
||||||
|
- Hard dependency on ADR-312 (twin), ADR-299 (observability metric), and
|
||||||
|
ADR-303 (scene); this ADR does not build a simulator or an observability
|
||||||
|
metric of its own.
|
||||||
|
- Being phase 3, this is design intent sitting on the fused world state; it is
|
||||||
|
expected to be revised as ADR-312 and the phase-1 spine land.
|
||||||
|
- No claim that recommended placement *guarantees* sensing — it maximizes
|
||||||
|
modelled observability subject to inventory and geometry, with explicit
|
||||||
|
uncertainty.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests: coverage/observability prediction is a deterministic function of
|
||||||
|
scene + placement + twin parameters; Fresnel-zone and wall-attenuation math
|
||||||
|
against known analytic cases; search returns the modelled-optimal placement on
|
||||||
|
small synthetic scenes.
|
||||||
|
- Integration test: on a synthetic floorplan with a known-good and a
|
||||||
|
known-bad placement, the optimizer ranks them correctly and reports higher
|
||||||
|
uncertainty for the marginal case.
|
||||||
|
- Post-install loop test: injected predicted-vs-measured disagreement produces a
|
||||||
|
sensible adjustment recommendation and a twin-parameter residual.
|
||||||
|
- Field validation (deferred, real-silicon): predicted vs. measured
|
||||||
|
observability on an instrumented real site, reported as `MEASURED` with a
|
||||||
|
reproducer. Until then all coverage output is `SYNTHETIC`/L0. No coverage or
|
||||||
|
accuracy number is asserted by this ADR.
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
# ADR-306: Active sensing — closed-loop RF experiment control
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 3)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: active-sensing, control-plane, closed-loop, information-gain, actuation, phase-3
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #9, *active sensing*. In
|
||||||
|
the ADR-297 phasing it is a phase-3 primitive that sits on top of the fused
|
||||||
|
world state produced by **ADR-308** (real sensor fusion) and is driven by the
|
||||||
|
information budget of **ADR-311** (information-gain scheduler). It is authored
|
||||||
|
as **Proposed**: design intent and validation plan, not a phase-1 build.
|
||||||
|
|
||||||
|
The default posture of every current RuView path is **passive**: RF traffic
|
||||||
|
happens for its own reasons (a device transmits, a beacon fires), RuView
|
||||||
|
observes whatever CSI/CIR arrives, and the pipeline extracts what it can from
|
||||||
|
that incidental signal. The strategic assessment behind ADR-297 named the next
|
||||||
|
step: move from *RF-happens → observe* to **RuView-controls-RF → observe the
|
||||||
|
response → optimize the next measurement**. That turns sensing into a
|
||||||
|
closed-loop experiment — the system chooses what to measure to resolve the
|
||||||
|
uncertainty it currently has, rather than accepting the measurements the
|
||||||
|
environment happens to offer.
|
||||||
|
|
||||||
|
Substantial control-plane scaffolding already exists and must be
|
||||||
|
**reused/extended, not rebuilt**:
|
||||||
|
|
||||||
|
- **ADR-280** (active sensing / programmable perception, *implemented* in
|
||||||
|
`ruview-unified/src/control.rs`) already defines the governed control surface
|
||||||
|
this ADR closes the loop over: `SensingTask` (evidence-aware, fail-closed
|
||||||
|
admission), `SensingAction` + `InformationGoal` (a deliberate act of
|
||||||
|
evidence-gathering against a stated hypothesis, bounded by a `PrivacyClass`
|
||||||
|
P0–P5 ceiling), `ActiveSensingPlanner` (age-of-information scheduler),
|
||||||
|
`CoherentSensorGroup` (coherent fusion fails closed), and `request_actuation`
|
||||||
|
→ `ActuationReceipt` for governed RIS/movable/fluid-antenna actuation.
|
||||||
|
- ADR-280 explicitly recorded that **information-gain *estimation* is not
|
||||||
|
implemented** — "the planner uses staleness heuristics, not mutual
|
||||||
|
information; RIS drivers, actual multi-AP coherence measurement, and OTFS
|
||||||
|
waveform control are hardware-dependent roadmap items." ADR-306 is the ADR
|
||||||
|
that closes exactly those gaps, in coordination with ADR-311.
|
||||||
|
|
||||||
|
The missing piece is not the actuation surface — ADR-280 built that and made it
|
||||||
|
fail closed — but the **loop**: a controller that reads the current fused-state
|
||||||
|
uncertainty, selects a *controllable measurement configuration* expected to
|
||||||
|
reduce it most, requests it through the ADR-280 governed surface, observes the
|
||||||
|
response, and updates its belief before choosing the next measurement.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Stay passive; only schedule which incidental observations to keep.** This
|
||||||
|
is roughly today's `ActiveSensingPlanner` (staleness-priority over regions).
|
||||||
|
Rejected as the endpoint: it optimizes *attention* over uncontrolled RF, not
|
||||||
|
the *measurement* itself. It remains the fallback when nothing is
|
||||||
|
controllable.
|
||||||
|
2. **Open-loop measurement scripting** (a fixed sweep of channels/bandwidths).
|
||||||
|
Rejected: a fixed sweep spends the RF/energy/privacy budget the same way
|
||||||
|
regardless of what is already known; it cannot concentrate measurement where
|
||||||
|
uncertainty actually is.
|
||||||
|
3. **Closed-loop experiment control** — read uncertainty, pick the controllable
|
||||||
|
configuration with highest expected information gain per unit cost/privacy,
|
||||||
|
actuate through the ADR-280 governed surface, observe, update, repeat.
|
||||||
|
Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Adopt **closed-loop RF experiment control** as a phase-3 controller layered on
|
||||||
|
the ADR-280 surface. RuView selects and drives the controllable degrees of
|
||||||
|
freedom of the RF measurement, then optimizes the next measurement from the
|
||||||
|
observed response.
|
||||||
|
|
||||||
|
### 1. Controllable degrees of freedom
|
||||||
|
|
||||||
|
Define an `ExperimentControl` vocabulary over the configuration axes RuView can
|
||||||
|
influence on hardware that exposes them (each axis is optional and
|
||||||
|
capability-gated by ADR-317's HAL, so an ESP32-only deployment simply has an
|
||||||
|
empty controllable set and degrades to the passive planner):
|
||||||
|
|
||||||
|
- **Channel / band** and **bandwidth** (which spectrum to probe; reuses the
|
||||||
|
ADR-289 wideband subcarrier-agnostic metadata).
|
||||||
|
- **Packet timing / cadence** (when to solicit a sounding, and at what rate).
|
||||||
|
- **Antenna / chain selection** (which subset of a distributed aperture to
|
||||||
|
activate — bounded by the ADR-280 `CoherentSensorGroup` compatibility proof).
|
||||||
|
- **Beam / RIS configuration** (which rooms and people become observable —
|
||||||
|
governed exactly as ADR-280 §6 requires, via `request_actuation` and an
|
||||||
|
`ActuationReceipt`).
|
||||||
|
- **802.11bf measurement parameters** (TB/non-TB, reporting config) once
|
||||||
|
ADR-307 exposes standardized sensing as a native measurement type.
|
||||||
|
|
||||||
|
### 2. The loop
|
||||||
|
|
||||||
|
```
|
||||||
|
fused-state uncertainty (ADR-308)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
info-gain ranking of ExperimentControl options (ADR-311)
|
||||||
|
│ select argmax E[ΔI] / (cost, energy, privacy ceiling)
|
||||||
|
▼
|
||||||
|
governed request (ADR-280 admit_task / request_actuation, fail-closed)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
observe response → update belief (ADR-308) → repeat
|
||||||
|
```
|
||||||
|
|
||||||
|
The controller never bypasses the ADR-280 admission and actuation gates: every
|
||||||
|
solicited measurement is a `SensingTask`/`SensingAction`, every environment
|
||||||
|
change is an `ActuationReceipt`, and every step composes with the ADR-277
|
||||||
|
policy engine. Information gain is what **ADR-311** supplies (the mutual-
|
||||||
|
information estimate ADR-280 deferred); ADR-306 owns the *control loop* that
|
||||||
|
consumes that estimate and drives the hardware.
|
||||||
|
|
||||||
|
### 3. Governance and honesty boundary
|
||||||
|
|
||||||
|
- Actuation and solicitation stay fail-closed and privacy-ceilinged: a
|
||||||
|
closed-loop experiment cannot widen the P0–P5 ceiling of the task it serves,
|
||||||
|
and cannot steer a beam into a zone that does not grant the purpose (ADR-280
|
||||||
|
`actuation_requires_policy_authorization`).
|
||||||
|
- Any accuracy or "traffic-reduction" claim from the closed loop is tagged
|
||||||
|
**MEASURED** only with a named reproducer over a stated scenario, **SYNTHETIC**
|
||||||
|
for simulated apertures, and **CLAIMED** otherwise. Real multi-AP coherent
|
||||||
|
measurement and RIS actuation remain **hardware-dependent** and require
|
||||||
|
real-silicon evidence (a captured runtime log) before any hardware claim, per
|
||||||
|
CLAUDE.md. No number is invented here.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Sensing becomes an experiment: RuView spends its RF/energy/privacy budget on
|
||||||
|
the measurements that most reduce current uncertainty, instead of processing
|
||||||
|
whatever incidental traffic arrives.
|
||||||
|
- The loop is only as strong as its two dependencies: ADR-308 must expose a
|
||||||
|
usable uncertainty surface and ADR-311 must produce trustworthy information-
|
||||||
|
gain estimates. Where either is absent, the controller degrades to the
|
||||||
|
ADR-280 staleness planner rather than acting on a fabricated gain estimate.
|
||||||
|
- Controllability is hardware-bounded. On commodity ESP32 sensors the
|
||||||
|
controllable set may be limited to cadence; the full loop (bandwidth, antenna,
|
||||||
|
beam) needs NICs/RIS that expose those axes, surfaced through ADR-317.
|
||||||
|
- This ADR adds a controller; it does not re-open ADR-280's raw-export or
|
||||||
|
actuation-governance decisions, which remain authoritative and fail-closed.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Design-level acceptance (phase 3): a simulated closed loop over a synthetic
|
||||||
|
scene reduces terminal fused-state uncertainty faster than (a) the passive
|
||||||
|
ADR-280 staleness planner and (b) an open-loop fixed sweep, at equal
|
||||||
|
measurement budget — reported **SYNTHETIC**, with the scenario and seed named.
|
||||||
|
- Governance tests: every solicited measurement and actuation in the loop is
|
||||||
|
admitted through the ADR-280 fail-closed path; a loop step that would exceed
|
||||||
|
the task's privacy ceiling or steer into an ungranted zone is denied.
|
||||||
|
- Degradation test: with an empty controllable set (ESP32-only), the controller
|
||||||
|
falls back to the staleness planner with no error and no fabricated gain.
|
||||||
|
- Hardware validation of bandwidth/antenna/beam actuation is explicitly out of
|
||||||
|
scope until real silicon exposes those axes and produces a captured log.
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
# ADR-307: 802.11bf-native architecture — standardized WLAN sensing as native measurement types
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 2)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: 80211bf, wlan-sensing, standards, measurement-types, hal, phase-2
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #10, *802.11bf-native
|
||||||
|
architecture*. In the ADR-297 phasing it is a phase-2 integration primitive: it
|
||||||
|
sits on the phase-1 spine (authenticated identity ADR-302, spatial ontology
|
||||||
|
ADR-303, evidence engine ADR-301) and **feeds ADR-317** (the RuView sensor HAL),
|
||||||
|
which is the clause of the acceptance test that "identifies the hardware." It is
|
||||||
|
authored as **Proposed**.
|
||||||
|
|
||||||
|
**IEEE 802.11bf-2025 ("WLAN Sensing") was published 2025-09-26** — verified
|
||||||
|
against the IEEE SA record in `wifi-densepose-hardware` (`ieee80211bf/mod.rs`
|
||||||
|
header, "evidence grade MEASURED", ADR-152 §1.1). Standardization is complete
|
||||||
|
for sub-7 GHz and >45 GHz (DMG) bands: formal sensing measurement setup,
|
||||||
|
measurement instances, feedback/reporting, and sensing-by-proxy (SBP). This
|
||||||
|
changes RuView's strategic frame: rather than treating every WiFi measurement as
|
||||||
|
an *opportunistic* extraction from incidental traffic, RuView can be the **open
|
||||||
|
reference sensing stack around the standard** — the day commodity silicon
|
||||||
|
exposes it.
|
||||||
|
|
||||||
|
Substantial scaffolding already exists and must be **reused/extended, not
|
||||||
|
rebuilt**. `v2/crates/wifi-densepose-hardware/src/ieee80211bf/` already models
|
||||||
|
the standardized procedure surface as forward-compatible types (ADR-152/153):
|
||||||
|
|
||||||
|
- `types` — `SpecProfile` version gates, `SensingRole`/`TransceiverRole`,
|
||||||
|
`MeasurementSetupParams`, `SensingCapabilities` negotiation, and required
|
||||||
|
`ConsentMode` governance metadata on every setup.
|
||||||
|
- `messages` — `SensingMeasurementSetupRequest/Response`,
|
||||||
|
`SensingMeasurementInstance`, `SensingMeasurementReport`, `CsiReportPayload`,
|
||||||
|
`SbpRequest/Response`, `SensingSessionTermination`.
|
||||||
|
- `session` — a deterministic FSM (`Idle → SetupNegotiating → Active →
|
||||||
|
Terminating → Idle`) with rejection paths, single-role enforcement, and SBP
|
||||||
|
proxy mode; `table` (responder-side setup registry); `transport` (the
|
||||||
|
`SensingTransport` seam, a `SimTransport` test double, and an
|
||||||
|
`OpportunisticCsiBridge` that maps today's opportunistic CSI onto the
|
||||||
|
standardized report path).
|
||||||
|
|
||||||
|
The module's own honesty note is authoritative and carried forward here: it is
|
||||||
|
**not a certified 802.11bf implementation**, and **no commodity silicon — ESP32
|
||||||
|
included — implements the standard yet**; the OTA frame binding lands when a
|
||||||
|
chipset exposes it. Wideband ingest plumbing is already in place too: **ADR-289**
|
||||||
|
(FeitCSI/AX210) carries native subcarrier dimensionality end-to-end and records
|
||||||
|
the native→pipeline mapping, and noted that "truncated CIR is a natural
|
||||||
|
extension of the same plumbing."
|
||||||
|
|
||||||
|
What is missing is architectural, not protocol scaffolding: normalized CSI is
|
||||||
|
still treated as *the* WiFi input. The standardized sensing measurements
|
||||||
|
(TB/non-TB soundings, truncated CIR / PDP reports) are modeled as protocol
|
||||||
|
messages but are **not yet first-class native measurement types** that flow
|
||||||
|
through calibration (ADR-298), fusion (ADR-308), and the ontology (ADR-303) on
|
||||||
|
equal footing with normalized CSI.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Keep 802.11bf as a protocol model only; always down-convert its reports to
|
||||||
|
normalized CSI at ingest.** Rejected: truncated CIR/PDP carry range-resolved
|
||||||
|
multipath structure that flattening to a CSI matrix discards; it also wastes
|
||||||
|
the standard's native report semantics.
|
||||||
|
2. **Fork a parallel "bf pipeline" alongside the CSI pipeline.** Rejected:
|
||||||
|
duplicates calibration, fusion, ontology, and evidence plumbing, and re-opens
|
||||||
|
the O(surfaces²) translation problem ADR-303 exists to close.
|
||||||
|
3. **Promote standardized sensing measurements to native measurement types
|
||||||
|
inside the existing pipeline**, with normalized CSI as one measurement type
|
||||||
|
among several. Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Adopt an **802.11bf-native architecture**: standardized WLAN sensing
|
||||||
|
measurements become **additional native measurement types**, alongside — not
|
||||||
|
replacing — normalized CSI.
|
||||||
|
|
||||||
|
### 1. Native measurement types
|
||||||
|
|
||||||
|
- Define the standardized reports the `ieee80211bf` module already models
|
||||||
|
(TB and non-TB soundings; truncated CIR; PDP) as first-class
|
||||||
|
`MeasurementType` variants that the pipeline carries end-to-end, each tagged
|
||||||
|
with its `SpecProfile` and band. Normalized CSI remains one such type; the
|
||||||
|
`OpportunisticCsiBridge` remains the path for silicon that only offers
|
||||||
|
incidental CSI.
|
||||||
|
- Truncated CIR/PDP reuse the **ADR-289** subcarrier-agnostic / native-
|
||||||
|
dimensionality plumbing (truncated CIR is the stated natural extension); the
|
||||||
|
native→pipeline mapping is recorded in frame metadata so downstream stages
|
||||||
|
know the true range/spectral resolution of a bf report vs. an interpolated CSI
|
||||||
|
frame.
|
||||||
|
|
||||||
|
### 2. Ontology and governance binding
|
||||||
|
|
||||||
|
- Each standardized measurement becomes an ADR-303 `Observation` node from an
|
||||||
|
ADR-302-authenticated `Sensor`, carrying `SemanticProvenance` and exactly one
|
||||||
|
`EvidenceLevel` (L0–L5, ADR-282). The `ieee80211bf` `ConsentMode` metadata —
|
||||||
|
required on every setup — composes with the ADR-277 policy engine, so a
|
||||||
|
standardized session is admitted under the same governance as any other
|
||||||
|
sensing task (ADR-280).
|
||||||
|
- SBP (sensing-by-proxy) sessions attribute the report to the proxying and the
|
||||||
|
sensing entities distinctly, so provenance is not laundered through the proxy.
|
||||||
|
|
||||||
|
### 3. HAL feed (ADR-317)
|
||||||
|
|
||||||
|
- The capability set a device advertises — which `MeasurementType`s, bands,
|
||||||
|
bandwidths, roles, and `SpecProfile` it supports — is exactly the descriptor
|
||||||
|
**ADR-317** (HAL) needs to "identify the hardware." ADR-307 defines that
|
||||||
|
capability descriptor as the projection of `SensingCapabilities`; ADR-317
|
||||||
|
consumes it. A device that implements no bf profile advertises only the
|
||||||
|
opportunistic-CSI capability.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView is positioned as the open reference stack *around* the standard: when a
|
||||||
|
chipset exposes 802.11bf, its native reports flow through calibration, fusion,
|
||||||
|
ontology, and evidence with no bespoke pipeline — the plumbing is already
|
||||||
|
tested against `SimTransport` and synthetic fixtures.
|
||||||
|
- Normalized CSI is demoted from "the WiFi input" to "one measurement type,"
|
||||||
|
which is the correct framing for a multi-measurement future and prevents the
|
||||||
|
bf path from being a second-class citizen.
|
||||||
|
- **No hardware claim is made or implied.** No commodity silicon implements
|
||||||
|
802.11bf yet; this ADR wires the *types and flow*, tested in simulation. Any
|
||||||
|
OTA/native-report accuracy claim requires real silicon evidence (a captured
|
||||||
|
log) per CLAUDE.md, and any wideband number must be tagged with the capture
|
||||||
|
hardware (ADR-289). No benchmark number is invented here.
|
||||||
|
- This ADR does not re-open ADR-152/153's decision to avoid OTA frame binding
|
||||||
|
until silicon exists; it consumes that surface and adds the pipeline
|
||||||
|
integration.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test -p wifi-densepose-hardware` — existing `ieee80211bf` FSM,
|
||||||
|
table, and transport tests continue to pass; new tests assert that a
|
||||||
|
`SensingMeasurementReport` (TB and non-TB) and a truncated-CIR/PDP report
|
||||||
|
round-trip through the pipeline as native `MeasurementType`s.
|
||||||
|
- `cargo test -p wifi-densepose-mat` — truncated CIR ingest reuses the ADR-289
|
||||||
|
subcarrier-agnostic path and records the native→pipeline mapping; dimension/
|
||||||
|
version validation on standardized reports mirrors the FeitCSI parser gates.
|
||||||
|
- Ontology/governance tests: each standardized measurement becomes an ADR-303
|
||||||
|
`Observation` from an ADR-302-authenticated `Sensor` with one `EvidenceLevel`;
|
||||||
|
`ConsentMode` composes with ADR-277 admission; SBP attributes proxy vs. sensor
|
||||||
|
provenance distinctly.
|
||||||
|
- HAL contract test: the ADR-317 capability descriptor is derivable from
|
||||||
|
`SensingCapabilities`; a bf-less device advertises only opportunistic CSI.
|
||||||
|
- All measurement-type flows are simulation-tested (`SimTransport`, synthetic
|
||||||
|
fixtures); OTA binding and any hardware accuracy claim remain out of scope
|
||||||
|
until real silicon exposes the standard.
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
# ADR-308: Real sensor fusion — uncertainty-aware, multiple observations → one world state
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 2)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: fusion, uncertainty, multimodal, world-state, ontology, phase-2
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #11, *real sensor fusion*.
|
||||||
|
In the ADR-297 DAG it is a phase-2 integration primitive: it **consumes ADR-303**
|
||||||
|
(canonical spatial ontology) and **produces the single fused world state** that
|
||||||
|
the phase-3 primitives build on — **ADR-309** (long-term spatial memory),
|
||||||
|
**ADR-310** (counterfactual inference), and **ADR-312** (digital RF twin). It is
|
||||||
|
authored as **Proposed**.
|
||||||
|
|
||||||
|
The defining invariant is not "support more modalities" but the *shape of the
|
||||||
|
output*: **multiple observations must resolve to one probabilistic world state,
|
||||||
|
not many feeds into a visualization.** A dashboard that shows a WiFi layer, a
|
||||||
|
mmWave layer, and a BLE layer side by side is not fusion; it pushes the
|
||||||
|
reconciliation onto the human. Real fusion produces one uncertainty-aware state
|
||||||
|
that every downstream consumer reads, with each contributing observation's
|
||||||
|
provenance and confidence still recoverable.
|
||||||
|
|
||||||
|
Substantial scaffolding already exists and must be **reused/extended, not
|
||||||
|
rebuilt**:
|
||||||
|
|
||||||
|
- **ADR-063** (60 GHz mmWave ↔ WiFi CSI fusion, *Proposed*) established the
|
||||||
|
first cross-modal fusion case: pairing noisy CSI-derived vitals with clinical-
|
||||||
|
grade mmWave FMCW radar (Seeed MR60BHA2 over UART, with a **live hardware
|
||||||
|
capture** logged on 2026-03-15). ADR-308 generalizes that pairwise case into
|
||||||
|
an N-modality, uncertainty-aware fusion.
|
||||||
|
- **ADR-137** (fusion-engine quality scoring, *Accepted — partial*) already
|
||||||
|
built the auditable-quality building block: it identified that the multistatic
|
||||||
|
fusers (`wifi-densepose-signal/src/ruvsense/multistatic.rs`,
|
||||||
|
`wifi-densepose-ruvector/src/viewpoint/fusion.rs`) discarded the evidence they
|
||||||
|
used, and specified a single auditable record — "this fused output is
|
||||||
|
trustworthy because X, Y, Z, but be aware of contradiction C" — with evidence
|
||||||
|
references and contradiction flags. ADR-308 reuses that record as the
|
||||||
|
provenance/quality carrier of the fused state.
|
||||||
|
- **ADR-280** `CoherentSensorGroup` (fail-closed coherent fusion) and
|
||||||
|
**ADR-303** `Observation`/`Track`/`Event` node types are the input and output
|
||||||
|
vocabulary respectively.
|
||||||
|
|
||||||
|
What is missing is the **uncertainty-aware combiner across heterogeneous
|
||||||
|
modalities**: a fusion stage that takes authenticated observations from WiFi,
|
||||||
|
BLE, UWB, mmWave, acoustic, IMU, lidar, and cameras (only where policy permits),
|
||||||
|
each with its own uncertainty, and emits one probabilistic `WorldState` — with
|
||||||
|
per-observation contradiction flags, not a stack of independent feeds.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Per-modality feeds rendered together** (today's implicit model on some
|
||||||
|
surfaces). Rejected: it is visualization, not fusion; contradictions are
|
||||||
|
never reconciled and there is no single state to reason over.
|
||||||
|
2. **Hard-switch "best modality wins"** (e.g., always prefer mmWave vitals over
|
||||||
|
CSI vitals). Rejected: throws away corroborating evidence and cannot express
|
||||||
|
*disagreement* — the very thing ADR-137's contradiction flags exist to
|
||||||
|
surface — and degrades badly when the preferred modality is absent or OOD.
|
||||||
|
3. **Uncertainty-weighted probabilistic fusion into one world state**, reusing
|
||||||
|
ADR-137's auditable quality record and ADR-280's fail-closed coherence gate.
|
||||||
|
Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Adopt **uncertainty-aware multimodal fusion** whose invariant output is one
|
||||||
|
probabilistic world state.
|
||||||
|
|
||||||
|
### 1. Inputs: authenticated, ontology-typed observations
|
||||||
|
|
||||||
|
- Inputs are ADR-303 `Observation` nodes from **ADR-302-authenticated** sensors.
|
||||||
|
Supported modalities: WiFi (CSI / 802.11bf native reports via ADR-307), BLE,
|
||||||
|
UWB, mmWave (ADR-063), acoustic, IMU, lidar, and cameras. Cameras and any
|
||||||
|
higher privacy-class modality enter fusion **only where the ADR-277 policy
|
||||||
|
engine permits** — camera-free coverage is a RuView invariant (ADR-282), so
|
||||||
|
cameras are an opt-in, policy-gated input, never assumed present.
|
||||||
|
- Each observation carries its own uncertainty and exactly one `EvidenceLevel`
|
||||||
|
(ADR-282). An observation flagged out-of-distribution by **ADR-299** is
|
||||||
|
down-weighted or excluded per its OOD verdict rather than silently averaged in.
|
||||||
|
|
||||||
|
### 2. Combiner: uncertainty-weighted, contradiction-aware
|
||||||
|
|
||||||
|
- Observations are combined by their uncertainty into one probabilistic
|
||||||
|
`WorldState` over the ADR-303 entities (`Person`, `Object`, `Track`, and the
|
||||||
|
per-`Space` inference). The combiner does **not** collapse disagreement: when
|
||||||
|
modalities conflict beyond their stated uncertainty, the fused output carries
|
||||||
|
ADR-137 **contradiction flags** and the evidence references that produced
|
||||||
|
them, so a consumer can see *that* WiFi and mmWave disagree and *why*.
|
||||||
|
- Coherent multi-node fusion inherits ADR-280's fail-closed
|
||||||
|
`CoherentSensorGroup` gate: no coherent combination unless sync, phase, and
|
||||||
|
geometry compatibility are proven; otherwise the group degrades to incoherent
|
||||||
|
combination rather than producing confident nonsense.
|
||||||
|
|
||||||
|
### 3. Output: one world state, provenance preserved
|
||||||
|
|
||||||
|
- The output is a single `WorldState` written into the ADR-303 ontology, with
|
||||||
|
every fused value retaining recoverable per-observation provenance and the
|
||||||
|
ADR-137 quality record. This is the state ADR-309/310/312 consume; they read
|
||||||
|
one probabilistic world, not a modality stack.
|
||||||
|
- The fused state carries an aggregate uncertainty and an evidence level derived
|
||||||
|
from its inputs (never upgraded above the weakest contributing L-level for a
|
||||||
|
given claim).
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Downstream primitives (spatial memory, counterfactual, RF twin) build on one
|
||||||
|
probabilistic world state with uniform uncertainty and provenance, instead of
|
||||||
|
re-implementing reconciliation per consumer.
|
||||||
|
- Contradictions become first-class signal, not noise: ADR-137's record means a
|
||||||
|
disagreement between mmWave and CSI is surfaced and auditable, which is also
|
||||||
|
what lets ADR-299 and the evidence engine (ADR-301) reason about reliability.
|
||||||
|
- Fusion is uncertainty-honest: an OOD or low-evidence observation is
|
||||||
|
down-weighted, not averaged in as if trustworthy; a fused claim never presents
|
||||||
|
a stronger evidence level than its weakest necessary input.
|
||||||
|
- **No accuracy or "camera-grade" claim is made.** ADR-063's mmWave path has a
|
||||||
|
real-silicon capture; the multimodal combiner's accuracy is not asserted here.
|
||||||
|
Any fused-accuracy number requires a named reproducer tagged MEASURED /
|
||||||
|
SYNTHETIC / CLAIMED, and WiFi sensing is never presented as camera-grade
|
||||||
|
(CLAUDE.md, ADR-282). No number is invented.
|
||||||
|
- Cameras remain a governed, opt-in input; enabling them does not weaken the
|
||||||
|
camera-free coverage guarantee for deployments that exclude them.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test -p wifi-densepose-ruvector` / `-p wifi-densepose-signal` — the
|
||||||
|
ADR-137 quality record and contradiction flags travel with the fused output;
|
||||||
|
the ADR-280 `CoherentSensorGroup` gate still fails closed under
|
||||||
|
clock/phase/geometry violation.
|
||||||
|
- Fusion invariant test: N modality observations over one scene resolve to a
|
||||||
|
single `WorldState` node in the ADR-303 ontology (not N feeds), with
|
||||||
|
per-observation provenance recoverable and one aggregate evidence level.
|
||||||
|
- Uncertainty tests: a high-uncertainty or ADR-299-flagged-OOD observation is
|
||||||
|
down-weighted/excluded; conflicting modalities produce a contradiction flag
|
||||||
|
rather than a silently averaged value; the fused evidence level never exceeds
|
||||||
|
the weakest necessary input.
|
||||||
|
- Governance test: a camera or higher-privacy modality is admitted into fusion
|
||||||
|
only when the ADR-277 policy engine permits; otherwise it is excluded and the
|
||||||
|
fused state notes the exclusion.
|
||||||
|
- Any accuracy comparison (e.g., fused vitals vs. mmWave-only) is reported with
|
||||||
|
its evidence tag and reproducer; none is asserted in this ADR.
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
# ADR-309: Long-term spatial memory — learn the normal physics of a location
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 3)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: spatial-memory, ruvector, anomaly-detection, temporal, world-state, phase-3
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** and owns primitive #12, *long-term spatial
|
||||||
|
memory*. In the ADR-297 phasing it is a phase-3 primitive that sits on the fused
|
||||||
|
world state produced by **ADR-308** (real sensor fusion) and **ties to ADR-312**
|
||||||
|
(digital RF twin): spatial memory is the *learned normal* that a twin can
|
||||||
|
simulate against and that anomaly detection compares against. It is authored as
|
||||||
|
**Proposed**.
|
||||||
|
|
||||||
|
The capability is to **learn the normal physics of a location** so anomalies
|
||||||
|
surface *without training a detector for every anomaly*. Concretely, the system
|
||||||
|
should learn statements like: "a chair is normally here"; "this bedroom is
|
||||||
|
usually occupied between these hours"; "the RF propagation of this space
|
||||||
|
changed"; "this machine's vibration signature changed"; "a new reflector
|
||||||
|
appeared." None of these is a labeled anomaly class — they are *deviations from
|
||||||
|
a learned baseline of normality*. This is the difference between supervised
|
||||||
|
anomaly detection (which needs examples of every failure) and **baseline-relative
|
||||||
|
anomaly detection** (which needs only a well-characterized normal).
|
||||||
|
|
||||||
|
Substantial substrate already exists and must be **reused/extended, not
|
||||||
|
rebuilt**:
|
||||||
|
|
||||||
|
- **RuVector** (`v2/crates/wifi-densepose-ruvector`) is the designated substrate
|
||||||
|
in the ADR-282 layer stack ("persistent objects, Gaussian fields, scene
|
||||||
|
graphs, temporal memory"). It already provides the vector/temporal machinery
|
||||||
|
this ADR needs — HNSW indexing (`hnsw.rs`, `hnsw_quantized.rs`), an event log
|
||||||
|
(`event_log.rs`), coverage and estimator surfaces, and the `crv`/`mat`
|
||||||
|
temporal sub-modules — so long-term spatial memory is a *consumer and
|
||||||
|
organizer* of RuVector primitives, not a new store.
|
||||||
|
- **ADR-303** supplies the entity vocabulary the memory is indexed by (`Space`,
|
||||||
|
`Object`, `Sensor`, `Track`, `Event`); **ADR-308** supplies the fused,
|
||||||
|
uncertainty-carrying `WorldState` snapshots that memory accumulates over time.
|
||||||
|
- **ADR-135** (empty-room baseline calibration) and **ADR-298** (automatic
|
||||||
|
domain calibration) already establish a *calibration-time* baseline of a
|
||||||
|
space; ADR-309 extends that from a one-shot baseline to a **continuously
|
||||||
|
learned, time-of-day-aware** model of normal.
|
||||||
|
|
||||||
|
What is missing is the **temporal normality model**: a per-`Space` learned
|
||||||
|
distribution of fused world states over time (including periodicity — hour of
|
||||||
|
day, day of week), plus RF-propagation and modality-signature baselines, against
|
||||||
|
which a live fused state is scored for deviation.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Supervised anomaly classifiers per anomaly type.** Rejected: it needs
|
||||||
|
labeled examples of every anomaly (fall, intrusion, machine fault, moved
|
||||||
|
furniture), which do not exist for most spaces and do not transfer between
|
||||||
|
rooms; it also cannot catch a *novel* anomaly it was never trained on.
|
||||||
|
2. **Single static baseline** (the ADR-135 empty-room snapshot, used forever).
|
||||||
|
Rejected as the endpoint: it cannot express *when* a space is normally
|
||||||
|
occupied, cannot track slow legitimate drift (furniture rearranged on
|
||||||
|
purpose), and flags every diurnal change as anomalous.
|
||||||
|
3. **Continuously learned, time-aware normality model on the RuVector
|
||||||
|
substrate**, scoring live fused state against learned normal. Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Adopt a **long-term spatial memory** that learns each location's normal physics
|
||||||
|
on the RuVector substrate and scores live fused state against it.
|
||||||
|
|
||||||
|
### 1. What "normal" is learned over
|
||||||
|
|
||||||
|
Per ADR-303 `Space` (and the entities within it), accumulate the ADR-308 fused
|
||||||
|
`WorldState` over time into a learned normality model covering:
|
||||||
|
|
||||||
|
- **Occupancy / activity periodicity** — the distribution of presence and
|
||||||
|
activity by hour-of-day and day-of-week (the "bedroom usually occupied certain
|
||||||
|
hours" case).
|
||||||
|
- **Static scene layout** — persistent `Object` positions and the expected
|
||||||
|
reflector set (the "chair normally here" / "new reflector appeared" cases),
|
||||||
|
building on the ADR-135/298 baseline.
|
||||||
|
- **RF-propagation baseline** — the space's normal multipath/propagation
|
||||||
|
signature (the "RF propagation changed" case).
|
||||||
|
- **Per-modality signatures** — e.g., a machine's normal vibration/acoustic/IMU
|
||||||
|
signature (the "vibration signature changed" case).
|
||||||
|
|
||||||
|
Each learned baseline carries its own uncertainty and an `EvidenceLevel`
|
||||||
|
(ADR-282); a baseline learned from replay is L1, from a field pilot L4, and is
|
||||||
|
never presented above the evidence of the observations it was learned from.
|
||||||
|
|
||||||
|
### 2. Substrate: RuVector, temporally compressed
|
||||||
|
|
||||||
|
- The memory is stored and indexed on RuVector (HNSW for nearest-normal recall,
|
||||||
|
the event log for the temporal stream, the temporal sub-modules for
|
||||||
|
compression). Long-horizon history is temporally compressed — recent detail
|
||||||
|
retained, older history summarized — so memory cost is bounded rather than
|
||||||
|
growing linearly forever.
|
||||||
|
- The memory is *keyed by* the ADR-303 ontology, so "normal for this `Space` at
|
||||||
|
this hour" is a first-class query, and slow legitimate drift updates the
|
||||||
|
baseline (with provenance) instead of accumulating as permanent anomaly.
|
||||||
|
|
||||||
|
### 3. Anomaly = deviation from learned normal
|
||||||
|
|
||||||
|
- A live fused `WorldState` is scored against the applicable learned baseline
|
||||||
|
(matched by space and time context). A deviation beyond the baseline's
|
||||||
|
uncertainty is surfaced as an ADR-303 `Event` — *without* a per-anomaly
|
||||||
|
detector — carrying the baseline it deviated from, the deviation magnitude,
|
||||||
|
and its evidence level. Whether that event is actionable is a policy/consumer
|
||||||
|
decision (ADR-277), not this layer's.
|
||||||
|
- The learned normal is exactly what **ADR-312** (RF twin) can simulate against:
|
||||||
|
the twin proposes an expected state, spatial memory supplies the learned
|
||||||
|
actual-normal, and their divergence is a physically grounded anomaly signal.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Anomaly detection generalizes: a space gets deviation detection from its own
|
||||||
|
learned normal, so a novel anomaly (never labeled anywhere) still registers as
|
||||||
|
a deviation, and the model transfers to a new room by *learning that room's*
|
||||||
|
normal rather than importing a foreign detector.
|
||||||
|
- Bounded memory: temporal compression keeps long-horizon memory finite; the
|
||||||
|
trade-off is that fine detail of old history is summarized, which is acceptable
|
||||||
|
for a normality baseline.
|
||||||
|
- Legitimate change is not a permanent false positive: slow drift updates the
|
||||||
|
baseline with provenance, distinguishing "furniture deliberately rearranged"
|
||||||
|
(baseline shifts) from "reflector appeared unexpectedly" (deviation event).
|
||||||
|
- **No accuracy claim is made.** Deviation-detection quality is not asserted
|
||||||
|
here; any detection-rate or false-positive number requires a named reproducer
|
||||||
|
tagged MEASURED / SYNTHETIC / CLAIMED, and a health/safety framing stays within
|
||||||
|
the ADR-282 bounded-claims discipline (decision support, not diagnosis). No
|
||||||
|
number is invented.
|
||||||
|
- The memory is governed: learned baselines are observations of a space, subject
|
||||||
|
to the same ADR-277 retention/privacy policy as the fused state they summarize;
|
||||||
|
no raw P0 RF is retained to build a baseline.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test -p wifi-densepose-ruvector` — the normality model builds on the
|
||||||
|
existing HNSW/event-log/temporal primitives; nearest-normal recall and
|
||||||
|
temporal-compression bounds are exercised on synthetic streams.
|
||||||
|
- Baseline/deviation tests: a synthetic scene with a known injected change (moved
|
||||||
|
`Object`, altered propagation, altered modality signature) produces a deviation
|
||||||
|
`Event` against the learned normal *without* a per-anomaly detector; an
|
||||||
|
unchanged diurnal cycle produces none (no false positive on normal periodicity).
|
||||||
|
- Drift test: a slow legitimate change updates the baseline (with provenance)
|
||||||
|
rather than emitting a persistent anomaly; an abrupt change does emit one.
|
||||||
|
- Evidence test: a learned baseline carries the evidence level of its source
|
||||||
|
observations and is never presented above it; retention honors ADR-277.
|
||||||
|
- Twin-linkage design check (with ADR-312): divergence between a twin-simulated
|
||||||
|
expected state and the learned normal is expressible as a deviation signal.
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
# ADR-310: Counterfactual inference — generative spatial reasoning
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 3)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: inference, generative, counterfactual, rf-twin, fusion, uncertainty, phase-3
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** (perception substrate program) and owns
|
||||||
|
primitive #13, *counterfactual inference*. In the ADR-297 DAG it is a phase-3,
|
||||||
|
research-forward primitive that sits on top of the fused world state: it
|
||||||
|
**consumes ADR-308** (real sensor fusion) for the current fused estimate and
|
||||||
|
**ADR-312** (digital RF twin) for the twin's expected measurement
|
||||||
|
distributions. It is design intent, authored as Proposed, and is expected to be
|
||||||
|
revised as the phase-1 spine and the phase-2 fusion layer land.
|
||||||
|
|
||||||
|
RuView today reasons discriminatively: a task head maps measurements to a label
|
||||||
|
or a pose. That answers "what does the classifier say?" but not the questions an
|
||||||
|
operator actually asks — *would these RF measurements still make sense if nobody
|
||||||
|
were present? Does one person explain the observation better than two?* Those
|
||||||
|
are counterfactual questions, and a classifier cannot answer them because it has
|
||||||
|
no model of what a measurement *should* look like under a hypothesized world
|
||||||
|
state. A discriminative head asked about an empty room simply emits its
|
||||||
|
best-effort label; it cannot say "the observation is better explained by
|
||||||
|
absence."
|
||||||
|
|
||||||
|
The step this ADR proposes is toward a **generative spatial model**: given a
|
||||||
|
hypothesized scene state (occupancy, count, coarse positions) and the ADR-312
|
||||||
|
twin's propagation model for the deployment, predict the *expected* measurement
|
||||||
|
distribution, then score how well each hypothesis explains the observed
|
||||||
|
measurement. The best-explaining hypothesis — including the *nobody-present*
|
||||||
|
null hypothesis — is the answer, and the margin between hypotheses is a
|
||||||
|
first-class uncertainty signal.
|
||||||
|
|
||||||
|
Relevant existing assets to build on rather than duplicate:
|
||||||
|
|
||||||
|
- **ADR-308** (fusion) already produces the fused world estimate and its
|
||||||
|
covariance; the counterfactual layer scores hypotheses *relative to* that
|
||||||
|
estimate rather than re-fusing raw measurements.
|
||||||
|
- **ADR-312** (RF twin) is the generative forward model — per-deployment
|
||||||
|
geometry, radio locations, and expected measurement distributions. This ADR
|
||||||
|
is a *consumer* of the twin's forward simulator, not a second simulator.
|
||||||
|
- **ADR-299** (OOD/observability) already owns the `UNKNOWN` verdict; the
|
||||||
|
null-hypothesis ("nobody present better explains this than any occupancy
|
||||||
|
hypothesis") and the "no hypothesis explains this" case route through ADR-299,
|
||||||
|
not a parallel gate.
|
||||||
|
- `frame::EvidenceLevel` L0–L5 (ADR-282) and the ADR-301 evidence engine
|
||||||
|
account for the resulting confidence.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Keep only discriminative heads.** Rejected: cannot express absence,
|
||||||
|
cannot compare "one person vs. two" as competing explanations, and gives a
|
||||||
|
confident label even when no world state explains the data.
|
||||||
|
2. **A second, independently trained generative network with its own forward
|
||||||
|
model.** Rejected for the default path: duplicates the ADR-312 twin's
|
||||||
|
propagation model, invites the two models to disagree, and multiplies the
|
||||||
|
surface that must be validated. Reserved only if the twin's analytic forward
|
||||||
|
model proves insufficient for a phenomenon.
|
||||||
|
3. **A hypothesis-scoring layer that uses the ADR-312 twin as the forward model
|
||||||
|
and the ADR-308 fused state as the hypothesis prior, routing low-margin and
|
||||||
|
null-dominant cases to the ADR-299 UNKNOWN verdict.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Define a **counterfactual inference layer** that scores a small set of scene
|
||||||
|
hypotheses against observed measurements using the digital RF twin as the
|
||||||
|
generative forward model.
|
||||||
|
|
||||||
|
### 1. Hypothesis set
|
||||||
|
|
||||||
|
- Hypotheses are drawn from the ADR-308 fused state and its neighbourhood: the
|
||||||
|
current estimate, the **null hypothesis** (nobody present), and a bounded set
|
||||||
|
of nearby alternatives (±1 occupant, shifted position). The fused estimate
|
||||||
|
supplies the prior so the search stays small and grounded rather than
|
||||||
|
enumerating an open world.
|
||||||
|
- The hypothesis space is expressed over the **ADR-303** canonical ontology
|
||||||
|
(`Space`/`Zone`, occupant count, coarse position), so a counterfactual result
|
||||||
|
is a governed spatial statement, not an opaque score.
|
||||||
|
|
||||||
|
### 2. Forward model and scoring
|
||||||
|
|
||||||
|
- For each hypothesis, query the **ADR-312 twin** for the expected measurement
|
||||||
|
distribution given that scene state and the deployment's propagation model.
|
||||||
|
Score the observed measurement's likelihood under each hypothesis's expected
|
||||||
|
distribution.
|
||||||
|
- The answer is the maximum-likelihood hypothesis; the **margin** between the
|
||||||
|
top hypotheses (and between the top hypothesis and the null) is the
|
||||||
|
confidence signal, carried into the ADR-301 evidence engine.
|
||||||
|
|
||||||
|
### 3. Routing to UNKNOWN
|
||||||
|
|
||||||
|
- When the null hypothesis dominates, the layer reports *absence*, not a
|
||||||
|
low-confidence occupancy label.
|
||||||
|
- When **no** hypothesis explains the observation well (all likelihoods low, or
|
||||||
|
the winning margin below threshold), the result routes to the **ADR-299**
|
||||||
|
`UNKNOWN` verdict — the observation is outside what the twin can explain, and
|
||||||
|
the honest output is "I cannot account for this," never a forced label.
|
||||||
|
|
||||||
|
### Evidence discipline
|
||||||
|
|
||||||
|
- Twin-predicted distributions are a **simulation** (evidence level L0 per
|
||||||
|
ADR-282) labelled `SYNTHETIC`; a counterfactual verdict inherits the evidence
|
||||||
|
level of its weakest input and is never presented as camera-grade ground
|
||||||
|
truth (CLAUDE.md honesty rule).
|
||||||
|
- Any accuracy statement about counterfactual discrimination (e.g. "distinguishes
|
||||||
|
one occupant from two") requires the mean-pose-style baseline discipline of
|
||||||
|
CLAUDE.md, a leakage-free held-out split, and a reproducer before it may be
|
||||||
|
tagged `MEASURED`. This ADR asserts **no** such number.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView gains the ability to answer absence and "which explanation is better"
|
||||||
|
questions that discriminative heads structurally cannot — a step toward
|
||||||
|
generative spatial reasoning and a differentiator for security and
|
||||||
|
facility-monitoring applications where *absence* is the valuable signal.
|
||||||
|
- Quality is bounded by the fidelity of the ADR-312 twin's forward model and the
|
||||||
|
ADR-308 fused prior; the layer reports margins and defers to ADR-299 UNKNOWN
|
||||||
|
rather than overstating a coarse model.
|
||||||
|
- Hard dependency on ADR-308 (fused state and covariance) and ADR-312 (forward
|
||||||
|
model); this ADR builds neither a fusion engine nor a propagation simulator of
|
||||||
|
its own.
|
||||||
|
- Being phase 3, this is design intent sitting on the fused world state; it is
|
||||||
|
expected to be revised as ADR-308 and ADR-312 land, and it is not implemented
|
||||||
|
by the phase-1 swarm.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests: hypothesis likelihood scoring is a deterministic function of
|
||||||
|
observed measurement + hypothesis + twin parameters; the null hypothesis wins
|
||||||
|
on a synthesized empty-room measurement; a two-occupant measurement scores the
|
||||||
|
two-occupant hypothesis above the one-occupant hypothesis on a controlled
|
||||||
|
synthetic case.
|
||||||
|
- Integration test: measurements the twin cannot explain (out-of-model
|
||||||
|
scattering) drive the layer to the ADR-299 UNKNOWN verdict rather than a
|
||||||
|
forced occupancy label; margins propagate into the ADR-301 evidence engine.
|
||||||
|
- Held-out discrimination (deferred, real-silicon): one-vs-two and
|
||||||
|
presence-vs-absence discrimination on a leakage-free held-out split with a
|
||||||
|
mean-pose baseline, reported as `MEASURED` with a reproducer. Until then all
|
||||||
|
counterfactual output is `SYNTHETIC`/L0. No discrimination accuracy number is
|
||||||
|
asserted by this ADR.
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
# ADR-311: Information-gain scheduler — sample the most informative radios
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 3)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: scheduling, active-sensing, information-gain, edge, energy, fusion, phase-3
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** (perception substrate program) and owns
|
||||||
|
primitive #14, *information-gain scheduler*. In the ADR-297 DAG it is a phase-3,
|
||||||
|
research-forward primitive that sits on top of the fused world state and
|
||||||
|
**pairs with ADR-306** (active sensing): ADR-306 decides *what to probe*
|
||||||
|
(waveform, sensing task); this ADR decides *which radios/modalities to spend
|
||||||
|
budget on next*. It is authored as Proposed and is not implemented by the
|
||||||
|
phase-1 swarm.
|
||||||
|
|
||||||
|
With multiple sensors, processing every stream at full rate is wasteful: many
|
||||||
|
radios are, at any moment, contributing little to the current estimate while
|
||||||
|
consuming compute, energy, and bandwidth — the three scarce resources on the
|
||||||
|
edge nodes RuView targets (ESP32-S3/C6 and small gateways). Treating all sensors
|
||||||
|
equally is precisely the design that does not survive a real deployment of
|
||||||
|
"hundreds of sensors."
|
||||||
|
|
||||||
|
The scheduler assigns each candidate sensor/modality a value
|
||||||
|
|
||||||
|
```
|
||||||
|
Value(sensor) ≈ expected uncertainty reduction / (compute + energy + bandwidth)
|
||||||
|
```
|
||||||
|
|
||||||
|
and spends the next sampling/processing budget on the highest-value sensors.
|
||||||
|
Expected uncertainty reduction is estimated *before* paying for the measurement,
|
||||||
|
which is why the scheduler needs a model of what each sensor is likely to tell
|
||||||
|
it — supplied by the fused state's covariance and the RF twin's forward model,
|
||||||
|
not by actually sampling.
|
||||||
|
|
||||||
|
Relevant existing assets to build on rather than duplicate:
|
||||||
|
|
||||||
|
- **ADR-308** (fusion) maintains the fused state and its covariance — the
|
||||||
|
current uncertainty the scheduler is trying to reduce. Expected uncertainty
|
||||||
|
reduction is computed against that covariance, not a private one.
|
||||||
|
- **ADR-312** (RF twin) provides the per-sensor forward model used to predict a
|
||||||
|
candidate measurement's expected informativeness before sampling.
|
||||||
|
- **ADR-317** (RuView sensor HAL, phase 2) exposes each radio's real
|
||||||
|
compute/energy/bandwidth cost descriptors; the denominator is read from the
|
||||||
|
HAL, not guessed per platform.
|
||||||
|
- **ADR-306** (active sensing) is the paired actuator: the scheduler ranks
|
||||||
|
sensors, ADR-306 chooses the probe on the chosen sensor.
|
||||||
|
- **ADR-299** (observability) defines the phenomenon the estimate is *for*, so
|
||||||
|
the scheduler prioritizes uncertainty reduction on the objective that matters,
|
||||||
|
not on nuisance dimensions.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Round-robin / process-everything scheduling.** Rejected: burns edge
|
||||||
|
compute and energy on redundant streams and does not scale to large fleets;
|
||||||
|
the strategic and external reviews named exactly this as an edge-deployment
|
||||||
|
blocker.
|
||||||
|
2. **Static priority per sensor type (e.g. always prefer mmWave).** Rejected:
|
||||||
|
ignores that a sensor's *current* informativeness depends on the scene and
|
||||||
|
the present uncertainty — a well-placed WiFi link can dominate an occluded
|
||||||
|
mmWave node in a given moment.
|
||||||
|
3. **A value-of-information scheduler that ranks sensors by expected uncertainty
|
||||||
|
reduction per unit cost, using the ADR-308 covariance and ADR-312 forward
|
||||||
|
model, with costs from the ADR-317 HAL.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Define an **information-gain scheduler** that allocates the next
|
||||||
|
sampling/processing budget across available radios by value of information.
|
||||||
|
|
||||||
|
### 1. Value function
|
||||||
|
|
||||||
|
- For each candidate sensor/modality, estimate **expected uncertainty
|
||||||
|
reduction** on the ADR-299 objective by evaluating how much a predicted
|
||||||
|
measurement (via the **ADR-312** forward model) would shrink the **ADR-308**
|
||||||
|
fused-state covariance — a value-of-information estimate made *before* paying
|
||||||
|
for the measurement.
|
||||||
|
- Divide by the sensor's **cost** — compute + energy + bandwidth — read from the
|
||||||
|
**ADR-317** HAL descriptors. The exact weighting of the three cost terms is a
|
||||||
|
deployment policy (a battery node weights energy heavily; a wired gateway
|
||||||
|
weights bandwidth), configured, not hardcoded.
|
||||||
|
|
||||||
|
### 2. Allocation
|
||||||
|
|
||||||
|
- Rank candidates by value and spend the budget on the top set, subject to a
|
||||||
|
configurable floor that guarantees each sensor is sampled at least
|
||||||
|
occasionally (so a sensor whose value is currently low is not starved into
|
||||||
|
permanent blindness and can be re-evaluated as the scene changes).
|
||||||
|
- The scheduler emits an allocation, not a measurement; **ADR-306** active
|
||||||
|
sensing chooses the probe/waveform on each selected sensor, and the fusion
|
||||||
|
layer (ADR-308) incorporates the result.
|
||||||
|
|
||||||
|
### 3. Governance and honesty
|
||||||
|
|
||||||
|
- Skipping a sensor for a cycle is a *deliberate* reduction in coverage; the
|
||||||
|
scheduler records which sensors were sampled so downstream evidence (ADR-301)
|
||||||
|
reflects the actual sensing that occurred, and observability (ADR-299) can
|
||||||
|
raise `UNKNOWN` for a zone that went under-sampled rather than reporting a
|
||||||
|
stale estimate as current.
|
||||||
|
|
||||||
|
### Evidence discipline
|
||||||
|
|
||||||
|
- Expected-uncertainty-reduction estimates are model predictions from the
|
||||||
|
ADR-312 twin (simulation, L0 per ADR-282, `SYNTHETIC`); a scheduling decision
|
||||||
|
is a resource choice, never a sensing claim.
|
||||||
|
- Any energy/latency/throughput improvement figure requires real-silicon
|
||||||
|
measurement with a reproducer before it is tagged `MEASURED` (CLAUDE.md
|
||||||
|
hardware rule). This ADR asserts **no** efficiency number.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Edge deployments spend scarce compute, energy, and bandwidth where they buy
|
||||||
|
the most certainty, making "hundreds of sensors" operationally tractable — a
|
||||||
|
capability the reviews flagged as critical for edge deployment.
|
||||||
|
- Quality is bounded by the accuracy of the ADR-312 forward model (informativeness
|
||||||
|
prediction) and ADR-317 cost descriptors; a poor forward model degrades to
|
||||||
|
near-round-robin, which is safe but not optimal. The sampling floor bounds the
|
||||||
|
worst case.
|
||||||
|
- Hard dependency on ADR-308 (covariance), ADR-312 (forward model), and ADR-317
|
||||||
|
(cost descriptors), and paired with ADR-306; this ADR builds none of those.
|
||||||
|
- Being phase 3, this is design intent sitting on the fused world state and is
|
||||||
|
expected to be revised as ADR-306, ADR-308, ADR-312, and the ADR-317 HAL land.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests: the value function is a deterministic function of covariance +
|
||||||
|
forward model + cost descriptors; a sensor predicted to reduce objective
|
||||||
|
uncertainty more per unit cost ranks above one that reduces it less; the
|
||||||
|
sampling floor guarantees eventual re-evaluation of a low-value sensor.
|
||||||
|
- Integration test: on a synthetic multi-sensor scene, the scheduler reduces
|
||||||
|
objective uncertainty faster per unit modelled cost than round-robin, and
|
||||||
|
raises ADR-299 UNKNOWN for a deliberately starved zone rather than reporting a
|
||||||
|
stale estimate.
|
||||||
|
- Field validation (deferred, real-silicon): energy/latency/throughput on an
|
||||||
|
instrumented multi-node deployment, reported as `MEASURED` with a reproducer.
|
||||||
|
Until then all informativeness and cost figures are `SYNTHETIC`/L0. No
|
||||||
|
efficiency number is asserted by this ADR.
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
# ADR-312: Digital RF twin — persistent per-deployment RF model
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 3)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: rf-twin, digital-twin, propagation, calibration, spatial-memory, worldgraph, phase-3
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** (perception substrate program) and owns
|
||||||
|
primitive #15, *digital RF twin*. In the ADR-297 DAG it is a phase-3,
|
||||||
|
research-forward primitive that underpins several other phase-3 primitives:
|
||||||
|
**ADR-305** (placement optimizer) plans against the twin's propagation model,
|
||||||
|
**ADR-310** (counterfactual inference) uses it as the generative forward model,
|
||||||
|
and **ADR-311** (information-gain scheduler) uses it to predict per-sensor
|
||||||
|
informativeness. It ties directly to **ADR-298** (calibration), **ADR-305**
|
||||||
|
(placement), and **ADR-309** (long-term spatial memory). It is authored as
|
||||||
|
Proposed and is not implemented by the phase-1 swarm.
|
||||||
|
|
||||||
|
RuView today has no persistent, per-deployment model of the RF environment.
|
||||||
|
Calibration state, observed multipath, and radio geometry exist transiently
|
||||||
|
inside a running session; when the process restarts or a change happens
|
||||||
|
overnight, there is nothing that says "this is what this room's RF looked like
|
||||||
|
yesterday." Without a persistent baseline, a physical change — furniture moved,
|
||||||
|
a wall opened, a machine relocated, an intruder present — has nothing to be a
|
||||||
|
*delta against*. It is just a different measurement, indistinguishable from
|
||||||
|
noise or drift.
|
||||||
|
|
||||||
|
The **digital RF twin** is that persistent baseline: a per-deployment model
|
||||||
|
holding
|
||||||
|
|
||||||
|
- **geometry and radio locations** (from the ADR-303 scene / worldgraph),
|
||||||
|
- **propagation history** and **observed multipath** structure,
|
||||||
|
- **calibration state** (from ADR-298),
|
||||||
|
- **expected measurement distributions** for each link and phenomenon.
|
||||||
|
|
||||||
|
Once the twin exists, a physical change becomes a **measurable delta against the
|
||||||
|
twin** rather than an unexplained measurement. This is what connects RuView to
|
||||||
|
facility management (what changed in this space?), security (is there an
|
||||||
|
unexplained presence?), robotics (has the map drifted?), and industrial
|
||||||
|
monitoring (did the plant layout change?) — the applications the strategic
|
||||||
|
assessment named as the value beyond a single detector.
|
||||||
|
|
||||||
|
Relevant existing assets to build on rather than duplicate:
|
||||||
|
|
||||||
|
- The `worldgraph` crate already models the physical scene — `Room`/`Space`
|
||||||
|
with `bounds_enu`, `Wall { rf_attenuation_db }`, `Doorway`, `Zone`, and
|
||||||
|
`Sensor` nodes (ADR-303). The twin *annotates and persists* this scene with RF
|
||||||
|
state; it does not invent a second geometry.
|
||||||
|
- `wifi-densepose-calibration` (enrollment, bank, anchor, runtime, specialist)
|
||||||
|
holds the calibration state the twin persists; the twin references and
|
||||||
|
versions calibration records, it does not reimplement calibration.
|
||||||
|
- **ADR-309** (long-term spatial memory, phase 3) is the persistence and
|
||||||
|
temporal-history substrate; the twin is a *structured occupant* of that
|
||||||
|
memory, not a separate database.
|
||||||
|
- **ADR-302** (authenticated identity) and **ADR-292** (provenance) mean the
|
||||||
|
measurements that update the twin carry verified lineage, so a delta is
|
||||||
|
attributable rather than anonymous.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **No persistent RF model (status quo).** Rejected: every change looks like
|
||||||
|
noise; nothing supports "what changed since yesterday?", which is the
|
||||||
|
question the facility/security/industrial applications actually ask.
|
||||||
|
2. **A full electromagnetic digital twin (per-site ray-tracing / FDTD kept in
|
||||||
|
sync in real time).** Rejected for the default path: far heavier than the
|
||||||
|
coarse `rf_attenuation_db` scene RuView actually has and impractical on edge
|
||||||
|
hardware. A high-fidelity solver is retained as an *optional backend* the
|
||||||
|
twin can call, not the baseline.
|
||||||
|
3. **A persistent, per-deployment RF model layered over the ADR-303 scene and
|
||||||
|
ADR-309 memory: geometry + radio locations + calibration state + observed
|
||||||
|
multipath + expected measurement distributions, updated by verified
|
||||||
|
measurements, exposing changes as deltas.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Define the **digital RF twin** as a persistent, versioned, per-deployment model
|
||||||
|
of the RF environment, layered over existing scene, calibration, and memory
|
||||||
|
assets.
|
||||||
|
|
||||||
|
### 1. State the twin holds
|
||||||
|
|
||||||
|
- **Geometry and radio locations** referenced from the ADR-303 / worldgraph
|
||||||
|
scene (not copied).
|
||||||
|
- **Calibration state** referenced and versioned from
|
||||||
|
`wifi-densepose-calibration` (ADR-298), so the twin knows *which* calibration
|
||||||
|
a stored distribution was captured under.
|
||||||
|
- **Observed multipath and propagation history** — a bounded temporal summary
|
||||||
|
of per-link channel structure, stored in ADR-309 spatial memory.
|
||||||
|
- **Expected measurement distributions** per link and phenomenon — the forward
|
||||||
|
model ADR-305, ADR-310, and ADR-311 consume.
|
||||||
|
|
||||||
|
### 2. Update and delta
|
||||||
|
|
||||||
|
- Verified measurements (ADR-302 identity, ADR-292 provenance) update the twin's
|
||||||
|
distributions online, bounded by ADR-298 calibration validity. A new
|
||||||
|
observation is compared to the twin's expected distribution; the **delta** —
|
||||||
|
and its statistical significance against the twin's own variance — is the
|
||||||
|
primary output. A change large relative to the twin's modelled variance is a
|
||||||
|
*detected physical change*, not noise.
|
||||||
|
- The twin is **versioned**: a calibration event, a deliberate geometry edit, or
|
||||||
|
an accepted physical change advances the twin version, so history is
|
||||||
|
auditable and a delta is always relative to a named baseline.
|
||||||
|
|
||||||
|
### 3. Consumers
|
||||||
|
|
||||||
|
- **ADR-305** queries the twin's propagation model to plan placements.
|
||||||
|
- **ADR-310** uses the twin's expected distributions as the generative forward
|
||||||
|
model for hypothesis scoring.
|
||||||
|
- **ADR-311** uses per-sensor expected informativeness from the twin.
|
||||||
|
- Facility/security/robotics/industrial integrations read the twin's change
|
||||||
|
deltas as governed ADR-303 spatial events.
|
||||||
|
|
||||||
|
### Evidence discipline
|
||||||
|
|
||||||
|
- The twin's expected distributions and any propagation simulation are
|
||||||
|
**simulation** (evidence level L0 per ADR-282), labelled `SYNTHETIC`. A delta
|
||||||
|
computed against them is a model-relative statement.
|
||||||
|
- A change/anomaly detection *claim* (e.g. "detects furniture-scale changes")
|
||||||
|
requires real-silicon measurement against a leakage-free protocol with a
|
||||||
|
reproducer before it is tagged `MEASURED` (CLAUDE.md hardware rule). The twin
|
||||||
|
never presents a modelled expected distribution as evidence that a physical
|
||||||
|
state *is* the case; it presents a *delta and its significance*. This ADR
|
||||||
|
asserts **no** detection-accuracy number.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView gains a persistent per-deployment baseline, turning "a different
|
||||||
|
measurement" into "a measurable, attributable, versioned change" — the bridge
|
||||||
|
from a sensing runtime to facility management, security, robotics, and
|
||||||
|
industrial monitoring.
|
||||||
|
- The twin is the shared forward model for ADR-305/310/311, so those primitives
|
||||||
|
speak one propagation model rather than three inconsistent ones — a
|
||||||
|
deliberate reason to build the twin before its consumers mature.
|
||||||
|
- Quality is bounded by the coarseness of the worldgraph scene and the fidelity
|
||||||
|
of the forward model; the twin reports deltas *with significance against its
|
||||||
|
own variance* rather than asserting confident change detection on a coarse
|
||||||
|
model. The optional high-fidelity backend is where higher accuracy lives.
|
||||||
|
- Hard dependency on ADR-303 (scene), ADR-298 (calibration state), and ADR-309
|
||||||
|
(persistence); it reuses `worldgraph` and `wifi-densepose-calibration` rather
|
||||||
|
than rebuilding geometry or calibration.
|
||||||
|
- Being phase 3, this is design intent; it is expected to be revised as the
|
||||||
|
phase-1 spine, ADR-308 fusion, and ADR-309 memory land.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests: the twin's expected distribution is a deterministic function of
|
||||||
|
scene + calibration + propagation history; delta computation and its
|
||||||
|
significance against stored variance are correct on synthetic distributions;
|
||||||
|
versioning advances on calibration/geometry/accepted-change events and history
|
||||||
|
is retained.
|
||||||
|
- Integration test: on a synthetic deployment, an injected physical change (a
|
||||||
|
wall attenuation shift) produces a significant delta against the twin while
|
||||||
|
ordinary noise does not; the delta surfaces as a governed ADR-303 event with
|
||||||
|
provenance (ADR-302/292).
|
||||||
|
- Field validation (deferred, real-silicon): change detection on an instrumented
|
||||||
|
real deployment with a controlled physical-change protocol, reported as
|
||||||
|
`MEASURED` with a reproducer. Until then all twin distributions and deltas are
|
||||||
|
`SYNTHETIC`/L0. No detection-accuracy number is asserted by this ADR.
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
# ADR-313: Fleet control plane — provisioning to audit trails
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 2)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: fleet, operations, provisioning, firmware, updates, audit, identity, phase-2
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is a child of **ADR-297** (perception substrate program) and owns
|
||||||
|
primitive #16, *fleet control plane*. In the ADR-297 DAG it is a phase-2
|
||||||
|
integration-and-operations primitive that sits on the phase-1 spine: it
|
||||||
|
**consumes ADR-302** (authenticated sensor identity) for per-device identity and
|
||||||
|
enrollment, and **ADR-315** (capability certificate) for the signed models,
|
||||||
|
calibration validity, and capability envelopes a device is allowed to run. It is
|
||||||
|
authored as Proposed and is not implemented by the phase-1 swarm.
|
||||||
|
|
||||||
|
The external and internal reviews both named the same operational gap: RuView
|
||||||
|
has strong per-device primitives but no **release identity** and no **bill of
|
||||||
|
materials** binding a fielded sensor to the exact firmware, model, and
|
||||||
|
calibration it is running — and no plane to manage that across many devices.
|
||||||
|
Without this, a handful of nodes is fine but *hundreds* of sensors become an
|
||||||
|
operational nightmare: no coherent way to provision, roll certificates, verify
|
||||||
|
firmware compatibility, distribute signed models, track calibration lifecycle,
|
||||||
|
watch health, stage updates, roll back, diagnose remotely, enforce data
|
||||||
|
retention, or produce an audit trail. This ADR addresses that release-identity /
|
||||||
|
BOM gap directly.
|
||||||
|
|
||||||
|
The scope is deliberately the **control plane**, not the data plane. The
|
||||||
|
authenticated measurement path is **ADR-293** (bind + allowlist) plus **ADR-302**
|
||||||
|
(signed envelope); this ADR governs the *devices and artifacts*, not the
|
||||||
|
per-frame stream.
|
||||||
|
|
||||||
|
Relevant existing assets to build on rather than duplicate:
|
||||||
|
|
||||||
|
- **ADR-302** already defines per-device keypairs, the `DeviceId → public key →
|
||||||
|
capabilities` enrollment record, key rotation and revocation *semantics* — and
|
||||||
|
explicitly deferred their **fleet distribution** to this ADR. The control
|
||||||
|
plane is the distribution and lifecycle layer over ADR-302 identity, not a new
|
||||||
|
identity scheme.
|
||||||
|
- **ADR-315** (capability certificate) defines the signed, expiring artifact a
|
||||||
|
device is authorized to run; the fleet plane is what *distributes, stages, and
|
||||||
|
revokes* those certificates and the signed models they point at.
|
||||||
|
- **ADR-298** (calibration) owns calibration validity/expiry; the fleet plane
|
||||||
|
tracks calibration *lifecycle* across the fleet (which nodes are due, which are
|
||||||
|
stale) rather than redefining calibration.
|
||||||
|
- **ADR-316** (witness chain) provides the append-only, re-verifiable record;
|
||||||
|
fleet audit trails are witness-chain entries, not a parallel log format.
|
||||||
|
- **ADR-317** (RuView sensor HAL, phase 2) provides hardware/firmware capability
|
||||||
|
descriptors used for firmware-compatibility checks before staging an update.
|
||||||
|
- `wifi-densepose-bfld` `CapabilityAttestation` (ADR-141) is the device-side
|
||||||
|
attestation the plane checks against declared cohort capabilities.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Manual per-device operations (SSH/flash by hand).** Rejected: does not
|
||||||
|
scale past a handful of nodes, produces no release identity, no audit trail,
|
||||||
|
and no safe rollback — exactly the operational nightmare the reviews named.
|
||||||
|
2. **Adopt a generic third-party IoT device-management platform wholesale.**
|
||||||
|
Rejected as the core: generic platforms do not understand RuView's signed
|
||||||
|
capability certificate, calibration validity, or witness chain, and would
|
||||||
|
fork trust away from the phase-1 spine. A generic transport/agent *may* be a
|
||||||
|
backend, but identity, certificates, and audit remain RuView's.
|
||||||
|
3. **A RuView-native control plane layered on ADR-302 identity, ADR-315
|
||||||
|
certificates, ADR-298 calibration lifecycle, and ADR-316 audit — covering
|
||||||
|
provisioning through rollback and retention.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Define a **fleet control plane** that manages RuView sensors and their signed
|
||||||
|
artifacts across their lifecycle, built on the phase-1 identity/certificate
|
||||||
|
spine.
|
||||||
|
|
||||||
|
### 1. Release identity and bill of materials
|
||||||
|
|
||||||
|
- Each fielded device has a **BOM record** binding `DeviceId` (ADR-302) → exact
|
||||||
|
firmware version → signed model set → active capability certificate (ADR-315)
|
||||||
|
→ current calibration record (ADR-298) → HAL/hardware descriptor (ADR-317).
|
||||||
|
This *is* the release identity the reviews found missing: given a device you
|
||||||
|
can state precisely what it is running and prove it is signed.
|
||||||
|
|
||||||
|
### 2. Provisioning, certificates, firmware compatibility
|
||||||
|
|
||||||
|
- **Provisioning** is the authorized ADR-302 enrollment step at fleet scale:
|
||||||
|
minting a keypair, registering the public key and capabilities, and issuing
|
||||||
|
the initial ADR-315 certificate. A device is untrusted until provisioned.
|
||||||
|
- **Certificate lifecycle**: issue, rotate, expire, and **revoke** ADR-315
|
||||||
|
certificates and the ADR-302 keys behind them; revocation lists are
|
||||||
|
distributed here (the distribution ADR-302 deferred).
|
||||||
|
- **Firmware compatibility**: before staging a firmware or model, check the
|
||||||
|
target's ADR-317 HAL descriptor and ADR-141 capability attestation so an
|
||||||
|
incompatible or under-capable device is never sent an artifact it cannot
|
||||||
|
honestly run.
|
||||||
|
|
||||||
|
### 3. Cohorts, staged updates, rollback
|
||||||
|
|
||||||
|
- Devices group into **cohorts** (by site, hardware, capability). Updates —
|
||||||
|
signed models and firmware — roll out **staged** (canary → cohort → fleet)
|
||||||
|
with health gates between stages, and **roll back** to the previously recorded
|
||||||
|
BOM on a failed health check. Only signed artifacts are ever staged.
|
||||||
|
|
||||||
|
### 4. Health telemetry, remote diagnostics, retention, audit
|
||||||
|
|
||||||
|
- **Health telemetry** and **remote diagnostics** report device liveness,
|
||||||
|
calibration staleness (ADR-298), certificate expiry (ADR-315), and error
|
||||||
|
state — read-only diagnostics by default, mutations authorized explicitly.
|
||||||
|
- **Data retention** policy is enforced per cohort, and P0/CSI/person data never
|
||||||
|
leaves the edge except under the ADR-277/280 governance already in force
|
||||||
|
(CLAUDE.md: never commit or exfiltrate CSI/person data).
|
||||||
|
- Every lifecycle action — provision, rotate, revoke, stage, roll back — is
|
||||||
|
written as an **ADR-316 witness-chain** entry, giving a re-verifiable **audit
|
||||||
|
trail** rather than a mutable log.
|
||||||
|
|
||||||
|
### Authority and least privilege
|
||||||
|
|
||||||
|
- The control plane is default-deny (CLAUDE.md: default to least authority).
|
||||||
|
Provisioning, key rotation, revocation, staging, and rollback are each
|
||||||
|
separately authorized operations; no fleet action is implied by another.
|
||||||
|
Credentials and private keys are never logged or committed.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Hundreds of sensors become operable: coherent release identity, signed-artifact
|
||||||
|
distribution, staged updates with rollback, and a re-verifiable audit trail —
|
||||||
|
closing the release-identity / BOM gap the reviews raised.
|
||||||
|
- The plane concentrates operational authority; that is mitigated by
|
||||||
|
default-deny, per-action authorization, signed-only artifacts, and
|
||||||
|
witness-chained audit. A compromised plane must still forge signatures the
|
||||||
|
phase-1 spine verifies.
|
||||||
|
- Hard dependency on ADR-302 (identity), ADR-315 (certificate), ADR-298
|
||||||
|
(calibration lifecycle), ADR-316 (audit), and ADR-317 (firmware/HAL
|
||||||
|
compatibility). This ADR distributes and sequences those artifacts; it does
|
||||||
|
not redefine identity, certificates, calibration, or the witness format.
|
||||||
|
- Being phase 2, this is design intent depending on the spine; it is expected to
|
||||||
|
be revised as ADR-315, ADR-316, and ADR-317 land.
|
||||||
|
- **No fielded fleet-operation claim is MEASURED without real-silicon evidence**
|
||||||
|
(CLAUDE.md hardware rule): staged update and rollback on real nodes require a
|
||||||
|
captured runtime log. A passing simulation is not fleet evidence.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Unit tests: BOM records bind identity/firmware/model/certificate/calibration
|
||||||
|
consistently and reject inconsistent bindings; certificate issue/rotate/revoke
|
||||||
|
transitions are correct; a firmware-incompatible target is refused staging;
|
||||||
|
every lifecycle action emits a well-formed ADR-316 witness entry.
|
||||||
|
- Integration test: a synthetic cohort undergoes a canary→cohort→fleet staged
|
||||||
|
update; an injected health failure triggers rollback to the prior BOM; the
|
||||||
|
full sequence is re-verifiable from the witness chain offline; a revoked
|
||||||
|
certificate is rejected fleet-wide.
|
||||||
|
- Security test (`npm run test:security` analogue for the plane): default-deny
|
||||||
|
is enforced; unauthorized provision/rotate/revoke/stage is rejected and
|
||||||
|
counted; no credential or P0 data appears in telemetry or audit output.
|
||||||
|
- Field validation (deferred, real-silicon): a real multi-node staged update and
|
||||||
|
rollback with a captured boot/runtime log, reported as `MEASURED` with a
|
||||||
|
reproducer. Until then all fleet-operation results are simulator-level. No
|
||||||
|
fielded reliability number is asserted by this ADR.
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
# ADR-314: Multi-domain benchmark scorecard — regressions cannot hide behind pooled accuracy
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: benchmark, aetherarena, ci-gate, evidence, honesty, domain-generalization, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 17 of the perception-substrate program (ADR-297) and the
|
||||||
|
per-PR enforcement edge of the phase-1 certificate spine. In the ADR-297
|
||||||
|
dependency DAG it reads accuracy from the evidence engine (ADR-301), consumes
|
||||||
|
the domain state produced by out-of-distribution detection (ADR-299), scores
|
||||||
|
against calibration certificates (ADR-298), and is anchored in the witness chain
|
||||||
|
(ADR-316). It is the surface that makes the rest of the spine testable on every
|
||||||
|
change to sensing code.
|
||||||
|
|
||||||
|
A single pooled accuracy number is the classic way a domain-generalization
|
||||||
|
regression hides. A model can raise mean PCK or mean presence accuracy while
|
||||||
|
quietly collapsing on unseen rooms, unseen devices, or stationary subjects —
|
||||||
|
exactly the conditions WiFi sensing fails in and exactly the conditions a
|
||||||
|
pooled average washes out. The strategic assessment (ADR-297) named this: what
|
||||||
|
distinguishes infrastructure from a demo is that a regression on *any* operating
|
||||||
|
domain is caught before merge, not discovered in the field.
|
||||||
|
|
||||||
|
RuView does not need a new benchmark to do this. AetherArena is already
|
||||||
|
**v0-complete infrastructure** (ADR-149): a deterministic scoring engine
|
||||||
|
reusing `wifi-densepose-train` (`src/ruview_metrics.rs`, `src/ablation.rs`,
|
||||||
|
`src/eval.rs`, `src/proof.rs`), a `PROOF_SEED=42` determinism substrate that
|
||||||
|
SHA-256-hashes outputs against an expected hash, an append-only witness ledger,
|
||||||
|
and a live Hugging Face Space. ADR-145's ablation harness already computes
|
||||||
|
presence accuracy, localization error, FP/FN, latency percentiles, a
|
||||||
|
privacy-leakage score, and **cross-room degradation**. The board is
|
||||||
|
intentionally empty (benchmark-first). What is missing is not a scorer but a
|
||||||
|
**scorecard format** that reports per-domain rather than pooled, and a
|
||||||
|
**sensing-crate CI gate** that runs it on every PR.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Keep the single pooled score / `RuViewTier`.** Rejected: it is exactly the
|
||||||
|
surface a per-domain regression hides behind; a Gold tier can coexist with a
|
||||||
|
broken unseen-room slice.
|
||||||
|
2. **Add a new benchmark repo/harness for domains.** Rejected: AetherArena's
|
||||||
|
scorer, determinism binding, and witness ledger already exist and are the
|
||||||
|
right engine; a parallel harness would fork the scoring substrate and its
|
||||||
|
anti-gaming/leakage discipline.
|
||||||
|
3. **Extend the AetherArena scorer with a per-domain scorecard and wire it as a
|
||||||
|
per-PR sensing-crate gate.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Reuse the AetherArena scorer and witness ledger (ADR-149) and add two things: a
|
||||||
|
**multi-domain scorecard** format and a **sensing-crate PR gate** that produces
|
||||||
|
it.
|
||||||
|
|
||||||
|
### 1. The multi-domain scorecard
|
||||||
|
|
||||||
|
The scorecard reports each capability broken out by operating domain, never
|
||||||
|
pooled into one figure. The v0 domain axes:
|
||||||
|
|
||||||
|
- **Presence**: `room-known`, `room-unseen`, `device-unseen`, `stationary-10m`
|
||||||
|
(a stationary subject at range — the canonical WiFi failure case).
|
||||||
|
- **Pose**: `matched`, `subject-unseen`, `room-unseen`.
|
||||||
|
- **OOD rejection**: the rate at which genuinely out-of-distribution input is
|
||||||
|
correctly returned as UNKNOWN by ADR-299 (a capability, not a failure) and
|
||||||
|
the false-UNKNOWN rate on in-distribution input.
|
||||||
|
- **Calibration drift**: fingerprint-distance trajectory against the ADR-298
|
||||||
|
certificate over the scored window, and the fraction of inferences in each
|
||||||
|
ADR-299 `DomainState` (KNOWN / DEGRADED / UNKNOWN).
|
||||||
|
|
||||||
|
Each cell carries exactly one `EvidenceLevel` (L0–L5, ADR-282). A slice scored
|
||||||
|
on synthetic input is L0/`Synthetic` by construction; a slice on a leakage-free
|
||||||
|
held-out real split is graded higher and only then may a per-domain number be
|
||||||
|
labelled MEASURED. Pose PCK cells additionally require the mean-pose baseline
|
||||||
|
and a leakage-free held-out split (CLAUDE.md) or they are not reported as pose
|
||||||
|
accuracy at all.
|
||||||
|
|
||||||
|
### 2. Per-domain regression gate
|
||||||
|
|
||||||
|
- The gate compares each scorecard cell against the merged-baseline scorecard
|
||||||
|
stored in the AetherArena witness ledger. A regression **in any single
|
||||||
|
domain** beyond its configured threshold fails the PR, even if the pooled
|
||||||
|
average improved. Improvement on `room-known` cannot buy a regression on
|
||||||
|
`room-unseen`.
|
||||||
|
- Thresholds are per-domain and per-capability; the unseen/stationary/OOD
|
||||||
|
domains carry the strictest budgets because they are the ones a pooled score
|
||||||
|
hides. The baseline is append-only and witness-anchored — a new baseline is a
|
||||||
|
new signed ledger entry, never an in-place overwrite (ADR-149 ledger pattern,
|
||||||
|
ADR-316 anchoring).
|
||||||
|
|
||||||
|
### 3. Sensing-crate CI wiring
|
||||||
|
|
||||||
|
- Every PR that touches a sensing crate runs the scorecard across all domains
|
||||||
|
under the ADR-011/ADR-149 determinism binding (`PROOF_SEED=42`), so the run
|
||||||
|
is reproducible and tamper-evident. The gate is added to
|
||||||
|
`.github/workflows/` as an authoritative check.
|
||||||
|
- The held-out real split remains private and is never accessible to synthetic
|
||||||
|
generation, augmentation, or calibration (ADR-149 leakage constraint, ADR-282
|
||||||
|
rule d). Submitters/PRs provide a model, not predictions on data they hold.
|
||||||
|
|
||||||
|
### Provenance and honesty discipline
|
||||||
|
|
||||||
|
- No benchmark numbers are invented by this ADR. It delivers the scorecard
|
||||||
|
format, the per-domain gate, and the CI wiring; the numbers come from the
|
||||||
|
ADR-301 evidence ledger and the AetherArena scorer on real data, labelled at
|
||||||
|
the honest evidence level. Empty domains report "no evidence," which the gate
|
||||||
|
treats as no coverage — never as a pass.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- A domain-generalization regression can no longer merge behind a flattering
|
||||||
|
pooled average; the failure mode that most distinguishes fielded sensing from
|
||||||
|
a demo is caught at PR time.
|
||||||
|
- Every PR touching sensing pays a per-domain scoring cost. Bounded by reusing
|
||||||
|
the existing deterministic scorer and by tiered compute (CPU smoke vs full
|
||||||
|
score, ADR-149), but it is a deliberate cost for per-domain safety.
|
||||||
|
- The empty AetherArena board fills with honest, per-domain, evidence-labelled
|
||||||
|
results rather than a single headline tier — consistent with the
|
||||||
|
benchmark-first posture and with ADR-282's ecosystem positioning.
|
||||||
|
- Some domains will show weak or absent coverage. Surfacing that per-domain is
|
||||||
|
the point; the scorecard must never paper over a thin domain with a pooled
|
||||||
|
number.
|
||||||
|
- The program-level acceptance test (ADR-297) is encoded here as an AetherArena
|
||||||
|
scenario, closing the loop once the phase-1 spine lands.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test` on the AetherArena scorer extension — per-domain slicing math
|
||||||
|
against fixtures; per-domain regression gate fails on a single-domain
|
||||||
|
regression while pooled improves, and passes when all domains hold; empty
|
||||||
|
domains report "no evidence," not a pass; every cell carries exactly one
|
||||||
|
`EvidenceLevel`; synthetic slices are L0 by construction.
|
||||||
|
- Determinism: a scored run reproduces its SHA-256 hash under `PROOF_SEED=42`
|
||||||
|
(ADR-011/ADR-149 binding); the baseline scorecard is append-only and
|
||||||
|
witness-anchored (ADR-316), never mutated in place.
|
||||||
|
- CI: the sensing-crate gate runs on a PR touching a sensing crate and blocks a
|
||||||
|
planted single-domain regression.
|
||||||
|
- Real-data scorecards (a leakage-free held-out split with ADR-300 references)
|
||||||
|
are the maturity milestone; a synthetic scorecard is L0 and no per-domain
|
||||||
|
number is MEASURED without a reproducer per CLAUDE.md.
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
# ADR-315: Capability certificates — validated-for-this-environment claims
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: capability, certificate, evidence, provenance, signature, honesty, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 18 of the perception-substrate program (ADR-297) and,
|
||||||
|
per the strategic assessment, among the strongest ideas in the program: it is
|
||||||
|
where the whole certificate spine becomes a consumable contract. In the ADR-297
|
||||||
|
dependency DAG it **consumes the evidence engine (ADR-301)** — a capability
|
||||||
|
certificate is a signed attestation minted over a slice of that ledger — the
|
||||||
|
**calibration certificate (ADR-298)** for the environment it is validated
|
||||||
|
against, and the **RuField signature types (ADR-302 / ADR-260/262/277/279)** to
|
||||||
|
sign it. It reports domain state via ADR-299 and is anchored in the witness
|
||||||
|
chain (ADR-316).
|
||||||
|
|
||||||
|
RuView must stop making unconditional capability claims. "Supports presence" is
|
||||||
|
not a true statement — presence detection works in some rooms, on some hardware,
|
||||||
|
for some subject dynamics, and fails on a stationary subject at range in an
|
||||||
|
uncalibrated room. A capability is only ever *validated for a specific
|
||||||
|
environment*, and the honest unit of that claim is a signed, expiring
|
||||||
|
certificate, not a feature flag in a README.
|
||||||
|
|
||||||
|
The ingredients now exist across the phase-1 spine: ADR-301 accumulates
|
||||||
|
per-`(room, device, subject)` accuracy, false-positive rate, drift, and domain
|
||||||
|
state; ADR-298 produces the signed room fingerprint the environment is keyed to;
|
||||||
|
ADR-302 provides the authenticated device identity and `CapabilityAttestation`
|
||||||
|
(BFLD, ADR-141) that bounds *what a device is even attested to sense*; ADR-282
|
||||||
|
provides the mandatory `EvidenceLevel`. What is missing is the artifact that
|
||||||
|
binds them into a single, verifiable "validated here, until then" claim and the
|
||||||
|
consumer-side rule that refuses capabilities lacking one.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Static capability flags / a `supports_presence` boolean.** Rejected: it is
|
||||||
|
the exact dishonest claim — environment-independent, unsigned, non-expiring,
|
||||||
|
and false the moment the room, device, or subject dynamics differ.
|
||||||
|
2. **Report raw ledger accuracy to consumers directly.** Rejected: the ledger
|
||||||
|
(ADR-301) is the source of truth but not a portable, signed, bounded contract;
|
||||||
|
handing consumers raw records pushes evidence-weighting and expiry logic into
|
||||||
|
every consumer and drops the single verifiable object.
|
||||||
|
3. **Mint a signed, expiring `CapabilityCertificate` over an ADR-301 ledger
|
||||||
|
slice, and make consumers refuse capabilities without a valid one.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Introduce a signed **`CapabilityCertificate`**: a bounded attestation that a
|
||||||
|
specific capability has been validated for a specific environment, for a bounded
|
||||||
|
time.
|
||||||
|
|
||||||
|
### 1. The certificate
|
||||||
|
|
||||||
|
A serializable `CapabilityCertificate` binding:
|
||||||
|
|
||||||
|
- `capability` — the phenomenon (e.g. `presence`, `pose`), which must be within
|
||||||
|
the device's ADR-302/ADR-141 `CapabilityAttestation` (a device cannot be
|
||||||
|
certified for something it is not even attested to sense).
|
||||||
|
- `room` — the ADR-303 space identifier, tied to the ADR-298 calibration
|
||||||
|
certificate version the validation was performed against.
|
||||||
|
- `hardware` — the ADR-302 authenticated `DeviceId` (and, in phase 2, the
|
||||||
|
ADR-317 HAL descriptor of the sensor).
|
||||||
|
- `model` — the model version scored.
|
||||||
|
- `calibrated_date` — the calibration certificate age at validation time.
|
||||||
|
- `moving_recall`, `stationary_recall`, `false_presence_per_24h` — the measured
|
||||||
|
operating metrics, sliced from the ADR-301 ledger for this exact context (not
|
||||||
|
a global average), each honestly labelled. These are per-capability; a pose
|
||||||
|
certificate carries pose metrics with the mean-pose baseline and a
|
||||||
|
leakage-free split (CLAUDE.md) or it is not issued.
|
||||||
|
- `valid_until` — an explicit expiry; a certificate is never open-ended.
|
||||||
|
- `evidence_level` — exactly one L0–L5 (ADR-282). A certificate minted from a
|
||||||
|
synthetic ledger slice is L0/`Synthetic`; a MEASURED metric requires an
|
||||||
|
ADR-300 reference and a reproducer. The certificate cannot upgrade the level
|
||||||
|
of the ledger it is minted from (ADR-301 honesty rule).
|
||||||
|
- `signature` — a RuField `SignatureBlock` (ADR-302 / ADR-260/262/277/279) over
|
||||||
|
the canonical serialization; an unsigned certificate is not a valid
|
||||||
|
certificate. The certificate is anchored in the witness chain (ADR-316).
|
||||||
|
|
||||||
|
### 2. Minting
|
||||||
|
|
||||||
|
- A certificate is minted from a slice of the ADR-301 evidence ledger for one
|
||||||
|
`(room, device, subject-class, model)` context. If the ledger reports "no
|
||||||
|
evidence" for that context, **no certificate is issued** — absence of evidence
|
||||||
|
is never a capability. Minting is a pure function over the append-only ledger
|
||||||
|
at mint time; the metrics are frozen into the signed object.
|
||||||
|
- Expiry (`valid_until`) is derived from calibration validity (ADR-298) and an
|
||||||
|
evidence-freshness policy: a certificate cannot outlive the calibration it was
|
||||||
|
validated against, and drift beyond the ADR-298 envelope invalidates both.
|
||||||
|
|
||||||
|
### 3. Consumer refusal rule
|
||||||
|
|
||||||
|
- Applications and surfaces **refuse to consume a capability that lacks a valid
|
||||||
|
certificate for the current environment**. "Valid" means: signature verifies,
|
||||||
|
`room`/`hardware`/`model` match the running context, `valid_until` is in the
|
||||||
|
future, and the referenced calibration certificate is itself still valid
|
||||||
|
(ADR-298 not invalidated). A failed check yields UNKNOWN via ADR-299, not a
|
||||||
|
best-effort guess.
|
||||||
|
- This makes the ADR-297 acceptance clause "quantify whether it can reliably
|
||||||
|
sense the requested phenomenon → generate a signed capability certificate"
|
||||||
|
a hard gate rather than a hope.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- RuView can no longer claim a capability it has not validated for the caller's
|
||||||
|
environment; the honest failure — "not certified here" → UNKNOWN — is
|
||||||
|
surfaced by construction rather than by discipline.
|
||||||
|
- OEM/integrator diligence gets a single verifiable artifact ("presence,
|
||||||
|
validated in *this* room, on *this* device, with *these* recall/false-alarm
|
||||||
|
numbers, until *this* date, at *this* evidence level, signed") — the strongest
|
||||||
|
commercial output of the spine.
|
||||||
|
- Certificates expire and get refused; some environments will have no
|
||||||
|
certificate and therefore no capability until validated. That refusal is the
|
||||||
|
intended honest behavior, not a regression.
|
||||||
|
- Key management and expiry policy are operational responsibilities, reusing the
|
||||||
|
ADR-302 enrollment/rotation and ADR-298 validity machinery rather than new
|
||||||
|
infrastructure; fleet distribution of certificates is owned by ADR-313.
|
||||||
|
- No capability number is invented here; every metric on a certificate is sliced
|
||||||
|
from the ADR-301 ledger at its honest evidence level.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test` on the certificate crate — mint from a ledger slice produces the
|
||||||
|
frozen metrics; "no evidence" context yields no certificate; signature
|
||||||
|
round-trip and tamper rejection; `valid_until` and calibration-linked expiry
|
||||||
|
enforced; consumer refusal on room/hardware/model mismatch, expiry, or
|
||||||
|
invalidated calibration resolves to UNKNOWN (ADR-299), not a guess; evidence
|
||||||
|
level is inherited from the ledger and cannot be upgraded; a certificate
|
||||||
|
cannot be issued for a capability outside the device's ADR-302/ADR-141
|
||||||
|
attestation.
|
||||||
|
- Cross-ADR: an ADR-301 ledger fixture mints a certificate; an ADR-299 test
|
||||||
|
asserts an expired/mismatched certificate gates to UNKNOWN; the ADR-297
|
||||||
|
acceptance test consumes a minted certificate end-to-end.
|
||||||
|
- Real-deployment certificates (minted from a populated ledger with ADR-300
|
||||||
|
references on live ESP32 captures) are the maturity milestone and require
|
||||||
|
hardware evidence per CLAUDE.md; a certificate minted from a synthetic ledger
|
||||||
|
is L0 by construction.
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
# ADR-316: Witness chain — epistemic infrastructure for physical AI
|
||||||
|
|
||||||
|
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: provenance, witness, evidence, signature, epistemics, ontology, substrate
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 19 of the perception-substrate program (ADR-297) and a
|
||||||
|
spine root of its phase-1 certificate stack. In the ADR-297 dependency DAG it
|
||||||
|
**extends the source-provenance state machine (ADR-292)** and the RuField
|
||||||
|
provenance types, **ties to the signature machinery (ADR-302 /
|
||||||
|
ADR-260/262/277/279)**, and anchors the artifacts produced by ADR-298
|
||||||
|
(calibration certificates), ADR-301 (evidence records), ADR-314 (benchmark
|
||||||
|
scorecards), and ADR-315 (capability certificates). In phase 2 it carries the
|
||||||
|
independent-corroboration link from ADR-300.
|
||||||
|
|
||||||
|
The strategic assessment (ADR-297) framed RuView's real product as **epistemic
|
||||||
|
infrastructure for physical AI**: the value is not the claim "a person is
|
||||||
|
present" but the *auditable reasoning* behind it. A bare boolean output discards
|
||||||
|
everything a downstream system needs to trust or contest it — which radio
|
||||||
|
observed it, what DSP evidence supported it, which model inferred it, whether an
|
||||||
|
independent sensor agreed, what spatial state it updated, and what policy acted
|
||||||
|
on it. Once the answer is a boolean, "why do you believe that?" has no answer.
|
||||||
|
|
||||||
|
RuView already has the pieces of a chain but not the chain itself. ADR-292
|
||||||
|
defines a canonical `SourceState` (`Synthetic` / `LiveVerified` /
|
||||||
|
`LiveUnverified` / `Stale` / `Disconnected`) with `Unknown` structurally
|
||||||
|
forbidden from collapsing to live. ADR-302 defines the signed
|
||||||
|
`device → measurement → sequence → timestamp → … → signed event` chain of
|
||||||
|
custody. RuField carries `FrameProvenance`, `SemanticProvenance`, and signature
|
||||||
|
types; the AetherArena witness ledger (ADR-149) demonstrates an append-only,
|
||||||
|
witness-anchored ledger. What is missing is a single **staged, signed envelope**
|
||||||
|
that travels the whole pipeline and records, at each stage, the confidence and
|
||||||
|
provenance of that stage.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Keep provenance as scattered per-stage fields (status quo).** Rejected:
|
||||||
|
`FrameProvenance`, `SourceState`, calibration state, and model uncertainty
|
||||||
|
live in different structures and are re-encoded per surface; there is no
|
||||||
|
single object a consumer can re-verify offline to answer "why."
|
||||||
|
2. **Log a free-form audit trail alongside the output.** Rejected: mutable,
|
||||||
|
unsigned, and not structurally tied to the output — the classic
|
||||||
|
dashboard-that-overwrites-yesterday failure the evidence engine (ADR-301)
|
||||||
|
already rejects.
|
||||||
|
3. **A staged, signed witness envelope carried through the pipeline, each stage
|
||||||
|
appended and signed, anchored in an append-only ledger.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Define the **witness chain**: a staged, append-only, signed envelope that
|
||||||
|
accompanies an observation from radio to policy decision. Instead of emitting
|
||||||
|
"person present," RuView emits a chain whose stages are:
|
||||||
|
|
||||||
|
```
|
||||||
|
RF observation ▸ DSP evidence ▸ model inference ▸ independent corroboration
|
||||||
|
▸ spatial state ▸ policy decision
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1. The staged envelope
|
||||||
|
|
||||||
|
- Each stage is a signed record carrying its **confidence** and its
|
||||||
|
**provenance**:
|
||||||
|
- **RF observation** — the ADR-302 authenticated frame envelope
|
||||||
|
(`DeviceId`, sequence, timestamp, measurement hash) and its ADR-292
|
||||||
|
`SourceState`. This is the root link; a `Synthetic` root can never present
|
||||||
|
as a `LiveVerified` one (ADR-292 invariant).
|
||||||
|
- **DSP evidence** — the deterministic signal features and the ADR-137
|
||||||
|
quality signals that support (or fail to support) an inference.
|
||||||
|
- **model inference** — the model version, its raw output, and its predictive
|
||||||
|
uncertainty; the ADR-299 `DomainState` (KNOWN / DEGRADED / UNKNOWN) gate
|
||||||
|
result, so a low-confidence or out-of-distribution inference is recorded as
|
||||||
|
such, not silently promoted.
|
||||||
|
- **independent corroboration** — the phase-2 ADR-300 agreement link
|
||||||
|
(a reference/second modality that agreed or disagreed); absent in phase 1,
|
||||||
|
the stage records "no corroboration," never a fabricated one.
|
||||||
|
- **spatial state** — the ADR-303 ontology `Observation`/`Track`/`Event` the
|
||||||
|
inference updated, carrying `SemanticProvenance` and its `EvidenceLevel`.
|
||||||
|
- **policy decision** — the governed action taken (or withheld), with the
|
||||||
|
certificate (ADR-315) it relied on.
|
||||||
|
- Each stage carries exactly one `EvidenceLevel` (L0–L5, ADR-282); the envelope's
|
||||||
|
effective level is the **minimum** across its stages — a synthetic root or an
|
||||||
|
unreferenced inference caps the whole chain, so the chain cannot claim more
|
||||||
|
than its weakest link.
|
||||||
|
|
||||||
|
### 2. Signing and anchoring
|
||||||
|
|
||||||
|
- Each stage is signed with RuField signature types (ADR-302 /
|
||||||
|
ADR-260/262/277/279) over the canonical serialization of that stage plus the
|
||||||
|
hash of the prior stage, so the chain is tamper-evident end to end and any
|
||||||
|
broken link is detectable. The completed chain is anchored in an append-only,
|
||||||
|
witness-anchored ledger following the AetherArena pattern (ADR-149); it is the
|
||||||
|
same anchoring ADR-298/ADR-301/ADR-314/ADR-315 write into.
|
||||||
|
- The chain is **append-only**: a correction is a new chain referencing the
|
||||||
|
prior one, never an in-place edit (mirroring ADR-301 and CLAUDE.md's "source
|
||||||
|
over summaries").
|
||||||
|
|
||||||
|
### 3. Offline re-verification
|
||||||
|
|
||||||
|
- A consumer with the enrolled public keys (ADR-302) can re-verify a chain
|
||||||
|
offline: check each stage signature, check each prior-stage hash, and read the
|
||||||
|
per-stage confidence and evidence level — answering "why do you believe this?"
|
||||||
|
without trusting the emitting host. This is the property store-and-forward
|
||||||
|
channel authentication (rejected in ADR-302) cannot provide.
|
||||||
|
|
||||||
|
### Provenance and honesty discipline
|
||||||
|
|
||||||
|
- The witness chain never manufactures confidence: a stage that lacks evidence
|
||||||
|
records the absence. A `Synthetic` root, a missing corroboration, or an
|
||||||
|
UNKNOWN gate is carried faithfully and caps the chain's evidence level. No
|
||||||
|
accuracy number is invented here; the chain records the numbers the other
|
||||||
|
primitives produce at their honest level.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Every RuView output becomes contestable and auditable: a downstream physical-AI
|
||||||
|
system can inspect the reasoning, weight it by per-stage confidence, and reject
|
||||||
|
a chain whose weakest link is too weak — the defining property of epistemic
|
||||||
|
infrastructure the strategic assessment asked for.
|
||||||
|
- The certificate spine (ADR-298/301/314/315) gains a single anchoring substrate;
|
||||||
|
each of those artifacts is a specialization of a witness record rather than a
|
||||||
|
bespoke signed blob.
|
||||||
|
- Carrying and signing a staged envelope adds per-observation size and CPU cost;
|
||||||
|
bounded by reusing RuField signatures and the existing ledger, and by the
|
||||||
|
minimum-level rule keeping the object honest rather than exhaustive.
|
||||||
|
- The chain will frequently reveal weak links (synthetic root, no corroboration,
|
||||||
|
DEGRADED gate). Surfacing that is the point; the envelope must never smooth a
|
||||||
|
weak stage into a confident summary.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test` on the witness-chain crate — stage-by-stage signature round-trip
|
||||||
|
and tamper rejection (a mutated stage or a broken prior-stage hash fails
|
||||||
|
verification); effective evidence level equals the minimum across stages; a
|
||||||
|
`Synthetic` root caps the chain and cannot present as `LiveVerified`
|
||||||
|
(ADR-292 invariant); an UNKNOWN gate (ADR-299) and a "no corroboration" stage
|
||||||
|
are recorded faithfully; append-only correction produces a new chain
|
||||||
|
referencing the prior one.
|
||||||
|
- Cross-ADR: an ADR-302 signed frame lineage serializes into a chain that
|
||||||
|
re-verifies offline with only the enrolled public keys; ADR-298/301/314/315
|
||||||
|
artifacts anchor into the same ledger.
|
||||||
|
- Real-deployment chains (from live ESP32 captures with ADR-300 corroboration)
|
||||||
|
are the maturity milestone and require hardware evidence per CLAUDE.md; a
|
||||||
|
chain rooted in synthetic input is L0 by construction.
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
# ADR-317: RuView sensor HAL — abstract all sensing hardware to one Observation type
|
||||||
|
|
||||||
|
- **Status**: Proposed (ADR-297 phase 2)
|
||||||
|
- **Date**: 2026-08-11
|
||||||
|
- **Deciders**: ruv
|
||||||
|
- **Tags**: hal, sensor-abstraction, ontology, fusion, adapters, category, phase-2
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
This ADR is primitive 20 of the perception-substrate program (ADR-297) and a
|
||||||
|
phase-2 integration primitive; it is authored as **Proposed**. In the ADR-297
|
||||||
|
DAG it **consumes the canonical spatial ontology (ADR-303)** — its output is an
|
||||||
|
ontology `Observation` bound to a `Sensor` entity — and **feeds real sensor
|
||||||
|
fusion (ADR-308)**, which resolves many observations into one world state. It
|
||||||
|
closes the "identify the hardware" clause of the ADR-297 acceptance test that
|
||||||
|
phase 1 leaves open.
|
||||||
|
|
||||||
|
RuView's strategic ceiling is set by how tightly it is coupled to WiFi CSI.
|
||||||
|
Every new modality today lands as a bespoke ingest path with its own frame
|
||||||
|
shape, its own provenance handling, and its own place in the pipeline. That is
|
||||||
|
the difference between "a WiFi-DensePose project" and "an open
|
||||||
|
spatial-intelligence operating layer": the category changes the moment *any*
|
||||||
|
sensing hardware — {CSI, 802.11bf, BLE, UWB, mmWave, acoustic, camera, lidar,
|
||||||
|
IMU, custom} — enters through one abstraction and becomes one `Observation`
|
||||||
|
feeding one world model.
|
||||||
|
|
||||||
|
Crucially this is a *unification*, not a green field. Adapters already exist and
|
||||||
|
must be reused, not rebuilt:
|
||||||
|
|
||||||
|
- ADR-279's native RF frame contract (`RfFrameV2`) already unifies ESP32,
|
||||||
|
Intel, Atheros, PicoScenes, Realtek radar, and 320 MHz 802.11bk producers as
|
||||||
|
`RfFrameV2` producers into a shared latent — "lightweight per-device adapters
|
||||||
|
into a shared latent, not a shared tensor." The HAL generalizes that lesson
|
||||||
|
beyond RF.
|
||||||
|
- Existing CSI adapters (ESP32/Nexmon/FeitCSI paths), the mmWave fusion path
|
||||||
|
(ADR-063), and the multistatic WiFi path (ADR-029) are concrete producers to
|
||||||
|
bring under one trait.
|
||||||
|
- ADR-302 already authenticates a `Sensor`/`DeviceId`; ADR-303 already defines
|
||||||
|
`Sensor`, `Observation`, `Track`, and `Event` as first-class node types. The
|
||||||
|
HAL is the trait that turns a heterogeneous device into that authenticated
|
||||||
|
`Sensor` emitting those `Observation`s.
|
||||||
|
|
||||||
|
The gap is a single **`SensorHal` trait and one `Observation` type** that every
|
||||||
|
modality implements, so the world model never sees a modality-specific frame —
|
||||||
|
only a provenance-bearing, evidence-labelled `Observation`.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
1. **Continue adding per-modality ingest paths.** Rejected: O(modalities) bespoke
|
||||||
|
pipelines, each re-encoding provenance and evidence, each a place the ladder
|
||||||
|
can be dropped — and it keeps RuView categorically a WiFi project.
|
||||||
|
2. **Force every modality into the ADR-274/279 RF tensor/frame.** Rejected: the
|
||||||
|
ADR-279 lesson is precisely that premature canonicalization discards
|
||||||
|
information (bandwidth, antenna structure, phase). A camera, lidar, or IMU
|
||||||
|
has no meaningful `RfFrameV2` projection; forcing one is the same mistake at a
|
||||||
|
larger scale.
|
||||||
|
3. **Define a `SensorHal` trait producing one `Observation` type, with existing
|
||||||
|
adapters as implementations feeding a shared latent and the ADR-303
|
||||||
|
ontology.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Introduce a **`SensorHal` trait** and a single **`Observation`** type. Every
|
||||||
|
sensing modality is an implementation of the trait; the world model consumes
|
||||||
|
only `Observation`s.
|
||||||
|
|
||||||
|
### 1. The `SensorHal` trait
|
||||||
|
|
||||||
|
- A `SensorHal` describes a device's **capabilities** (which phenomena it can
|
||||||
|
sense — reusing the ADR-302/ADR-141 `CapabilityAttestation`), its **native
|
||||||
|
frame** (kept native, not canonicalized, per the ADR-279 shared-latent
|
||||||
|
lesson), and a method that lifts a native frame into an `Observation`.
|
||||||
|
- Implementations wrap the existing producers: CSI (ESP32/Nexmon/FeitCSI via the
|
||||||
|
ADR-279 `RfFrameV2` path), 802.11bf (ADR-307, phase 2), BLE, UWB, mmWave
|
||||||
|
(ADR-063), acoustic, camera, lidar, IMU, and `custom`. RF modalities reuse the
|
||||||
|
ADR-279 per-device latent adapters wholesale; the HAL adds the non-RF and
|
||||||
|
ranging modalities under the same trait.
|
||||||
|
- The trait is the boundary where untrusted hardware input is validated
|
||||||
|
(CLAUDE.md: validate at every hardware/FFI boundary; default to least
|
||||||
|
authority). A device is authenticated as an ADR-302 `Sensor` before its
|
||||||
|
observations are trusted.
|
||||||
|
|
||||||
|
### 2. The `Observation` type
|
||||||
|
|
||||||
|
- One provenance-bearing `Observation`: a measurement plus its `SensorHal`
|
||||||
|
source descriptor, its ADR-302 authenticated `DeviceId`, its ADR-292
|
||||||
|
`SourceState`, its native-frame reference (not a lossy projection), and
|
||||||
|
exactly one `EvidenceLevel` (L0–L5, ADR-282). A camera-derived `Observation`
|
||||||
|
and a CSI-derived `Observation` are the same type with different provenance —
|
||||||
|
and a camera observation never lifts WiFi output to camera-grade; each carries
|
||||||
|
its own honest evidence level (CLAUDE.md: never present WiFi sensing as
|
||||||
|
camera-grade).
|
||||||
|
- The `Observation` maps directly onto the ADR-303 ontology `Observation` node
|
||||||
|
attached to its `Sensor`, so the ontology is the one representation and the
|
||||||
|
HAL is its ingest funnel.
|
||||||
|
|
||||||
|
### 3. Feeding fusion
|
||||||
|
|
||||||
|
- Observations from any set of modalities flow into ADR-308 fusion, which
|
||||||
|
resolves them into one probabilistic world state. The HAL guarantees fusion
|
||||||
|
never sees a modality-specific frame — only `Observation`s with uniform
|
||||||
|
provenance and evidence — which is what makes ADR-308's "many observations →
|
||||||
|
one world state" invariant implementable across heterogeneous hardware.
|
||||||
|
|
||||||
|
### Category and honesty discipline
|
||||||
|
|
||||||
|
- This ADR changes RuView's category from a WiFi-DensePose pipeline to an open
|
||||||
|
spatial-intelligence operating layer, but it makes **no accuracy claim**: the
|
||||||
|
HAL delivers a uniform ingest boundary, not a detector. Any capability of a
|
||||||
|
newly-connected sensor is still gated by ADR-299 and certified by ADR-315 for
|
||||||
|
its specific environment — connecting a camera does not grant a validated
|
||||||
|
capability by itself.
|
||||||
|
- Hardware support for a given modality is CLAIMED until demonstrated on real
|
||||||
|
silicon with captured evidence per CLAUDE.md; a passing trait test proves the
|
||||||
|
abstraction, not a fielded device.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- New sensing hardware lands as one `SensorHal` implementation instead of a
|
||||||
|
bespoke pipeline; the translation matrix stays O(modalities), mirroring how
|
||||||
|
ADR-303 collapsed the surface matrix.
|
||||||
|
- The ADR-297 acceptance clause "identify the hardware" becomes implementable:
|
||||||
|
a new sensor type is described by its HAL, authenticated as an ADR-302
|
||||||
|
`Sensor`, calibrated (ADR-298), gated (ADR-299), and certified (ADR-315)
|
||||||
|
through the same phase-1 spine, closing the last open clause.
|
||||||
|
- A trait boundary and an `Observation` type are added; existing RF adapters
|
||||||
|
are re-expressed as implementations rather than rewritten, preserving the
|
||||||
|
ADR-279 native-frame/shared-latent design.
|
||||||
|
- Non-RF modalities (camera, lidar, acoustic) enter the governed plane with the
|
||||||
|
same provenance and privacy discipline as RF; a camera is not a privacy-free
|
||||||
|
shortcut — it inherits the ADR-277 governance and its own evidence level.
|
||||||
|
- As a phase-2 Proposed ADR, the trait shape may be revised as ADR-308 fusion
|
||||||
|
and ADR-307 802.11bf land; that revision is expected for a phased program.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `cargo test` on the HAL crate (design-time, Proposed) — a fixture `SensorHal`
|
||||||
|
for each of at least two modalities (CSI via ADR-279, plus one non-RF)
|
||||||
|
produces uniform `Observation`s; every `Observation` carries a `DeviceId`,
|
||||||
|
`SourceState`, native-frame reference, and exactly one `EvidenceLevel`; a
|
||||||
|
synthetic source yields L0/`Synthetic` and cannot alias to measured
|
||||||
|
(ADR-279 invariant 6); an unauthenticated device's observations are rejected
|
||||||
|
at the trait boundary (ADR-302).
|
||||||
|
- Cross-ADR: an `Observation` maps round-trip to an ADR-303 ontology
|
||||||
|
`Observation` node with no provenance loss, and a set of `Observation`s from
|
||||||
|
distinct modalities is accepted by an ADR-308 fusion fixture.
|
||||||
|
- Real-silicon evidence is required before any modality's hardware support is
|
||||||
|
claimed beyond CLAIMED: a captured boot/runtime log from the real device
|
||||||
|
emitting `Observation`s. A successful build or simulator run is not hardware
|
||||||
|
evidence (CLAUDE.md).
|
||||||
@@ -155,6 +155,26 @@ Statuses: **Proposed** (under discussion), **Accepted** (approved and/or impleme
|
|||||||
| [ADR-295](ADR-295-model-release-sanity-gates.md) | Model release sanity gates — block degenerate and mislabeled model artifacts | Accepted (initial implementation) |
|
| [ADR-295](ADR-295-model-release-sanity-gates.md) | Model release sanity gates — block degenerate and mislabeled model artifacts | Accepted (initial implementation) |
|
||||||
| [ADR-296](ADR-296-csi-data-incident-repo-controls.md) | Repository CSI data-incident controls — ignore rules and pre-commit/CI policy check | Accepted (controls implemented; tree remediation gated) |
|
| [ADR-296](ADR-296-csi-data-incident-repo-controls.md) | Repository CSI data-incident controls — ignore rules and pre-commit/CI policy check | Accepted (controls implemented; tree remediation gated) |
|
||||||
| [ADR-297](ADR-297-perception-substrate-program.md) | RuView perception substrate — phased 20-primitive program (calibration, evidence, trust, deployment) | Accepted (program; children ADR-298..317) |
|
| [ADR-297](ADR-297-perception-substrate-program.md) | RuView perception substrate — phased 20-primitive program (calibration, evidence, trust, deployment) | Accepted (program; children ADR-298..317) |
|
||||||
|
| [ADR-298](ADR-298-automatic-domain-calibration.md) | Automatic domain calibration — signed, versioned, invalidatable room fingerprint | Accepted (phase 1) |
|
||||||
|
| [ADR-299](ADR-299-out-of-distribution-detection.md) | Out-of-distribution detection — KNOWN / DEGRADED / UNKNOWN gating | Accepted (phase 1) |
|
||||||
|
| [ADR-300](ADR-300-ground-truth-synchronization.md) | Ground-truth synchronization — reference sensors as a formal validation plane | Proposed (phase 2) |
|
||||||
|
| [ADR-301](ADR-301-evidence-engine.md) | Evidence engine — per-(room,device,subject) accuracy ledger | Accepted (phase 1) |
|
||||||
|
| [ADR-302](ADR-302-authenticated-sensor-identity.md) | Authenticated sensor identity — RF chain of custody | Accepted (phase 1) |
|
||||||
|
| [ADR-303](ADR-303-canonical-spatial-ontology.md) | Canonical spatial ontology — one Site→…→Event model for every surface | Accepted (phase 1) |
|
||||||
|
| [ADR-304](ADR-304-persistent-identity-tracking.md) | Persistent identity & tracking — privacy-preserving probabilistic tracks | Proposed (phase 2) |
|
||||||
|
| [ADR-305](ADR-305-sensor-placement-optimizer.md) | Sensor placement optimizer — floorplan + inventory → recommended positions | Proposed (phase 3) |
|
||||||
|
| [ADR-306](ADR-306-active-sensing.md) | Active sensing — closed-loop RF experiment control | Proposed (phase 3) |
|
||||||
|
| [ADR-307](ADR-307-80211bf-native-architecture.md) | 802.11bf-native architecture — standardized WLAN sensing as native measurement types | Proposed (phase 2) |
|
||||||
|
| [ADR-308](ADR-308-real-sensor-fusion.md) | Real sensor fusion — uncertainty-aware, multiple observations → one world state | Proposed (phase 2) |
|
||||||
|
| [ADR-309](ADR-309-long-term-spatial-memory.md) | Long-term spatial memory — learn the normal physics of a location | Proposed (phase 3) |
|
||||||
|
| [ADR-310](ADR-310-counterfactual-inference.md) | Counterfactual inference — generative spatial reasoning | Proposed (phase 3) |
|
||||||
|
| [ADR-311](ADR-311-information-gain-scheduler.md) | Information-gain scheduler — sample the most informative radios | Proposed (phase 3) |
|
||||||
|
| [ADR-312](ADR-312-digital-rf-twin.md) | Digital RF twin — persistent per-deployment RF model | Proposed (phase 3) |
|
||||||
|
| [ADR-313](ADR-313-fleet-control-plane.md) | Fleet control plane — provisioning to audit trails | Proposed (phase 2) |
|
||||||
|
| [ADR-314](ADR-314-benchmark-multi-domain-scorecard.md) | Multi-domain benchmark scorecard — regressions cannot hide behind pooled accuracy | Accepted (phase 1) |
|
||||||
|
| [ADR-315](ADR-315-capability-certificates.md) | Capability certificates — validated-for-this-environment claims | Accepted (phase 1) |
|
||||||
|
| [ADR-316](ADR-316-witness-chain.md) | Witness chain — staged, signed epistemic envelope | Accepted (phase 1) |
|
||||||
|
| [ADR-317](ADR-317-sensor-hal.md) | RuView sensor HAL — abstract all sensing hardware to one Observation type | Proposed (phase 2) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user