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
5.3 KiB
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:
- Native samples are never overwritten —
to_canonical(&self)is read-only;canonical_view_is_derived_and_native_is_untouchedasserts byte-identical native IQ + mask after derivation. - Subcarrier/antenna masks are explicit (
valid_mask, arity-checked). - Phase declares its state — consumers branch on
PhaseStateinstead of guessing whether detrending happened. - TX/RX geometry uses one building coordinate system (
Pose3). - Results retain source identity via
receipt_id(consumed by the Gaussian memory'ssource_receiptslineage, ADR-275). - 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). - 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):
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
RfFrameV2producer + 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.