Files
ruvnet--RuView/docs/adr/ADR-279-native-rf-frame-contract.md
T
Claude 9aae7f04ff feat(ruview-unified): native frame contract + programmable perception (ADR-279..282)
Second increment of the unified RF spatial world model, applying the
architectural correction that the 56-bin canonical tensor must not be
the authoritative format, and moving the control plane from passive
sensing to programmable perception.

- RfFrameV2 (ADR-279): authoritative native RF record — native complex
  IQ preserved (proven byte-untouched by the derived view), explicit
  validity masks, declared PhaseState, TX/RX poses + antenna geometry,
  calibration/quality state, and construction-time provenance rules:
  Synthetic ⇒ L0Simulation, Measured ⇒ ≥ L1CapturedReplay (the L0–L5
  evidence ladder is now a type). Canonical tensor demoted to a
  mask-aware derived view through the shared adapter normalization.
  New modalities: WifiCir, WifiBfReport, FmcwRangeAzimuth,
  FmcwDopplerAzimuth. IEEE P3162 synthetic-aperture import profile.
- Active sensing control plane (ADR-280, control.rs): SensingTask
  admission (raw export always refused; identity requires consent),
  SensingAction/InformationGoal, age-of-information planner with
  measured 95% sensing-traffic reduction vs uniform refresh,
  fail-closed CoherentSensorGroup fusion (time/phase/geometry bounds,
  five denial paths tested), policy-authorized RIS actuation receipts,
  purpose-scoped TaskSufficientRepresentation leakage validation.
- BLE Channel Sounding (ADR-281): adapter + ble_cs_range with
  phase-slope and RTT as separate cross-validated evidence — exact
  recovery on synthetic tones, relay-style divergence flagged instead
  of averaged. Delay-Doppler-native FieldAxis + delay_doppler_map
  (unit-peak tone test).
- Factorized pose (ADR-281, RePos): relative skeleton on the content
  representation, root on the geometry-conditioned one, calibrated
  per-joint uncertainties; room-shortcut leakage experiment: held-out
  MPJPE 0.0003 m vs 0.2534 m monolithic; 740 params (<2% structured
  budget). Age gate input now log(1+age_ms); gradient check re-proven.
- Gaussian primitives: first_seen_ns, doppler_variance, bounded
  source_receipts lineage merged on fusion. PartitionKey gains a
  session dimension; SplitManifest certifies disjointness across all
  seven leakage dimensions.
- ADR-282: ecosystem positioning — RuView as the edge RF perception
  runtime under RuField/RuVector/MetaHarness; evidence-ladder policy.

Validation: ruview-unified 84 unit + 3 acceptance tests, 0 failed,
clippy-clean; workspace 3,789 passed 0 failed (--exclude
wifi-densepose-desktop, GTK headers unavailable in container); Python
proof VERDICT PASS. Docker images unaffected: no shipped binary
consumes this crate yet (Dockerfile.rust builds sensing-server /
cog-ha-matter / homecore-server only; Dockerfile.python builds
untouched archive/v1).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Q1R5zhz6sSfXGRXpgBwpFX
2026-07-26 19:29:18 +00:00

