Skip to content

fix(sensing-server): classification.presence contradicting motion_level (#1442) - #1447

Merged
ruvnet merged 1 commit into
mainfrom
fix/issue-1442-classification-presence-inconsistency
Jul 27, 2026
Merged

fix(sensing-server): classification.presence contradicting motion_level (#1442)#1447
ruvnet merged 1 commit into
mainfrom
fix/issue-1442-classification-presence-inconsistency

Conversation

@ruvnet

@ruvnet ruvnet commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Fixes #1442.

Root cause

The multi-node vitals path derived presence directly from vitals.presence independently of the motion_level label computed in the same block, so a frame with motion=true, presence=false produced {"motion_level": "present_moving", "presence": false} — internally contradictory. Since every UI gates rendering on classification.presence, a moving person could render as an empty room, at confidence 1.0 (the multi-node confidence boost applies regardless of the presence flag).

Every other classification site in this codebase already derives presence from the label instead:

  • main.rs's per-node path: presence: !matches!(ns.current_motion_level.as_str(), "absent")
  • csi.rs: classification.presence = label != "absent"

This was the one outlier.

Fix

Extracted the motion_level + ClassificationInfo assembly into a small pure classify_vitals(motion, presence, presence_score) function, so the invariant (motion implies presence) is enforced in one place and is unit-testable. Added 4 tests, including one pinning the exact contradictory frame from the report (motion=true, presence=false → must not yield presence: false).

Testing

  • cargo test -p wifi-densepose-sensing-server --no-default-features: 483 + 224 (+4 new) passing, 0 failed, 0 regressions.
  • New tests: classify_vitals_tests::{motion_implies_presence_issue_1442, presence_without_motion_is_present_still, neither_motion_nor_presence_is_absent, confidence_passes_through_presence_score}.

Did not touch the secondary "presence/presence_score anti-correlation" lead the reporter flagged (possible field-offset issue in the vitals packet decoder) or the "should the multi-node confidence boost apply when presence is false" question — both are explicitly framed as open questions/leads in the report, not concrete bugs, and are out of scope for this fix.

Reported with an exact root-cause analysis and suggested fix by @mattanapol — thank you, this made the fix straightforward.

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

…el (#1442)

The multi-node vitals path derived `presence` directly from `vitals.presence`
independently of the `motion_level` label it computed in the same block, so
a frame with motion=true, presence=false produced
`{"motion_level": "present_moving", "presence": false}` — internally
contradictory, and since every UI gates rendering on `classification.presence`,
a moving person could render as an empty room at confidence 1.0 (the
multi-node confidence boost applies regardless of the presence flag).

Every other classification site in this codebase already derives `presence`
from the label instead (main.rs's per-node path: `!matches!(label, "absent")`;
csi.rs: `label != "absent"`) — this was the one outlier. Extracted the
motion_level + ClassificationInfo assembly into a small pure `classify_vitals`
function so the invariant (motion implies presence) is enforced in one place
and is unit-testable, with a test pinning the exact contradictory frame from
the report.

Reported with an exact root-cause analysis and suggested fix by @mattanapol.

Fixes #1442

Co-Authored-By: claude-flow <ruv@ruv.net>
@ruvnet
ruvnet merged commit 4e72054 into main Jul 27, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant