The remaining scroll hitch on large estates was the realtime websocket
tick: every few seconds a delta landed mid-gesture and blocked the main
thread for 200-560ms. The scroll path itself was already clean after the
windowing fixes, so the tick was the one thing still hitting the wheel.
Mid-gesture ticks now cost ~1ms: the resource delta queues unapplied in
arrival order (even the baseline patch walks the whole estate), and the
reporting projection plus the lastUpdate tick token defer latest-wins
alongside it. Holding the token matters as much as holding the data —
it is what unified resource projections and workload remaps key on, so
deferring it keeps every downstream consumer quiescent through the
gesture. Everything drains as one coalesced batch at scroll idle,
through the same deferral set and flush the hidden-tab path uses.
Ordering and lifecycle guards: a non-empty queue keeps queueing so
deltas never apply out of order, hidden-tab ticks drain the queue before
applying in place, a full snapshot supersedes and clears the queue, and
connection resets drop all pending deferral state. Alert application
stays live mid-gesture.
Verified on the 50-node/929-guest mock estate: zero websocket long
frames across 16-20s continuous scrolls (previously one 200-560ms block
per tick), one coalesced flush ~300-450ms after gesture end, and the
Last refresh footer still advancing on desktop and narrow viewports.
This is a scheduling boundary, not a cost reduction: the per-tick
reconciliation cost itself remains owned by the
resource-payload-static-metadata coverage gap.
Wheel scrolling the Proxmox overview on a 929-guest estate hitched for
200-260ms per runway rebalance. Four compounding causes, all fixed:
- The windowing runway policy rebalanced in ~53-row jumps inside a
non-passive wheel listener, so the compositor waited on a multi-frame
remount. Both windowing owners now keep a symmetric runway topped up
in dead-band batches (one bounded mutation frame per ~8 rows of
travel), every windowed-page listener is passive, and only a viewport
that leaves the mounted window entirely re-centers it in one jump.
- The Workloads viewport-sync effect tracked the windowing signals its
own measurement pass moves, so every shift re-ran row measurement
(two forced reflows) and listener binding. The measurement pass is
now untracked, matching the unified-resource sync owner; the platform
and storage windowing owners had the same latent tracking and are
untracked too.
- WorkloadPanel built its guest-id lookup from the windowed slice, so a
shift re-validated every mounted row's memo chain. The lookup now
derives from the full group and only changes when data changes.
- The CPU/memory/disk bar hooks read offsetWidth in onMount, forcing a
full-table reflow per mounted bar during every top-up. Width now
comes solely from the ResizeObserver's initial pre-paint delivery.
Prewarmed-but-hidden platform tabs also ran viewport sync per scroll
event and paid the visible surface's layout flush; hidden surfaces now
skip sync via a shared checkVisibility guard.
Measured on the 50-node/929-guest mock estate at 2560x1240: a 4-row
top-up fell from ~230ms to ~7ms, scroll-jitter oscillation produces
zero frames over 25ms, and sustained fast scrolling holds native frame
cadence with one bounded mutation frame per dead-band. The remaining
scroll-time long tasks are realtime websocket merge ticks, which the
realtime-merge lane already owns.
Contract-Neutral: Storage history behavior is documented in the staged API and storage contracts and covered by staged focused regressions; shared router references do not change agent-lifecycle, performance, or security contracts, and the proof allowlists do not yet name the focused test files.
Add a language-neutral condition key and explicit resource context to generic alert payloads so receivers can translate notifications without parsing English text.
Refs #1779
Change-source: pulse-maintainer
Align manually created Agent tokens with the runtime lifecycle minimum, expose agent:manage in custom create/edit flows, and document the backend-owned scope boundary.
Change-source: pulse-maintainer
The guest and node drawer history lock panel and the shared history
chart lock overlay said a range was 'not enabled on this instance'
without saying why. Both now state that longer ranges require a higher
license plan, and the drawer panel keeps the current plan's retained
days. Refs #1717
Per-comment stamps at continuous-automation volume made the machinery
louder than the maintenance. The standing disclosure is this page: it
now says plainly that day-to-day activity may be automated and
unstamped, that the tracker's pace is part of what is disclosed, and
that asking gets a straight human answer. Support email keeps its
per-message Pulse Triage identity.