55 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-279: Native RF frame contract — `RfFrameV2` is authoritative, the canonical tensor is a derived view
| Field | Value |
|-------|-------|
| **Status** | Accepted — **implemented** (`ruview-unified/src/frame.rs`; 5 invariant tests) |
| **Date** | 2026-07-26 |
| **Parent** | ADR-273 (amends ADR-274 §2) |
| **Relates to** | ADR-136 (`CanonicalFrame` — extended, not replaced), ADR-262 (provenance discipline), ADR-282 (evidence ladder policy) |
## 0. PROOF discipline
Grades per ADR-273 §0. This ADR is a **correction** to ADR-274 §2, adopted before any measured-data debt accumulates.
## 1. Context — the architectural correction
ADR-274 made the 56-bin × 8-snapshot canonical `RfTensor` the adapter output, which is right for *compatibility* but wrong as the *authoritative* format: resampling every device into one fixed tensor discards bandwidth (a 320 MHz 802.11bk capture and a 20 MHz 802.11n capture become indistinguishable), antenna structure, phase state, and hardware-specific information a foundation encoder should learn from (the WiLLM lesson: lightweight per-device adapters into a shared *latent*, not a shared *tensor*). RuView's own history proves the cost of premature canonicalization — MERIDIAN's normalizer is useful precisely because the native data was still around.
## 2. Decision — `RfFrameV2`
The authoritative record preserves the native capture. Fields per the implementation: schema version, frame id, timestamp, modality (now including `WifiCir`, `WifiBfReport`, `FmcwRangeAzimuth`, `FmcwDopplerAzimuth` alongside CSI/SRS/FMCW/UWB/BLE-CS), **declared native axes** (`FieldAxis`: time/frequency/delay/Doppler/range/azimuth/elevation/antenna/polarization), centre frequency, bandwidth, sample rate, arbitrary-rank `native_shape` + `native_iq` + explicit `valid_mask`, TX/RX `Pose3` in one building frame, `AntennaElement` geometry, `sample_age_ns`, `CalibrationState` with a **declared `PhaseState`** (`Raw | Sanitized | Calibrated | Unavailable`), `SignalQuality`, and `FrameProvenance`.
Seven required invariants, each enforced in the validated constructor or proven by a test:
1. **Native samples are never overwritten**`to_canonical(&self)` is read-only; `canonical_view_is_derived_and_native_is_untouched` asserts byte-identical native IQ + mask after derivation.
2. Subcarrier/antenna masks are explicit (`valid_mask`, arity-checked).
3. Phase declares its state — consumers branch on `PhaseState` instead of guessing whether detrending happened.
4. TX/RX geometry uses one building coordinate system (`Pose3`).
5. Results retain source identity via `receipt_id` (consumed by the Gaussian memory's `source_receipts` lineage, ADR-275).
6. **Synthetic and measured frames can never share a provenance class**, strengthened to an evidence rule: `Synthetic ⇒ exactly L0Simulation`, `Measured ⇒ ≥ L1CapturedReplay` — both directions rejected at construction (`synthetic_and_measured_provenance_can_never_alias`).
7. Sample age is carried through the whole path (frame → tensor → age gate → `BoundedEvent`).
## 3. The canonical tensor is demoted to a compatibility view
`RfFrameV2::to_canonical()` derives the ADR-274 tensor **through the exact same normalization code path as every adapter** (`adapters::normalize_grid` — one normalization, many entry points), after mask-aware gap-filling (invalid bins interpolated from nearest valid neighbors on the complex plane). Rank ≠ 3 frames have no canonical projection and say so with a typed error. The existing ESP32/Intel/Atheros 114→56 projections stay as-is; they simply stop being the storage format.
## 4. The mandatory split manifest
The brief's leakage rule is now code: `PartitionKey` gains a `session` dimension (packet-session leakage is as real as room leakage) and `eval::SplitManifest` certifies per-dimension disjointness across **all seven** dimensions (room/day/person/chipset/firmware/layout/session):
```text
train_rooms ∩ test_rooms = ∅ … train_sessions ∩ test_sessions = ∅
```
`fully_disjoint()` is the bar for reporting a result as leakage-resistant; a room-holdout split that still shares people *says so* in its manifest instead of masquerading (test `split_manifest_certifies_per_dimension_disjointness`). The hidden real-world test set requirement (never accessible to synthetic generation/calibration) is process, recorded in ADR-282 §4.
## 5. Consequences
- New hardware (PicoScenes, Intel, Atheros, Realtek radar, 320 MHz 802.11bk) lands as an `RfFrameV2` producer + latent adapter; nothing is lost at ingest. Vendor conformance receipt = the constructor's invariants (native shape preserved, phase state declared, timestamps monotonic, geometry present, loss measured, synthetic flag correct).
- The encoder input contract (ADR-274) is unchanged *today* (it consumes the derived view); migrating the tokenizer to native-resolution tokens is the flagged follow-up once real multi-bandwidth data exists (P2).
- Storage cost rises (native + derived); accepted — the derived view can always be recomputed, the native never can be.
## 6. Verification
`cargo test -p ruview-unified frame::` — 5 tests: provenance aliasing, shape/mask/axes arity, derived-view purity + gap-filling, rank/geometry rejection, P3162 import-profile validation (`SyntheticApertureSoundingDataset`, ADR-281 §5). All MEASURED-CODE.