Files
pulse/docs/release-control
rcourtman ee3ebd800e Stop presenting a silent agent's node temperature as live (#2582)
A host agent linked to a Proxmox node merges with it into one read-state
row, and every PVE poll refreshes that row's `LastSeen`. The agent's
last sensors stay in state after it stops reporting. The node
temperature lookup (`getHostAgentTemperatureByID`) checked neither, so
each poll merged the silent agent's last reading into the node as a
fresh measurement, stamped with the row's fresh `LastSeen`:

- an open node temperature alert was re-observed every poll, so its
`LastSeen` kept moving and the 24h stale-alert cleanup never reached it;
a stale hot reading could keep activating
- node history recorded the frozen value as new samples, and the UI and
reports showed it as current
- SSH collection was skipped as if a recent agent payload existed

Since #2569 evaluates node temperature for agent-backed nodes, this
holds their temperature alerts open.

## Change

- `HostView.SourceStatus(source)` exposes the per-source freshness the
registry already records (same accessor the VM, container and
physical-disk views have).
- The linked-agent lookup reads the agent source's own sighting, uses
the agent's sensors only inside the reporting lease that keeps the agent
online (`hostAgentHealthWindow`, as `evaluateHostAgents` uses), and
stamps the reading with the agent's report time. Past the lease the node
has no agent reading (the cluster sensor cache is still consulted), and
alert evaluation treats that as a missing reading, not as evidence the
node cooled down.
- The poller's carry-over of a previous reading after a failed
collection is bounded to max(5 min, 2 × PVE polling interval) and keeps
its original timestamp. This branch does not engage today: the
previous-node projection carries the unified resource id and no
temperature, so it never matches the polled node. That is filed
separately; the bound keeps the carry honest once it's repaired.

The owner is the poller rather than `checkNodeTemperature`: the same
stale value also reaches history, reports and the UI. An alerts-side
`LastUpdate` check would also have missed this case, because the reading
was stamped with the merged row's fresh `LastSeen`. Mock fixtures are
untouched.

## Tests

- `TestSilentLinkedAgentStopsRefreshingNodeTemperatureAlert` (registered
monitoring proof): registry-backed merged agent+node row through the
production previous-node projection and `CheckNode`. A reporting agent
opens the alert. A silent agent leaves the alert open but stops
refreshing `LastSeen`. A resumed agent is evaluated again. It fails on
origin/main.
- `TestView_HostViewSourceStatusSeparatesAgentFromMergedRow`: a merged
row's `LastSeen` follows PVE, while `SourceStatus(SourceAgent)` keeps
the agent's own report time.
- `TestCollectNodeTemperatureCarryIsBoundedByCarryWindow`,
`TestHostAgentReportCurrent`,
`TestGetHostAgentTemperatureByID_IgnoresAgentPastReportingLease`.

Out of scope, filed separately: `mergeHostAgentSMARTIntoDisks` copies
silent agents' retained SMART temperatures into physical disks.
2026-10-06 17:31:31 +01:00
..