/api/v1/status reported source_state "live_unverified" for a configured
live source before any frame had arrived, because source_state() fed a
fixed zero frame age into the ADR-295 resolver. It now uses the real age
of the last accepted frame for the current source, so the states are:
- disconnected (waiting_for_frames: true) until the first frame
- live_unverified while frames arrive within ESP32_OFFLINE_TIMEOUT (5 s)
- stale once they stop for longer than that
The response also carries waiting_for_frames and last_frame_age_ms.
ADR-270 vendor events get their own receive clock so they age the same
way.
An unknown --source value (for example "macos") used to start a server
with no data task. Clap now rejects it with the list of valid values
(auto, esp32, wifi, simulated, simulate), and plan_source returns an
error for anything else.
Docs: user guide lists the valid --source values and status states, the
macOS section uses --source wifi, and the Linux section says there is no
Linux RSSI source in the server yet.
Refs #2097
Co-Authored-By: claude-flow <ruv@ruv.net>
EngineBridge built its StreamingEngine without ever calling
set_node_positions, so the governed fuser placed every node at the
origin even when --node-positions was set. Startup now passes the same
keyed map the sibling multistatic_fuser gets, via
EngineBridge::with_node_positions. The fuser resolves positions by
node_id per frame, so nodes discovered later need no extra call.
/api/v1/status (and /health/ready) now reports the map under
trust.node_positions so the configuration can be checked at runtime.
Co-Authored-By: claude-flow <ruv@ruv.net>
Closes the two documentation gaps from #1456 (follow-up to #1401):
- docs/calibration-guide.md: what calibrate/enroll/train-room actually
enforce, grounded in v2/crates/wifi-densepose-calibration and
wifi-densepose-cli source (not just ADR-135/151 aspirational prose).
Covers the hard 600-frame baseline minimum, per-anchor quality gate
thresholds, the unsolved pet/small-motion presence-detection gap, and
what the empty-room baseline capture actually needs (steady vs silent).
Flags that ADR-135's drift_score/BaselineDrift staleness system is not
implemented in code — only bank.rs's baseline_id STALE check is real.
- docs/trust-and-engine-errors.md: exact trigger conditions for
engine_error_count vs the separate, non-sticky `demoted` privacy-class
flag, where both are exposed (/health/ready and /api/v1/status share a
handler), the real diagnostic gap (no per-cause breakdown, log line is
the closest thing), the WDP_GUARD_INTERVAL_US recovery path for
persistent clock-drift demotion, and an honest "no code path found"
answer on whether a converted HuggingFace model explains engine errors.
Also adds both docs to the README documentation table. No code changes.