mirror of
https://github.com/ruvnet/RuView
synced 2026-07-27 18:11:43 +00:00
a0226392d0
PresenceSpecialist::train() set its variance decision threshold to the midpoint between empty-room and occupied-anchor variance, assuming occupied windows are always noisier than the empty baseline. A still, quiet occupant can measure LESS variance than an empty room's own ambient/interference noise floor -- in that case the midpoint sits BELOW the empty-room baseline itself, so a genuinely empty room reads "present" on every single frame, at nonzero confidence. This matches a secondary finding from issue #1440's controlled reproduction: after room calibration (train_empty_room/ train_still_presence/train_walking/train_active_movement), a known- empty room read "present" 31/31 frames. The reporter's primary finding (raw-CSI amplitude-only presence sits at chance, AUC ~= 0.576, once time-of-day is controlled) is a genuine sensing-difficulty result, not a code bug, and is already addressed by the maintainer's prior comment pointing to this per-room calibration path -- this fix addresses the part of the report that IS a code bug: the calibration path itself mis-behaving on presence classification, worse than chance (constant wrong answer) rather than merely noisy. Fix: only trust the variance channel when occupied variance exceeds the empty baseline by a margin (VARIANCE_SEPARATION_MARGIN = 5%); otherwise disable it (threshold = +inf), mirroring how the mean-shift channel already goes inert when the anchors' means don't separate. Also fixed a latent confidence-scoring bug this exposed: an infinite threshold previously drove the variance confidence term to a spurious 1.0 via `(x - inf).abs() / span`, which would have overstated confidence in a disabled channel's "vote". Added `presence_inverted_variance_never_reports_empty_room_as_present`, pinning the exact scenario (occ_var < empty_var, identical means, no mean-shift channel to fall back on) that isolates the variance-only bug. All 64 existing + new tests pass, 0 regressions. Fixes #1440 Co-Authored-By: claude-flow <ruv@ruv.net>