Presence is serve liveness, not controller freshness

A switched-off gamepad made --health fail and so kept the Idunn presence
at warming forever; the daemon was serving the whole time. Presence now
reads the telemetry surface the tick rewrites; source freshness stays in
--health where an operator asked for it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-11 14:15:23 +02:00
commit 24e5b50284

View file

@ -594,7 +594,10 @@ fn start_idunn_presence_worker(options: &Options) {
let published = (|| -> Result<()> {
let target = resolve_odin_cultmesh_uri(&options)
.context("Odin CultMesh URI does not resolve")?;
let (state, detail) = match evaluate_health(&options) {
// Presence is about this process serving, not about what it
// serves: a controller that is switched off is telemetry, not
// a dead daemon. The surface record is written by the tick.
let (state, detail) = match evaluate_serve_liveness(&options) {
Ok(detail) => ("active", detail),
Err(error) => ("warming", format!("{error:#}")),
};
@ -9411,6 +9414,27 @@ fn evaluate_health(options: &Options) -> Result<String> {
evaluate_health_from_node(options, &node)
}
/// Is `serve` ticking? The telemetry surface is rewritten every tick, so a
/// surface in `idle` or `active` is a live daemon. Source freshness is what
/// `--health` adds on top and is not part of presence.
fn evaluate_serve_liveness(options: &Options) -> Result<String> {
let node = open_node(options, "muninn-idunn-presence-liveness")?;
let surface = node
.get_required::<MuninnTelemetrySurfaceRecord>("latest")
.context("Muninn telemetry surface is unavailable")?;
if surface.state != "idle" && surface.state != "active" {
return Err(anyhow!(
"Muninn telemetry surface is {}: {}",
surface.state,
surface.detail
));
}
Ok(format!(
"Muninn serving: {} on {} ({})",
surface.surface_id, surface.host_id, surface.state
))
}
fn evaluate_health_from_node(
options: &Options,
node: &cultmesh_rs::CultMeshNode,