ruvnet / ruvnet/RuView

fix(calibration): fresh/bound calibration emits no `calibrated_presence_evidence` on any endpoint

Open
#1,759 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Rust
Stars
94.4k
Forks
12.5k
Avg merge
21h 27m
Merged PRs (30d)
43

Description

Summary

A successfully completed, bound empty-room calibration produced no calibrated output.
calibrated_presence_evidence is computed per tick (main.rs:8211) and is part of
SensingUpdate (types.rs:130), but it never appeared on any endpoint on a system where
calibration reported fresh and bound.

State at the time

/api/v1/calibration/status
  status: fresh          binding_mode: bound       legacy: false
  frame_count: 85731     baseline_eigenvalue_count: 6
  source_node_ids: [1,2,3]   observed_source_node_ids: [1,2,3]
  missing_source_node_ids: []
  model_receipt: ruview.calibration.field-model-receipt.v1 present

All three bound nodes active and streaming at the time of sampling.

Observation

calibrated_presence_evidence was absent from the response of every endpoint checked:

/api/v1/sensing/latest      absent
/api/v1/status              absent
/api/v1/nodes               absent
/api/v1/pose/current        absent
/api/v1/calibration/status  absent

/api/v1/sensing/latest top-level keys were: classification, estimated_persons, features, node_features, nodes, persons, room_inference, signal_field, signal_quality_score, source, tick, timestamp, type, vital_signs.

Since the field is Option<CalibratedPresenceEvidence>, absence means the chain returned
None on every tick.

Where it could be returning None

Not diagnosed — listing the candidates rather than guessing:

  • main.rs:1636self.field_model.as_ref()?
  • main.rs:1637 — node frame_history lookup
  • field_bridge.rs:146field.check_freshness(observed_at_us) != Fresh
  • field_bridge.rs:156 — empty frame window after canonical resampling
  • field_bridge.rs:168extract_perturbation(...).ok()?
  • calibration_session.rs:240-251 — receipt-side conditions (node in source_node_ids,
    observed_at >= completed_at, person_count <= 3, inference_method one of
    field_model_eigenvalue_v1 / field_model_perturbation_energy_v1)

Ruled out: a timestamp-unit mismatch between finalize_calibration(now.timestamp_micros())
(main.rs:6546) and the observed_at_unix_ms * 1_000 passed at main.rs:1641. Both are Unix
epoch microseconds; consistent.

Why it matters

This is the output the empty-room baseline exists to produce, and it is also the receipt-bound
one — it carries model_id, binding_digest and source_node_ids. Without it there is no way
for a consumer to tell calibrated output from uncalibrated, and an 11-minute calibration
appears to succeed while changing nothing observable.

Done when

A fresh/bound calibration with all bound nodes active emits calibrated_presence_evidence,
or the API states why it cannot.

Work items

  • Determine which condition in the chain returns None on a healthy bound calibration.
  • Surface the reason — a diagnostic field or a log line — so "calibrated but not emitting"
    is distinguishable from "not calibrated".
  • Add a check that a finalized bound calibration actually yields evidence, so this cannot
    regress silently.

Related

Same deployment as the stuck-classification issue. That one concerns the uncalibrated
top-level classification; this one concerns the calibrated path, which turns out not to be
emitting at all.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the None-returning chain from main.rs:1636-1641 through field_bridge.rs:146-168 and calibration_session.rs:240-251, starting with the healthy bound-calibration state described in the issue. Check the listed endpoint outputs and existing calibration flow before changing anything. Done means fresh/bound calibration emits calibrated_presence_evidence or exposes why it cannot, with a regression check for finalized bound calibration.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.