wifi-densepose/v2
WilliamMalone f0a448fa85 De-confound CSI: drop structureless null frames from the feature pipeline
Diagnosed against real 2-node mesh data: the occupancy-blind bimodality is NOT a
subcarrier-width artifact (frames are a fixed width at any instant) nor a
transmitter/RSSI split (RSSI is identical across modes). It is a *frame-structure*
split — promiscuous capture interleaves ~50% structureless "null" frames
(near-constant amplitude vectors, spatial CoV² ≈ 0) with real CSI frames
(CoV² ~0.4) at the SAME width and RSSI. Diffing a null frame against a real one in
temporal_motion_score fabricates large fake "motion", which is what makes presence
bimodal and occupancy-blind.

Fix: a per-node adaptive gate (`admit_frame_structure`) admits a frame into the
feature pipeline only if its spatial CoV² is >= DECONFOUND_FRACTION (0.1) of the
node's rolling-P95 CoV². No brittle absolute threshold — it self-calibrates per
node and is scale-invariant. Gates BOTH the global and per-node frame_history so
the person-count fallback stays consistent too. Excluded frames are counted
(`off_structure_frames`). Enabled by default; disable with SENSING_DECONFOUND=0.

Supersedes the static-MAC `filter_mac` approach, which starved CSI on the mesh,
and the modal-width gate, which is a no-op here (width is fixed at any instant).

Tests (3): CoV² is zero for flat / large for structured / scale-invariant; the
gate excludes null frames after warmup and counts them; and gating collapses the
fabricated temporal motion of an alternating null/rich stream (>10x reduction).
Full binary suite green (127 passed).

Open: real-occupancy validation (does de-confounding make presence track people?)
needs raw-frame capture through the running server — the recordings only preserve
a processed amplitude, not raw frames, so it could not be confirmed offline yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:21:17 -06:00
..
.cargo fix(security): audit — fix RUSTSEC vulns, clippy warnings, dead code (#769) 2026-05-23 05:36:13 -04:00
.claude-flow chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
crates De-confound CSI: drop structureless null frames from the feature pipeline 2026-06-03 17:21:17 -06:00
data chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
docs chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
examples chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
patches/ruvector-crv chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
Cargo.lock feat(swarm): add ruview-swarm crate — drone swarm control system (ADR-148) (#862) 2026-05-30 16:00:59 -04:00
Cargo.toml feat(swarm): add ruview-swarm crate — drone swarm control system (ADR-148) (#862) 2026-05-30 16:00:59 -04:00
rust-toolchain.toml v2: pin Rust 1.89 and fix sensing-server UI path when run from v2 (#523) 2026-05-17 18:00:36 -04:00
ruvector.db feat(worldmodel): ADR-147 — OccWorld world model integration, wifi-densepose-worldmodel v0.3.0 (#856) 2026-05-29 16:53:51 -04:00