Files
ruvnet--RuView/docs/adr/ADR-281-ble-cs-delay-doppler-pose-factorization.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.0 KiB
Raw Blame History

ADR-281: New modality surfaces — BLE Channel Sounding, delay-Doppler-native tensors, P3162 import, and factorized pose

Field Value
Status Accepted — implemented (adapters.rs BLE CS + ranging evidence, tensor.rs::delay_doppler_map, frame.rs P3162 import profile, heads.rs factorized pose; 8 new test suites)
Date 2026-07-26
Parent ADR-273; extends ADR-274
Relates to ADR-279 (FieldAxis native axes), ADR-152 (geometry conditioning intake), ADR-021/263 (radar hardware)

0. PROOF discipline

Grades per ADR-273 §0. Bluetooth SIG cm-level claims vs the ~2050 cm practical review, OTFS ISAC field trials, IEEE P3162, PerceptAlign's >60 % cross-domain error reduction, and RePos's 1021 % MPJPE gains are EXTERNAL-UNVERIFIED design inputs. Our numbers below are MEASURED-CODE / MEASURED-SYNTHETIC.

1. BLE Channel Sounding (§2) — likely the fastest path to consumer-scale spatial anchoring

BleCsFrame carries per-frequency-step round-trip tone phases plus optional RTT. Two rules:

  • Phase-based ranging and RTT are separate evidence sources. ble_cs_range computes both — d_phase = |dθ/df|·c/4π from the unwrapped phase-vs-frequency slope, d_rtt = rtt·c/2 — and cross-validates instead of averaging. Agreement raises confidence; divergence beyond 0.5 m yields RangingAnomaly::Divergent (multipath bias, relay attack, timing fault, or calibration problem) with confidence capped ≤ 0.2. Measured: exact recovery at 1.5/5/12 m (< 1 µm error on clean synthetic phases, 40 steps × 1 MHz); a relay-style RTT inflation to ~51 m against a 5 m phase estimate is flagged, not blended (ble_cs_flags_relay_style_divergence_instead_of_averaging).
  • The tensor view (BleCsAdapter, nrf54-cs in the registry) never detrends phase — the ranging ramp is the measurement; the preserved ramp is asserted in test.

Single-source evidence (no RTT) is capped at confidence 0.5 — one mechanism alone is never high-trust ranging.

2. Delay-Doppler-native support (§3)

FieldAxis (ADR-279) makes delay/Doppler first-class native axes so OTFS-style captures are stored natively, and RfTensor::delay_doppler_map provides the standard transform for frequency-time tensors: IDFT over bins (→ delay) × DFT over snapshots (→ Doppler). Measured: a synthetic scatterer at (delay 7, Doppler 3) produces a unit peak with < 1e-9 leakage everywhere else. Rule: derived features may be small, but delay-Doppler maps are not collapsed into scalar motion energy before provenance and local storage.

3. IEEE P3162 synthetic-aperture import (§5)

SyntheticApertureSoundingDataset (frequency range, aperture poses, directional PDP, coordinate system, processing-manifest hash) is the validated import profile — the calibration bridge between measured environments, Sionna-class simulators, and learned RF scene models. Schema + validation only; parsers arrive with the first real dataset.

4. Factorized pose (RePos) + log-age gating

FactorizedPoseHead separates what generalizes from what conditions:

  • relative skeleton branch reads the environment-invariant content representation (cannot learn room-position shortcuts);
  • root localization branch reads the geometry-conditioned representation (sensor pose is signal there — the PerceptAlign lesson);
  • absolute = root + relative (PoseOutput::absolute_joints_m), with calibrated per-joint and root residual σ so every pose output carries uncertainty (ADR-273 item 8).

The leakage experiment (factorized_pose_resists_room_shortcut_leakage): training rooms where room position correlates with body scale (the trap real deployments set), held-out room breaking the correlation — factorized MPJPE 0.0003 m vs monolithic absolute-head 0.2534 m (845× worse), on a toy that isolates the mechanism. MEASURED-CODE for the mechanism; not a pose-accuracy claim.

Budget: the structured pose head is the largest adapter at 740 params vs the 40,856-param backbone (1.8 %) — documented ceiling for structured heads is < 2 % (scalar heads keep the 1 % gate), both asserted in every_head_fits_the_one_percent_budget_at_deployment_config.

Age gating now matches the age-aware-CSI recipe exactly: the freshness gate input is log(1 + sample_age_ms) (encoder::age_feature), giving millisecond and multi-second staleness comparable input scale; the finite-difference gradient check re-proves the backward pass through the changed input.

5. Consequences

  • Bluetooth/UWB anchors slot in as geometric evidence while WiFi carries ambient activity — the complement strategy, in code.
  • The Gaussian primitive gained the lifecycle fields the update-loop spec requires (first_seen_ns, doppler_variance, bounded source_receipts lineage merged on fusion) — static structure is distinguishable from transients by lifetime, and every primitive traces to source frames.
  • Roadmap, explicitly not done: real nRF54 CS capture path, OTFS waveform generation, P3162 file parsing, pose heads on real MM-Fi-style data.