发布

  • v1428 9e7fa83210

    feat(signal): ADR-134 CSI→CIR via ISTA + NeumannSolver warm-start (#837)

    frostbyte_neo 发布于 2026-05-28 20:24:37 +00:00

    • feat(signal): ADR-134 — CSI→CIR via ISTA + NeumannSolver warm-start

    End-to-end first-class Channel Impulse Response estimation in the Rust
    workspace. Bridges CSI (frequency domain) to CIR (delay domain) so
    multistatic coherence gating, NLOS/LOS classification, and (at HT40+)
    ToF ranging become tractable in wifi-densepose-signal.

    Algorithm: ISTA L1 sparse recovery over a normalized DFT sub-matrix
    sensing operator Φ ∈ ℂ^(K×G) with G = 3K (3× super-resolution). The
    Tikhonov-regularised warm start re-uses ruvector_solver::neumann:: NeumannSolver — same call pattern as fresnel.rs:280 and
    train/subcarrier.rs:225 — so no new crate dependencies.

    Tiers supported: HT20 / HT40 / HE20 (Tier A-HE, C6) / HE40. The C6
    HE-LTF tier is the preferred Tier A target whenever an 11ax AP is in
    range; firmware substrate already shipped at v0.7.0-esp32 per ADR-110.

    Measured performance (release, single CirEstimator shared across 12
    links): HT20 2.72 ms / HE20 3.20 ms / HT40 13.43 ms / HE40 9.71 ms per
    estimate(). HT20 12-link multistatic 17.7 ms — fits the 50 ms RuvSense
    cycle; HT40 12-link 74 ms exceeds it and is flagged in ADR-134 §2.7 as
    requiring Rayon parallelism or G=2K super-res reduction.

    Measured Φ conditioning: κ(Φ) ≈ 1.00 identically across all tiers.
    ADR-134 §2.3 was corrected — the C6 advantage is statistical SNR gain
    (√(242/52) ≈ 2.16×) from more independent measurements, not improved
    conditioning.

    Witness: bit-deterministic SHA-256 over CirEstimator output on the
    synthetic ADR-028 reference signal (100 frames, top-5 taps, 1e-6
    quantization). Hash committed to expected_cir_features.sha256;
    verify-cir-proof.sh wires the check into the existing witness bundle.

    CI: cargo test --features cir + verify-cir-proof.sh added as separate
    steps under the Rust Workspace Tests job; regressions are unambiguously
    attributable.

    Files:

    • ADR + WITNESS-LOG-028 row 34 + CLAUDE.md module count (14 → 15)
    • src/ruvsense/cir.rs (~540 LOC) + lib.rs re-exports + multistatic.rs
      wire-up (reversible via use_cir_gate=false)
    • 3 integration tests + Criterion bench + 3 deterministic fixtures
    • cir_proof_runner binary + sha256 + verify-cir-proof.sh

    Test rate: 395 pass / 6 ignored (P2 ISTA hyperparameter tuning; see
    #[ignore] reasons) / 0 fail. cargo check clean; verify-cir-proof.sh
    VERDICT: PASS.

    Co-Authored-By: claude-flow ruv@ruv.net

    • fix(signal): make CIR witness cross-platform-deterministic

    The first witness (Windows-generated hash 89704bfd…) failed on Linux CI
    with a different hash (b36741bf…). Root cause: hashing re/im parts of
    top-5 taps at 1e-6 precision is too tight against libm differences in
    sin/cos/sqrt across glibc, MSVC, and Apple-clang. The previous
    "top-5 sorted by magnitude" form also suffered from rank instability when
    taps are near-tied — libm jitter could shuffle the ordering even when the
    algorithm is unchanged.

    New canonical form: full per-tap quantised-magnitude profile in natural
    index order, no sort.

    • 156 taps × 2 bytes (u16 le) per frame = 312 bytes/frame.
    • Quantisation 1e-2 — robust to ~1e-3 float drift while still tripping
      on real algorithmic changes (e.g., a 10× lambda shift moves magnitudes
      by >1e-2).
    • No top-K selection — eliminates the unstable magnitude-sort step.

    Regenerated expected_cir_features.sha256 — new hash 120bd7b1…

    If the next CI run still mismatches, the cause is structural (rustfft SIMD
    code path selection or NeumannSolver internal ordering), not magnitudes,
    and the witness needs further coarsening or to be made platform-tagged.

    Co-Authored-By: claude-flow ruv@ruv.net

    下载附件