wifi-densepose/v2
ruv 79cc2d7b22 Merge #491: feat(sensing-server): adaptive person count — RollingP95 + dedup_factor runtime API
Integrating @schwarztim's PR #491 into main on their behalf — their fork has
fallen too far behind for a clean rebase (the PR's commit graph dropped
silently during `git rebase origin/main`), so applying as a merge from the
fork head to preserve the diff cleanly.

What this lands:
- `RollingP95` adaptive normaliser for the person-count feature scaling.
  Streaming P95 over a 600-sample / ~30 s sliding window. Cold-start
  (<60 samples) falls back to the legacy denominators (variance/300,
  motion_band_power/250, spectral_power/500) so day-0 behaviour is
  preserved on every deployment.
- `RuntimeConfig` struct + `load_runtime_config` / `save_runtime_config`
  persisted to `data/config.json`. Exposes `dedup_factor` via REST so
  multi-node deployments can tune cluster-deduplication without a rebuild,
  including an auto-tune endpoint that derives optimal dedup from a known
  person count (calibration mode).
- `compute_person_score()` now takes &AppStateInner alongside &FeatureInfo
  so the adaptive denominators are reachable. All 3 call sites updated.
- New `AppStateInner` fields: `p95_variance`, `p95_motion_band_power`,
  `p95_spectral_power`, `dedup_factor`, `data_dir`.

Closes #491. Directly addresses:
- #499 (double skeletons, multi-node) — the slot-clustering problem this
  PR's adaptive normaliser was designed to fix
- #519 Bug 1 (ghost person detection on edge-tier 1 & 2 multi-node)
- #496 (person count over-reporting on single-room single-person)

Verified locally:
- cargo check -p wifi-densepose-sensing-server --no-default-features: 1.0s
- cargo test -p wifi-densepose-sensing-server --no-default-features --lib:
  233/233 passed in 25.0s

Co-authored-by: @schwarztim
Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-19 08:25:47 -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 Merge #491: feat(sensing-server): adaptive person count — RollingP95 + dedup_factor runtime API 2026-05-19 08:25:47 -04: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 chore: remove empty stub crates wifi-densepose-{api,db,config} (closes #578) (#608) 2026-05-17 18:50:57 -04:00
Cargo.toml chore: remove empty stub crates wifi-densepose-{api,db,config} (closes #578) (#608) 2026-05-17 18:50:57 -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