#1759·RuView

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

Author: proffesor-for-testingCreated Aug 31, 2026Updated Sep 16, 2026
Labelsbug

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.