From 559ad56aa4e2e6a0fada7698cb1e37e3b9d7baac Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 11 Aug 2026 00:30:00 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20ADR-298..317=20=E2=80=94=2020=20child?= =?UTF-8?q?=20ADRs=20of=20the=20perception-substrate=20program?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS --- .../ADR-298-automatic-domain-calibration.md | 149 ++++++++++++++++ .../ADR-299-out-of-distribution-detection.md | 135 +++++++++++++++ .../ADR-300-ground-truth-synchronization.md | 125 ++++++++++++++ docs/adr/ADR-301-evidence-engine.md | 117 +++++++++++++ .../ADR-302-authenticated-sensor-identity.md | 147 ++++++++++++++++ .../adr/ADR-303-canonical-spatial-ontology.md | 142 ++++++++++++++++ .../ADR-304-persistent-identity-tracking.md | 135 +++++++++++++++ .../adr/ADR-305-sensor-placement-optimizer.md | 138 +++++++++++++++ docs/adr/ADR-306-active-sensing.md | 152 +++++++++++++++++ .../ADR-307-80211bf-native-architecture.md | 147 ++++++++++++++++ docs/adr/ADR-308-real-sensor-fusion.md | 140 +++++++++++++++ docs/adr/ADR-309-long-term-spatial-memory.md | 146 ++++++++++++++++ docs/adr/ADR-310-counterfactual-inference.md | 142 ++++++++++++++++ .../adr/ADR-311-information-gain-scheduler.md | 138 +++++++++++++++ docs/adr/ADR-312-digital-rf-twin.md | 159 ++++++++++++++++++ docs/adr/ADR-313-fleet-control-plane.md | 156 +++++++++++++++++ ...DR-314-benchmark-multi-domain-scorecard.md | 140 +++++++++++++++ docs/adr/ADR-315-capability-certificates.md | 138 +++++++++++++++ docs/adr/ADR-316-witness-chain.md | 146 ++++++++++++++++ docs/adr/ADR-317-sensor-hal.md | 150 +++++++++++++++++ docs/adr/README.md | 20 +++ 21 files changed, 2862 insertions(+) create mode 100644 docs/adr/ADR-298-automatic-domain-calibration.md create mode 100644 docs/adr/ADR-299-out-of-distribution-detection.md create mode 100644 docs/adr/ADR-300-ground-truth-synchronization.md create mode 100644 docs/adr/ADR-301-evidence-engine.md create mode 100644 docs/adr/ADR-302-authenticated-sensor-identity.md create mode 100644 docs/adr/ADR-303-canonical-spatial-ontology.md create mode 100644 docs/adr/ADR-304-persistent-identity-tracking.md create mode 100644 docs/adr/ADR-305-sensor-placement-optimizer.md create mode 100644 docs/adr/ADR-306-active-sensing.md create mode 100644 docs/adr/ADR-307-80211bf-native-architecture.md create mode 100644 docs/adr/ADR-308-real-sensor-fusion.md create mode 100644 docs/adr/ADR-309-long-term-spatial-memory.md create mode 100644 docs/adr/ADR-310-counterfactual-inference.md create mode 100644 docs/adr/ADR-311-information-gain-scheduler.md create mode 100644 docs/adr/ADR-312-digital-rf-twin.md create mode 100644 docs/adr/ADR-313-fleet-control-plane.md create mode 100644 docs/adr/ADR-314-benchmark-multi-domain-scorecard.md create mode 100644 docs/adr/ADR-315-capability-certificates.md create mode 100644 docs/adr/ADR-316-witness-chain.md create mode 100644 docs/adr/ADR-317-sensor-hal.md diff --git a/docs/adr/ADR-298-automatic-domain-calibration.md b/docs/adr/ADR-298-automatic-domain-calibration.md new file mode 100644 index 00000000..be7b386a --- /dev/null +++ b/docs/adr/ADR-298-automatic-domain-calibration.md @@ -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. diff --git a/docs/adr/ADR-299-out-of-distribution-detection.md b/docs/adr/ADR-299-out-of-distribution-detection.md new file mode 100644 index 00000000..afbd4651 --- /dev/null +++ b/docs/adr/ADR-299-out-of-distribution-detection.md @@ -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. diff --git a/docs/adr/ADR-300-ground-truth-synchronization.md b/docs/adr/ADR-300-ground-truth-synchronization.md new file mode 100644 index 00000000..fe365b20 --- /dev/null +++ b/docs/adr/ADR-300-ground-truth-synchronization.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. diff --git a/docs/adr/ADR-301-evidence-engine.md b/docs/adr/ADR-301-evidence-engine.md new file mode 100644 index 00000000..2a801c1b --- /dev/null +++ b/docs/adr/ADR-301-evidence-engine.md @@ -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. diff --git a/docs/adr/ADR-302-authenticated-sensor-identity.md b/docs/adr/ADR-302-authenticated-sensor-identity.md new file mode 100644 index 00000000..d46565b7 --- /dev/null +++ b/docs/adr/ADR-302-authenticated-sensor-identity.md @@ -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. diff --git a/docs/adr/ADR-303-canonical-spatial-ontology.md b/docs/adr/ADR-303-canonical-spatial-ontology.md new file mode 100644 index 00000000..d7ccb1a0 --- /dev/null +++ b/docs/adr/ADR-303-canonical-spatial-ontology.md @@ -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. diff --git a/docs/adr/ADR-304-persistent-identity-tracking.md b/docs/adr/ADR-304-persistent-identity-tracking.md new file mode 100644 index 00000000..c3bde2b6 --- /dev/null +++ b/docs/adr/ADR-304-persistent-identity-tracking.md @@ -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. diff --git a/docs/adr/ADR-305-sensor-placement-optimizer.md b/docs/adr/ADR-305-sensor-placement-optimizer.md new file mode 100644 index 00000000..31a4a815 --- /dev/null +++ b/docs/adr/ADR-305-sensor-placement-optimizer.md @@ -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. diff --git a/docs/adr/ADR-306-active-sensing.md b/docs/adr/ADR-306-active-sensing.md new file mode 100644 index 00000000..0799d493 --- /dev/null +++ b/docs/adr/ADR-306-active-sensing.md @@ -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. diff --git a/docs/adr/ADR-307-80211bf-native-architecture.md b/docs/adr/ADR-307-80211bf-native-architecture.md new file mode 100644 index 00000000..e9ab3211 --- /dev/null +++ b/docs/adr/ADR-307-80211bf-native-architecture.md @@ -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. diff --git a/docs/adr/ADR-308-real-sensor-fusion.md b/docs/adr/ADR-308-real-sensor-fusion.md new file mode 100644 index 00000000..1abe7bc8 --- /dev/null +++ b/docs/adr/ADR-308-real-sensor-fusion.md @@ -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. diff --git a/docs/adr/ADR-309-long-term-spatial-memory.md b/docs/adr/ADR-309-long-term-spatial-memory.md new file mode 100644 index 00000000..1830b412 --- /dev/null +++ b/docs/adr/ADR-309-long-term-spatial-memory.md @@ -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. diff --git a/docs/adr/ADR-310-counterfactual-inference.md b/docs/adr/ADR-310-counterfactual-inference.md new file mode 100644 index 00000000..cc016db1 --- /dev/null +++ b/docs/adr/ADR-310-counterfactual-inference.md @@ -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. diff --git a/docs/adr/ADR-311-information-gain-scheduler.md b/docs/adr/ADR-311-information-gain-scheduler.md new file mode 100644 index 00000000..ac200dc1 --- /dev/null +++ b/docs/adr/ADR-311-information-gain-scheduler.md @@ -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. diff --git a/docs/adr/ADR-312-digital-rf-twin.md b/docs/adr/ADR-312-digital-rf-twin.md new file mode 100644 index 00000000..ac1f5158 --- /dev/null +++ b/docs/adr/ADR-312-digital-rf-twin.md @@ -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. diff --git a/docs/adr/ADR-313-fleet-control-plane.md b/docs/adr/ADR-313-fleet-control-plane.md new file mode 100644 index 00000000..0b386797 --- /dev/null +++ b/docs/adr/ADR-313-fleet-control-plane.md @@ -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. diff --git a/docs/adr/ADR-314-benchmark-multi-domain-scorecard.md b/docs/adr/ADR-314-benchmark-multi-domain-scorecard.md new file mode 100644 index 00000000..23f881b1 --- /dev/null +++ b/docs/adr/ADR-314-benchmark-multi-domain-scorecard.md @@ -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. diff --git a/docs/adr/ADR-315-capability-certificates.md b/docs/adr/ADR-315-capability-certificates.md new file mode 100644 index 00000000..4fc5f242 --- /dev/null +++ b/docs/adr/ADR-315-capability-certificates.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. diff --git a/docs/adr/ADR-316-witness-chain.md b/docs/adr/ADR-316-witness-chain.md new file mode 100644 index 00000000..672b2e2c --- /dev/null +++ b/docs/adr/ADR-316-witness-chain.md @@ -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. diff --git a/docs/adr/ADR-317-sensor-hal.md b/docs/adr/ADR-317-sensor-hal.md new file mode 100644 index 00000000..a35a6b6f --- /dev/null +++ b/docs/adr/ADR-317-sensor-hal.md @@ -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). diff --git a/docs/adr/README.md b/docs/adr/README.md index ccd0a62a..dca701d4 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.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-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-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) | ---