The previous-state input projected each host's current disk inventory before discarding offline or unlinked hosts. Check those immutable view fields first and keep the linked-host projection, source age and guest selection unchanged. Add exact selection, ownership, withdrawal/recovery and allocation-scaling controls.
Contract-Neutral: Allocation-only early filtering of hosts that never contributed to guest carry-over; linked evidence, wire fields, timestamps, polling and safety rules are unchanged.
Change-source: pulse-maintainer
Retained guest identity can survive a cancelled detail cycle or failed metadata refresh. Keep its original eligibility time through canonical snapshots instead of borrowing each VM poll timestamp, and preserve ordinary current-read recovery and the existing guest-command safety fences.
Change-source: pulse-maintainer
Retain recent filesystem-only evidence across safe deferrals without renewing its ten-minute age from VM polls or cached identity. Carry internal source provenance through canonical replacement, preserve independent linked-agent precedence and keep expired values unavailable until a new ordinary read succeeds.
Change-source: pulse-maintainer
Compose exact observed upstream e7cabc72f1 additively. Preserve both storage contract accounts at the sole documentation conflict; runtime merges retain reviewed repairs and upstream linked-agent disk ownership and public-demo profiling restrictions. Browser and security gaps remain publication blockers.
Change-source: pulse-maintainer
PR 2669 made the guest drawer's filesystem rows follow a linked Pulse
agent's freshness when its filesystems fill in for a VM that has no
Proxmox guest filesystems. The workload table's disk cell and the
drawer History still judged the same reading only by the Proxmox read
reason. So one guest read as current in the drawer and as "Unavailable:
Guest agent not running" in the table and History, and a silent
agent's reading could not show as last known there.
getWorkloadGuestDiskRead now owns one rule for the table cell, the
drawer rows and History: current while the agent reports, last known
once it is stale, unavailable once the guest is stopped. Proxmox's own
guest filesystems keep their read reason.
The rule also covers the aggregate disk metric, because Proxmox records
no guest disk usage without guest filesystems, so the manual link merge
keeps the agent's metric. Three paths broke that:
- The poller built its previous VM from the merged metric, so the next
poll carried the agent's disk forward as a Proxmox prev- read, and
Proxmox priority then froze it over the agent's live value. Only
Proxmox's own disk reading is carried now.
- agent.stale was omitempty, and the browser merges agent facets field
by field, so a resumed agent stayed "stopped reporting" until a
reload. It is always sent now.
- The same merge kept filesystems a native Proxmox VM facet or a native
agent facet had withdrawn, so the rows did not switch source.
Preserve exact reviewed tip b5b1fa9777 and upstream a85bdcdc9a additively. Retain both alert threshold test sets. Combine upstream mock-mode epoch fencing with reviewed structural-revision checks and Docker departure ownership; add a regression that a current revision cannot revive an ended epoch. Resolve the monitoring contract to describe both boundaries, without rewriting accepted history.
Publication remains deferred for genuine final-content browser receipts and independent CodeQL disposition. Composition checks do not establish native recovery, deployment, exact-head hosted acceptance or release readiness.
Change-source: pulse-maintainer
SetMockMode(false) switched the mock package off and then cleared active
alerts, but every path that evaluates mode-dependent data checked the
mode once, up front. A mock alert pass (started from the ticker with go,
so passes overlap), a frontend or ingest refresh evaluating a GetState
snapshot, a backup-age check over fixture recovery rollups, or a
connection check over the mock ledger could already hold fixture data
when the switch happened. Its evaluations then landed after the clear,
in live mode, where nothing evaluates or resolves fixture resources, so
the alerts stayed until the 24-hour stale sweep.
A pass-level lock around checkMockAlerts was tried and reverted: it left
the other paths open and made the mock-mode API wait behind a whole pass
of synchronous event-log writes.
The monitor now owns a mock-mode epoch fence. The mock pass, backup-age
and snapshot checks, connection checks, Docker pruning and the
resource-store refresh take a scope before reading anything
mode-dependent and send each alert-manager call through it. SetMockMode,
now serialized, flips the mode, ends the epoch, waits only for calls
already admitted, and then clears. Unified metrics are evaluated one
resource per call, so the wait covers single calls, not passes.
Registry rebuilds are tracked rather than waited on. A refresh evaluates
the registry it read back only if no rebuild from an ended epoch
overlapped it, and the readers that open or remove alerts from the
inventory use current state until a clean rebuild in the new epoch
replaces the previous mode's registry. The mock supplemental fixture
sources now serve nothing outside mock mode: the router swaps them for
the real pollers only after the switch, refreshing between sources, so
a single switch to live mode used to raise fixture vSphere incidents.
The new tests park a real evaluation at a fixed point (a held lock or a
blocking supplier), switch modes and release it. Against the unfenced
code the mock pass left about 40 fixture alerts, the frontend refresh 5
vSphere incidents and the backup check 137 backup-age alerts in live
mode, and a mock-mode connection observation counted toward a live
connection's confirmation. The drain, republish and pruning tests fail
against a fence without its wait, overlap check or registry tracking.
Switching mock mode with several tenant monitors running remains
uncovered and is noted in the monitoring contract.
Recompose the exact guest-only source from 8c25205d8544083e2ed873cab7b5593e0e0105a1 and its fixture correction 174f315e26132f167ea3d7ae9818d608b86f0eb0 on assigned main. The rejected combined candidate and its original evidence remain intact; no commit is cherry-picked, re-parented or amended. SMART changes are not required by guest views, transfer, builder or transport. Preserve newer main temperature and resource-boundary repairs.
Contract-Neutral: Internal transfer of existing linked-agent disk inventory; no public model, identity, expiry, guest command or safety policy change.
Change-source: pulse-maintainer
The poller reads the previous poll's nodes back from the unified read
state, but previousNodeFromView returned the registry's unified resource
ID and no temperature. Every lookup keyed on the Proxmox source ID
missed: nodeLastOnline in the offline grace policy, the temperature
carry, the CPU low/record tracking (reset to the current reading every
poll) and the node memory carry. When a whole instance poll failed,
markPVEInstanceNodesUnreachable wrote the projected nodes back, so each
failed poll re-ingested the node under a new unified ID. Cluster members
also lost the cluster identity their canonical ID derives from, so they
changed ID for the length of an outage.
The projection now returns the source ID, the stored temperature
details, the cluster name and the linked agent ID, and
previousNodesForInstance restores the config-derived identity stamps
(provider-scoped flag, native aliases, TLS fingerprint) the way
pollPVENode writes them.
Reviving those paths needed four bounds:
- The node memory carry uses the poller's own validated snapshot rather
than the read state, which holds the agent's reading on a node merged
with a host agent, and keeps used + cache + free equal to the total.
- A carried temperature keeps a lapsed host agent's lease. A reading
stamped no later than the agent's last report is not carried, so the
five-minute carry window cannot hold a silent agent's reading in
alerts and history past its lease, which #2582 guarantees.
- A carried reading keeps the node's CPU and GPU temperatures only. Its
SMART and NVMe rows also stamp the node's physical disks, so a disk
that went to standby would be stamped and recorded with its pre-sleep
value.
- Outage preservation and authoritative membership reconciliation keep a
node's temperature only under those rules and drop it when the node
goes offline.
TestPollPVEInstanceMarksStaleNodesOfflineWhenGetNodesReturnsEmpty relied
on the dead nodeLastOnline lookup and now ages that sighting too. The
silent-agent test from #2582 now rebuilds the store as production does
and feeds the polled node back, which is what exercises the carry.
Extend the #1962 linked-agent memory fallback to Proxmox LXC containers (#2148). A correlated online Pulse agent running inside a container now supplies the container's memory metric instead of the cache-inclusive cluster/resources fallback, which can badly under-report shared-memory workloads. The agent sample is only trusted when its total matches the container's configured limit, so an agent without lxcfs cannot leak host memory into the guest row. Threads the previous-guest agent map through the efficient and node-by-node container builders and reads agent-owned memory from merged ContainerView resources.
Change-source: pulse-maintainer
Read agent-owned memory and source freshness from VM views when correlation removes the standalone host row. Preserve preferred guest memory sources and reject stale, offline or unavailable agent evidence. Reproduce issue #1962 through registry merge, next-poll diagnostics, card projection and memory alerts.
Change-source: pulse-maintainer