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
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.
release/v6.3.2 becomes the governed branch for exactly version 6.3.2 via
the existing legacy_release_lines mechanism, so the surgical hotfix can
dispatch from its branch instead of shipping current main. Scoped to the
single version so 6.3.0/6.3.1 backfills and the 6.4 line stay on main.
Contract-Neutral: The release-note line documents an alert evaluator fix and does not change release promotion or artifact dispatch.
Change-source: pulse-maintainer
'My review' overstated per-change human review now that an autonomous
maintainer lands commits through the automated gates. Say what is
actually true: direction and responsibility are Richard's, review is of
the stream that lands, and the bar a fix must clear is his.
The 2026-08-25 evening perf pass re-profiled the remaining frontend
costs on the 50-node mock rig after d5440ff43. Idle main-thread burn on
a throttled phone (~10.5s of long tasks per 30s on the worst-case mock)
and residual warm tab-entry cost both decomposed into per-changed-row
work that ignores what actually changed: every metrics tick deep-cloned,
re-canonicalized, and fully re-merged each patched row, and both store
commits then deep-unwrapped the merged rows again through whole-row
keyed reconciles.
The server's resource delta is a JSON merge patch, so the change shape
is already known. applyResourceStateDelta now records the top-level
keys each patch touched (platformData expanded one level), the
connection store publishes them with the resource revision and unions
them across the bounded history and the hidden-tab deferral set, and
mergeCanonicalResourceDeltaSnapshot takes a fast path for changed
non-host rows whose keys stay within the pass-through metric fields,
the proxmox facet mirror, and the four platformData metric mirror
leaves: the previous display row with just those subtrees cloned in
(a manual plain-data clone — structuredClone's per-invocation setup
dominates at this size). Both commit sites write fast rows as per-key
subtree patches (nested reconcile for records, direct sets for
primitives and platformData leaves) instead of whole-row reconciles,
and the connection store commits aligned ticks per index. Any other
change shape — additions, removals, repeated patches in one frame,
structural keys, agent rows (host coalescing) — keeps the full
clone-canonicalize-merge path, and the fast output is pinned
content-equivalent to it in resourceStateAdapters tests; a websocket
store test pins the per-key change shapes, the meta-history union, and
its unknown-shape contamination.
Measured on the pulse-dev rig (VM-to-VM, 50-node/1500-resource mock,
worst-case RandomMetrics, vs two d5440ff43 baseline runs): mobile-4x
idle long tasks 10.8/10.2s -> 3.9s per 30s; warm Alerts entry 5-rep
median long-task total 3.85s -> 1.52s; mobile warm Overview return
3.8/1.7s -> 1.0s; desktop Backups entry settle 1.06/1.20s -> 0.71s;
warm Storage/Overview sub-tab switch medians flat within rep spread;
desktop cold load and /api/state size unchanged.
Browser-verified on the rig build of this tree: live ticks render
through the fast path with per-cell DOM-vs-store consistency at two
samples 30s apart, zero console errors, desktop and 390px/4x mobile.
The 2026-08-25 audit follow-up profiled the remaining frontend costs on
the 50-node mock rig. Entering a tab more than one websocket tick behind
the shared cache fell off the incremental path onto a full-estate
deep-unwrap merge — a 2.1s unwrap dominated warm Alerts entry at 4x
throttle — and the client-facing resource stream re-shipped ~3KB of
mostly-static metadata per resource on every snapshot, REST recovery,
and reconnect (governed gap resource-payload-static-metadata).
The connection store now keeps a bounded per-tick changed-id history and
serves unions from it, so an instance that mounts or resumes a few
revisions behind catches up with a delta merge over the union instead of
remerging the estate. Uncovered gaps and full-snapshot commits still
fall back to keyed full reconciliation.
Broadcast payloads dedupe the estate's distinct capability blobs into a
content-addressed state-level capabilityCatalog referenced per resource
by capabilitiesRef; default-posture resources (internal sensitivity,
cloud-summary routing, no redactions) omit policy and aiSafeSummary; and
canonicalIdentity.aliases no longer duplicates supersededIds. Ingestion
reverses all three: refs expand through the catalog as per-row clones
(reconcile mutates adopted objects in place), missing policies
synthesize the default posture so a policy:null transition patch cannot
strand a stale governed policy, and identity alias resolution consults
supersededIds explicitly. Slimming edits only the per-broadcast copy,
never stored monitor state, and the delta engine's generic top-level
field diff carries catalog changes in the same frame as the first
resource referencing a new entry.
Rig A/B on the pinned 50-node mock (same VM as the morning baseline,
single runs, +-30% variance; RandomMetrics mutates nearly every row per
tick, so this estate is the worst case for the catch-up union): mobile
4x Alerts entry settles 3.9s -> 2.0s with long tasks 5.5s -> 3.3s,
idle-30s long tasks drop 12.6s -> 10.8s mobile and 3.4s -> 2.8s
desktop, remaining steps flat within variance. Sparse-delta estates
gain more, because their catch-up unions stay small.
/api/state on the pinned mock estate drops 4.75MB -> 4.09MB (-13.9%);
the capability catalog is 7 entries totalling 2.5KB where 946 resources
previously inlined the blobs, and 806 default-posture resources shed
policy and aiSafeSummary. Browser-verified against a live build of this
tree: byte-identical UI outcomes vs the unmodified baseline across
overview/storage/docker/alerts probes at both viewports, with docker
container lifecycle actions enabled through catalog-expanded
capabilities. pulse-mobile and pulse-enterprise do not read the slimmed
fields; the AI runtime consumes the internal model, which is unchanged.
Contracts for monitoring, api-contracts, unified-resources,
performance-and-scalability, alerts, agent-lifecycle, and
storage-recovery are amended with the slimmed wire shape, the ingestion
synthesis obligations, the catch-up history, and superseded-id
resolution.