feat: add trust-gated Rydberg quantum RF vector sensing - #1
Conversation
|
Reviewed for merge alongside #3, #4, #5 and #7. This one cannot be merged as-is, for two independent reasons. Flagging rather than forcing, because both failure modes are silent. 1. Wire-code collision on
|
… main (#9) Re-creates #1 against a tree that exists. That PR shares no commit ancestry with `main` -- main's history was rewritten after it opened -- so merging it would have needed --allow-unrelated-histories and conflicted on 33 files wholesale, including the four that #5 and #7 had just changed. This carries the feature across instead of grafting the branch. Wire code moved from 16 to 17. #1 assigned `Modality::QuantumRf => 16`, which `main` now gives to `BleAdvertisementRssi` (#5). Two modalities cannot share a code, and a renumber is not a compile error -- it is a deployed decoder reading the wrong modality -- so 16 stays where it was published and quantum RF takes the next free code. `recent_wire_codes_are_pinned` asserts both by value, so a future edit cannot quietly swap them. Carried across unchanged (13 files, none of which exist on main): rufield-adapters: quantum_rf_{quality,replay,support,wire}.rs, three test suites, and the synthetic replay fixture rufield-fusion: bearing.rs, bearing_math.rs, bearing_trust.rs, and the quantum_bearing test suite docs/ADR-270-quantum-rf-vector-sensing.md Re-applied by hand, because these files exist on main and could not be taken from the branch without reverting recent work: - `Modality::QuantumRf` (code 17, `quantum_rf`) plus the registry contract tests, which correctly refused the addition until updated. - `FieldAxis::{CartesianComponent, ComplexComponent, DirectionCandidate}`. - Optional sensor pose on `SensorDescriptor` -- coordinate_frame, position_m, orientation_xyzw -- all `#[serde(default, skip_serializing_if)]`, so events that omit them round-trip unchanged. - `Observation::attributes`, likewise absent from the wire when empty. - `normalize_verifying_key_hex` and `verifying_key_from_hex` in rufield-provenance. `SensorDescriptor` loses its `Eq` derive: the pose carries f32 coordinates and float equality is not an equivalence relation. `PartialEq` is retained. ADR renumbered 266 -> 270. 266 is taken on main by field-evidence-promotion (#4). 255 workspace tests pass, 38 of them from the ported suites (13 replay, 23 bearing, 2 properties; the performance gate stays #[ignore]d by its author, requiring a release build). fmt and clippy -D warnings clean. Claude-Session: https://claude.ai/code/session_016QSCkKnxDjqU49NVVpWMK5
|
Superseded by #9, now merged. The feature is on Two changes from this branch worth knowing about: Wire code 16 → 17. ADR 266 → 270, since 266 is taken by field-evidence-promotion (#4). Closing rather than merging because this branch has no common ancestor with Thanks — the |
Summary
Adds a vendor-neutral, replay-first Rydberg quantum RF vector sensing contract to RuField, with a detailed architecture decision record and a fail-closed reference implementation.
Modality::QuantumRf(wire code16) plus Cartesian, complex, and direction-candidate tensor axes.RydbergReplayAdapterwhose default output is a P1 antipodal bearing tensor; raw complex electric-field output is explicit P0.0.2.0for the Rust source-compatibility event while retaining wire identifierrufield.mfs.v0.1.Evidence and claims boundary
This is a software contract and deterministic reference replay, not a hardware-performance claim.
LIVEbanner reports transport state and is not evidence-kind aware. Quantum RF replay is therefore forbidden through that source until replay-aware viewer states are implemented.Wire and tensor contract
Default derived bearing:
[direction_candidate, cartesian_component][2, 3][+k, -k]Explicit raw mode:
[cartesian_component, complex_component][3, 2]Signed attributes bind signal grouping, tensor frame, evidence kind, calibration hash, and exact calibration validity timestamps. Legacy JSON remains readable because new pose and attribute fields use Serde defaults and are omitted when absent.
Validation and safety gates
Replay ingestion is bounded to 65,536 bytes per line, 100,000 frames, and 256-byte identifiers. It rejects malformed or non-finite input, timestamp disorder, invalid integration intervals, calibration expiry, optical-lock failure, low calibration quality, inadequate SNR/ellipticity, invalid covariance, inconsistent polarization/axis data, noncanonical f32 conversion, pose mismatches, and calibration-contract changes within a stream.
Captured replay requires an explicit nondefault signing seed. Its signature attests package integrity, not live hardware identity.
Production trust boundary
Production fusion is separate from simulation and captured-replay policy. It requires:
evidence_kind=live;Malformed signed observations do not consume replay watermarks.
Fusion
QuantumBearingFusionpreserves the single-sensork ↔ -kambiguity and intersects lines through sign-invariant projectors. It rejects duplicate sensors, mismatched frames/signals/carriers, nonoverlapping half-open integration intervals, insufficient baseline, nearly parallel geometry, ill-conditioned information matrices, stale calibration, and already-expired estimates.The solver performs range-aware weighting from angular covariance, retains absolute uncertainty scale, inflates covariance by reduced chi-square, and caps estimate lifetime at the earliest supporting calibration expiry. Quality and covariance remain explicitly uncalibrated until hardware validation.
Privacy and governance
Validation performed
cargo build --workspace --all-targetscargo test --workspace— 144 passing tests including the doctest; zero failurescargo test -p rufield-adapters --release --test quantum_rf_performance -- --nocapturecargo clippy --workspace --all-targets -- -D warningscargo run -p rufield-bench -- 2026CI now runs the release performance gate and strict all-target clippy.
Compatibility and follow-up
Existing modality codes 1–15 and wire version remain unchanged. Code 16 is permanently assigned to
quantum_rf. The Rust crates move to 0.2.0 because exhaustive enum matches and external struct literals require updates.Before any live-product claim: implement evidence-aware viewer states, obtain a real receiver API and capture, establish calibration authority and device enrollment, run controlled direct-path and multipath trials, calibrate covariance coverage, and pass ADR-266's held-out RuView baseline gates.