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

5.3 KiB
Raw Blame History

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 overwrittento_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):

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.