Files
pulse/internal
rcourtman d9ffb39ce8 Keep a merged disk's temperature under its own row's state (#2618)
Stacked on #2609; until it merges this branch also carries its commit,
and the change here is the last commit.

## Why

The registry merges a physical disk's rows (Proxmox, host agent SMART,
Unraid inventory), choosing the temperature by source preference and
merging collection states separately. When two rows carry different
temperatures, the shown value could sit under the other row's
`available` state. A real case: a node whose disk temperature Proxmox
collects now (`proxmox_node_smart`, 40) and whose linked host agent has
gone silent (retained 72, `unavailable`). In either ingest order the
merged disk showed **72 labelled available**, so risk, history and the
UI treated the frozen reading as current.

## What

- `pairPhysicalDiskTemperatureState` runs at the end of each merge step.
When the merged state says collected but the row the shown value came
from says it was not, the merged state becomes that row's own.
- It never changes a value and never grants availability, so it cannot
revive a withdrawn reading or override a resumed agent's fresh one.
- Rows with the same value keep the merged state, so the agent's own
withdrawal still supersedes the Proxmox copy (#2593).
- With that guarantee the Unraid-native row no longer needs to withhold
`available` (#2609 restricted it), so it carries the same derived state
as a SMART row borrowing its reading.

## Known limit

This is exact for the two rows of one merge step. The merged disk keeps
one state per field, so with three or more rows for one disk, a
withdrawal that an earlier step replaced is invisible to a later step.
Sol found two such counterexamples, both needing three rows (one also
needs coincidentally equal values, the other a legacy agent plus two
Proxmox rows). Closing that needs each reading's own state tracked
across merges, and that redesign is filed separately. Preferring another
source's current value instead of the retained one was tried and
dropped: it needs an ordering between same-source states that the rows
do not record, and each version reopened a withdrawn reading somewhere.

## Tests

- `TestPhysicalDiskMergePairsTemperatureWithItsCollectionState`, in both
ingest orders:
- silent agent against a collected Proxmox reading, and against no
Proxmox reading
  - reporting agent
- silent agent against a Proxmox copy of its earlier reading, with and
without SMART attributes
  - resumed agent against a Proxmox copy of its withdrawal
  - standby agent against a Proxmox copy of its pre-sleep reading
- `TestPhysicalDiskMergeNeverPresentsAWithdrawnTemperatureAsCollected`:
three distinct-valued withdrawn or stale rows in all six orders.
- `TestUnraidInventoryRowDoesNotMaskTheSMARTRowState`: the Unraid
inventory's `available` no longer lends itself to a SMART row's
uncollected reading.
- Without the rule, the peer-reported case, the Unraid masking case and
one three-way order fail.
2026-10-06 23:05:53 +01:00
..