The expanded disk detail now shows its history charts in view, so this
test mounted HistoryChart, which measures itself with ResizeObserver.
jsdom has none, and the unhandled error failed the frontend job even
though every test passed. Chart rendering stays covered by the
HistoryChart and DiskDetail suites.
Beta cut from main at 1844f6c0ed. It carries every change merged since stable v6.5.0.
Contract-Neutral: Release-only v6.6.0-beta.3 version, release notes and distribution metadata; no public install or runtime contract changes.
Change-source: pulse-maintainer
The beta release train writes cumulative changelogs from the previous
stable, but the install packet check required the previous numbered
beta. Accept both supported comparison modes and continue rejecting
unrelated, missing or ambiguous bases.
Validation: targeted race tests and the failed beta.3 snapshot
regression, plus governance audits and native commit and push checks.
Preserve accepted 0efe3f7a12 and exact upstream ebfdc9d669 additively. Keep quiet unavailable captions, keyboard and touch reading explanations, stopped-agent provenance and primary CPU readings. Preserve stable denied-update help outside Details and all regression assertions.
Change-source: pulse-maintainer
Bind the existing Docs producer to its own parent: twelve desktop and phone navigation/code rows and eight native pixel inspections. Keep the first missing-touch-context failure and unavailable source-suite/build result explicit; this browser receipt is not native Kubernetes acceptance or delivery.
Contract-Neutral: Record existing-guide browser evidence only; no runtime, contract, entitlement or navigation delta.
Change-source: pulse-maintainer
The drawer range picker said "24 hours", the physical disk detail said
"Last 24 hours" and the storage pool detail said "24h", so the same
choice read three ways depending on where a reader opened history.
historyChartModel now owns one label table, and the drawer, disk and
pool pickers all take their option names from it: "1 hour", "24 hours",
"7 days". That matches how the rest of the app names durations (system
settings, Patrol schedule). The chart header's compact segmented range
buttons keep their short "24h" tokens; they are a different control and
are hidden inside these details.
Repair the two exact formatting failures found by the composed source check, without changing their assertions or product behavior.
Contract-Neutral: Mechanical formatting of tests only; no runtime or contract change.
Change-source: pulse-maintainer
Bind the combined backup presentation helper to its visible UTC instant and offset-equivalent input without changing any monitoring operation.
Contract-Neutral: Read-only browser assertion only; no runtime or product contract change.
Change-source: pulse-maintainer
rcourtman/Pulse#2913 moved the Proxmox guest and node drawers' charts
onto Overview and removed their History tab. This carries the same
change to the Docker host drawer and to the shared resource-detail
drawer (agent machines, containers, PBS, TrueNAS, Kubernetes and other
platform rows), so every platform drawer reads the same way: Overview
leads with the attention list and then the charts, and Manage holds the
controls.
- History charts render on Overview at 24 hours, with the range picker
beside them. The History tab is gone.
- Charts poll only while Overview shows. An active alert on a charted
metric draws its trigger (same `getDrawerChartAlerts` mapping, including
the MiB/s to B/s conversion for I/O).
- A snapshot that briefly drops the metrics target withdraws the charts
until it returns; the selected tab is kept.
- Storage page disk and pool details keep their own History tab. They
are separate components whose Overview has no charts to repeat.
Tests: the resource-detail, Docker and guardrail suites were updated to
the new layout, plus a new Docker host test for Overview charts paused
behind Manage. E2E specs 27 and 63 no longer click History.
Verification: typecheck and the Workloads, shared, Proxmox, Docker and
Infrastructure suites (305 files) on pulse-dev. I took full-resolution
screenshots of the built bytes at 1440 and 390px for a Docker host, a
container and an agent machine.
Not run: the manual `scripts/check-drawer-tab-retention.cjs` proof, now
adapted to select Manage, fails on main too because its fixture page
mounts the drawer without a WebSocket provider. The contract notes say
so.
Use the real millisecond timestamp field and await the producing fixture before recording consuming CPU evidence.
Contract-Neutral: Qualification fixture binding only; no product runtime or contract delta.
Change-source: pulse-maintainer
Pass the real in-memory node registry and frontend conversion through nodeFromResource into the containing chart consumer. GPU and NVMe peaks stay separate from the primary CPU field. Synthetic state only; no database, live API, guest or service operation.
Contract-Neutral: Read-only qualification producers and binding; product runtime and safety contracts are unchanged.
Change-source: pulse-maintainer
Qualify cache-reading disclosure with actual high pressure and preserve CPU facts while OS evidence changes. Document actual disk captions without mistaking memory-only N/A for disk state. Keep source/time, disclosure and missing-reading safety assertions.
Contract-Neutral: Test and read-only fixture reconciliation only; composed product contracts are unchanged.
Change-source: pulse-maintainer
The existing minimal role omitted the API metrics reads used by the collector, while its optional host recipe prescribed node-wide privilege and a shared host identity. Include only node/pod metrics reads, explain incomplete inventory and kubelet-summary limits, and replace that unsafe shortcut with deliberately separate host telemetry. Preserve the private-file Secret recipes and existing bookmarks.
Contract-Neutral: Correct existing Kubernetes operator guidance and consuming regression controls; no agent, API, RBAC runtime, token scope, entitlement or navigation change.
Change-source: pulse-maintainer
Retain the actual authentication refusal and existing client when the full-timeout session cannot be constructed after a successful short probe. Cover pinned HTTPS rejection, malformed and form-refused sessions, later ordinary recovery and the monitor endpoint projection.
Change-source: pulse-maintainer
Use the production column hooks, formatted per-filesystem evidence and committed fixture inputs for the composed drawer proof; no runtime or policy change.
Contract-Neutral: Qualification fixture formatting and exact consumer locators only.
Change-source: pulse-maintainer
Every resource drawer now charts history on its Overview. The storage
page's pool and physical-disk details were the last to keep it behind a
History tab, and that was their only other tab, so a reader opened a
pool or disk and then had to switch tabs to see whether it was filling
up or heating.
Both now render one view with no tab strip. A pool detail leads with its
Capacity Trend card, the range picker in the card header, followed by
configuration, topology and devices. A disk detail keeps its health
verdict and SMART facts first, as the evidence behind the verdict, then
its History charts with the range picker beside the heading, then live
I/O.
The storage contract had required these charts to stay behind the
History tab; it now records the 2026-10-13 decision instead.
Preserve exact published 170f726c history and min-max bands, primary CPU temperature and quiet captions alongside truthful disk unknowns, stale-Agent qualification and always-visible stable update guidance. Keep the existing text clipping controls rather than a tbody-ratio tolerance. Fresh consuming proof follows on these resolved bytes.
Change-source: pulse-maintainer
The release train explicitly compares the full beta range with the previous stable. Accept that supported base as well as the default previous numbered prerelease, while rejecting missing, ambiguous and unrelated comparison bases.
Contract-Neutral: Align release packet checks with the existing metadata contract. No public install or runtime contract delta.
PR 2913 moved the Proxmox guest and node drawers' charts onto Overview
and removed their History tab. The Docker host drawer and the shared
resource-detail drawer (agent machines, containers, PBS, TrueNAS,
Kubernetes and other platform rows) still kept the charts a tab away,
so the same kind of drawer behaved two ways depending on the page.
Both now render the history charts on Overview under the attention
list, opening on 24 hours with the range picker beside them, and drop
the History tab. Charts stop polling while another tab shows, and an
active alert on a charted metric draws its trigger the same way as in
the Proxmox drawers. A resource whose metrics target drops for one
snapshot simply loses its charts until the target returns; the
selected tab is kept.
Storage page disk and pool details keep their own History tab; they
are separate components and their Overview has no charts to repeat.
E2E specs 27 and 63 no longer click History; the drawer read starts
when it opens. The manual tab-retention proof now selects Manage. Its
fixture page fails before the drawer renders (no WebSocket provider)
on main as well, so it was not run.
Drawer charts plot one average per time bucket, so a short burst inside
a bucket (6 minutes at 24h; hourly rollups at 7d) averages away. The
trend cards removed in rcourtman/Pulse#2913 stated a "24h low–high"
range; this restores that information on the charts themselves.
- A tinted, outlined band behind each line spans each bucket's own min
and max (already in every stored point). A spike shows as a spire above
the average line; series that never spread draw no band.
- While a time is inspected (hover or the inspection slider), the legend
adds "peak X" for a bucket whose max rises at least a tenth of the plot
above its average. The default readout stays one number per series.
- The accessible value states each reading's average and range ("CPU
20.0% average, 10.0% to 99.0%").
Also fixes the post-merge E2E failure from rcourtman/Pulse#2913: spec 86
asserted the Memory rows in Details were fully in view with ratio
exactly 1. With the charts on Overview, CI landed that table on a
fractional offset and the rounded border clipped 0.4% (0.9956). It now
allows 0.98.
Verification: typecheck plus the Workloads, shared, Proxmox, Docker and
Infrastructure suites on pulse-dev. New proofs are in
`GuestDrawerHistory.inspection.test.tsx` and `GuestDrawer.test.tsx`.
Full-resolution screenshots at 1440 and 390px were taken against the
built bytes with synthetic spiky history; mock history barely spreads,
so it only shows a hairline halo.
Drawer charts plot one average per time bucket, so a short CPU burst or
I/O spike inside a 6-minute bucket (24h) or an hourly rollup (7d) shrinks into
the average and disappears. The trend cards this Overview replaced
stated a "24h low-high" range; the charts had nothing in its place.
Each stored point already carries its bucket's min and max. A tinted,
outlined band now spans those extremes behind every line, so a spike
stands as a spire above the average. Series whose buckets never spread
draw no band. While a time is inspected, the legend names that bucket's
peak when it rises at least a tenth of the plot above the average, and
the accessible value states each reading's average and range.
Spec 86 also allows sub-pixel clipping when it checks that the drawer's
Memory rows are fully in view. With the charts on Overview, CI placed
that table on a fractional offset and the rounded table border clipped
0.4% of it (ratio 0.9956), failing an assertion of exactly 1.
Opening a Proxmox guest or node drawer showed 24-hour trend cards for
CPU, memory and disk on Overview, then a History tab with the same
metrics in a different chart style, opening on 7 days, plus network,
disk I/O and thermals. One tab was a superset of the other.
This charts history on Overview itself and removes the History tab from
the guest and node drawers (tabs are now Overview and Manage):
- Overview reads: alerts line, Worth checking, the charts (24 hours by
default, range picker beside them), disks and sensors, facts strip,
closed Details.
- Charts poll only while Overview is shown, and show the live reading
(qualified current or last known) until history is stored. An offline or
stale node says so in one line and offers no live values.
- An active alert on a charted metric tones its reading and, with a
numeric trigger, draws a dashed line. I/O triggers are converted from
the alert engine's MiB/s to the charts' B/s.
- The facts strip carries the amounts behind the percentages: guest
vCPUs and used-of-total RAM and disk; node used-of-total RAM and root
disk.
- The range picker mints its id once per instance (a guest and a node
drawer can be open together). Legend readings are larger, and the charts
use two columns at medium widths.
Docker host and resource-detail drawers keep their History tab for now.
Verification: typecheck and the Workloads, shared, Proxmox, Docker and
Infrastructure suites (305 files, 5752 tests) on pulse-dev.
Full-resolution screenshots of the built bytes at 1440, 1000 and 390px;
the receipt lists what was exercised. The dashed alert line was not seen
in the browser (no Proxmox guest or node had a metric alert in the mock
estate) and is covered by unit tests.
Record actual desktop and phone consuming proof and native pixel inspection. Correct the test to distinguish native same-page fragments from routed cross-document links; the served guides are unchanged. Preserve the first failed suite and its three unrelated five-second timeouts for final validation.
Contract-Neutral: Documentation proof and test correction only; no runtime contract change.
Change-source: pulse-maintainer
Replace pre-retirement plan wording, unbounded log readers and speculative re-pairing or restarts with preserved evidence, bounded server log help and the approved phone-alert alternatives. Keep existing bookmarks and continuing Relay subscriber terms. This changes server documentation only, not app or Relay behaviour.
Contract-Neutral: Existing help correction only; no app, Relay, entitlement, API or runtime contract changes.
Change-source: pulse-maintainer
Record the requested daily beta cadence in the canonical release policy
and resolved decisions. Betas still require new source changes, normal
qualification and at least 24 hours between publications, with the
existing RC and stable promotion requirements.
Validation: native commit checks, governance tests, frontend lint and
type checking pass on pulse-dev.
Opening a Proxmox guest or node drawer showed 24-hour trend cards for
CPU, memory and disk on Overview, then a History tab with the same
metrics again, in a different chart style and opening on 7 days, plus
network, disk I/O and thermals. One tab was a superset of the other,
so the reader had to reconcile two views of the same data.
The guest and node drawers now chart history on Overview itself, under
the alerts line and Worth checking, opening on 24 hours with the range
picker beside the charts. The History tab and the trend cards are gone.
The charts stop polling while Manage is shown, show the live reading
(qualified current or last known) until history is stored, and an
offline or stale node says so in one line instead of offering live
values.
What the cards carried and the charts lacked moves with them:
- An active alert on a charted metric tones its reading and, when it has
a numeric trigger, draws it as a dashed line. I/O triggers are
converted from the alert engine's MiB/s to the charts' bytes per
second, and networkIn/networkOut map to the netin/netout series.
- The facts strip states the amounts the percentages are of: guest
vCPUs and used-of-total RAM and disk, node used-of-total RAM and root
disk (capacity only while a node's readings are withheld).
The range picker now mints its id once per instance, so a guest and a
node drawer open together no longer share a label target. Legend
readings are a step larger and the timestamp quieter, and the charts
use two columns at medium widths. Docker host and resource-detail
drawers keep their History tab for now.
Give each installer and signature transfer a five-second connection and sixty-second total budget, ignore ambient curl settings and preserve HTTPS through redirects. Failed or partial downloads leave the prior install, service and identity unchanged; pinned signature admission and recovery deadlines are unchanged.
Change-source: pulse-maintainer
Verify the production Backups producer/consumer and real installer at desktop and phone widths in both themes. Inspect all 34 final native captures; preserve prior adverse results and distinguish consuming proof from installed or reporter recovery.
Contract-Neutral: Own-parent browser evidence only; runtime and subsystem contracts are unchanged.
Change-source: pulse-maintainer
Separate resource-owned PBS health and identity from inventory loading/error gates. Preserve source-specific notices, unknown counts and ordinary retries; make complete optional signing environment names readable on phones without changing trust or copying.
Change-source: pulse-maintainer
The Workloads guest table put a second line under memory and disk cells
that repeated an empty cell and gave no reason: "N/A / Unavailable" and
"- / Unavailable" on every stopped guest, "Unavailable" under every
agentless VM's disk, and "May include cache" under every agentless VM's
memory bar regardless of value.
What changes:
- Memory that cannot be read renders the same dash as an unreadable
disk. Its reason stays in the cell title, the sparkline's hover title
and assistive text. Sparkline accessible values are unchanged.
- Disk shows a visible label only for a retained reading (Last known /
Prior) or a read the user can fix (No permission / Agent error, amber).
Stopped VMs, missing guest agents and lock deferrals show the dash.
- "May include cache" appears only when the guest's own memory is at its
warning or critical threshold (the figure the bar is coloured by, in
host-share mode too), the case from #2762 and #2639. Below that, the
caveat is title and assistive text.
- Unavailable memory explanations name what is known rather than
"Unknown source"; a powered-off guest reads "Unavailable while the guest
is powered off."
- `MetricMiniSparkline` gains an optional `tooltip` so the chart
covering the cell carries that reason without changing its accessible
name.
User guide: `docs/VM_DISK_MONITORING.md` (and its shipped mirror) now
describes the labels the row shows, and
`test_guest_disk_reading_docs.py` pins them. This replaces #2893, whose
docs recipe test still expected the old labels.
Contracts: `frontend-primitives.md` and `performance-and-scalability.md`
describe the new caption rules. Four browser proof scripts and
`86-hybrid-memory-browser.spec.ts` are updated to the new behaviour; the
proof scripts need their container harness and were not run here.
Verification: Workloads suites (106 files, 2160 tests),
`memoryObservation` and `MetricMiniSparkline` tests, lint, Prettier and
type check pass. Browser receipt `6e39cc0902eefe58.json` records a live
pass on a mock stack built from main, in Bars and Trends at 1900x1100
and 375x812: captions only on the cache VM at warning, dashes on stopped
and agentless rows, rows 32px / 44px, no overflow.
When Proxmox denies the package-update request, node Overview explains
why metrics can still work and offers guidance on read-only access
versus Sys.Modify. Update evidence wraps on narrow screens. The shared
help dialog retains its state through polling and stays inside the
viewport during resize and scrolling. Learn more opens Pulse's shipped
troubleshooting section.
Verified with targeted component and documentation-link tests, the
documentation drift check, full frontend type-check, lint and production
build, and Playwright at 1440x900, 900x900, 390x844, 320x640 and
844x390. Browser checks cover retained counts, recovery, keyboard and
touch input, dismissal, focus return, scrollable help and the actual
documentation route and section anchor. Source-bound browser receipts
cover the final source bytes.
Refs #1802
The Workloads table put a second line under memory and disk cells on
every stopped guest ("N/A / Unavailable", "- / Unavailable"), on every
agentless VM's disk, and "May include cache" under every agentless VM's
memory bar, even at 20%. None of them said why or what to do, and they
broke the row rhythm.
Memory that cannot be read now renders the same dash as an unreadable
disk, with its reason in the cell title, the sparkline's hover title
and assistive text. Disk shows a visible label only for a retained
reading (Last known) or a read the user can fix (No permission, Agent
error). The cache caption appears only when the guest's own memory is
at its warning or critical threshold, the figure that colours the bar
in host-share mode too, which is the case #2762 and #2639 were about;
below that the caveat stays in the title and assistive text.
An unavailable memory explanation names what is known instead of
"Unknown source": a powered-off guest reads "Unavailable while the
guest is powered off." MetricMiniSparkline gains an optional tooltip
so the chart covering the cell can carry that reason without changing
its accessible name.
Retain the exact existing safety candidate after returned final drawer proof; preserve current consuming source and mock History refinements. Native restart, every-volume History and independent thaw remain unverified.
Change-source: pulse-maintainer
Bind final merged source to desktop, phone, landscape and touch checks,
including disclosure dismissal, retained evidence and shipped docs focus.
Refs #1802
Preserve main's neutral denied-access state, wrapped Details and current
node metrics while retaining permission help across reading updates.
Verify disclosure dismissal, responsive placement and shipped docs.
Refs #1802
Three rules chose a node's single CPU temperature. Node history took
CPUMax first, agent history took cpu_package first, and the node drawer
recomputed the maximum of package, CPUMax and every core in the
browser. On an agent-fed node CPUMax is built from cores alone and can
sit below the package, and elsewhere a core can run above the package,
so the drawer's CPU temperature headline could disagree with the line
drawn beneath it and with the History tab. Node alerts and the CPU
low/record tracking used yet another package-first rule.
models.PrimaryCPUTemperatureCelsius is now the one rule: the hottest
usable package, CPU-maximum or core reading, with a sensor-map form for
agents. Node and agent history, the router's live fallbacks, the
unified resource temperature, node temperature alerts and the CPU
low/record tracking all call it. The drawer reads the resource value
through a new Node.cpuTemperature field instead of recomputing it, and
getCpuTemperature is removed.
Mock mode wrote a second package reading under a cpu.package key into
every agent host, including node-linked ones, from a series unrelated
to the node's static reading. A node and its linked agent now carry one
reading, sampled from the agent's series under the agent's real keys,
and both histories seed from that series, so the current reading
continues the line.
The help link followed branch-tip GitHub content, violating the runtime
documentation contract and preventing the guidance from landing. Point it
at the canonical in-app troubleshooting section.
Refs #1802
Contract-Neutral: Restore the existing shipped-documentation link contract without changing public APIs or shared primitive behavior.
Three rules chose a node's single CPU temperature. Node history took
CPUMax first, agent history took cpu_package first, and the node drawer
recomputed the maximum of package, CPUMax and every core in the
browser. On an agent-fed node CPUMax is built from cores alone and can
sit below the package, and elsewhere a core can run above the package,
so the drawer's CPU temperature headline could disagree with the line
drawn beneath it and with the History tab. Node alerts and the CPU
low/record tracking used yet another package-first rule.
models.PrimaryCPUTemperatureCelsius is now the one rule: the hottest
usable package, CPU-maximum or core reading, with a sensor-map form for
agents. Node and agent history, the router's live fallbacks, the
unified resource temperature, node temperature alerts and the CPU
low/record tracking all call it. The drawer reads the resource value
through a new Node.cpuTemperature field instead of recomputing it, and
getCpuTemperature is removed.
Mock mode wrote a second package reading under a cpu.package key into
every agent host, including node-linked ones, from a series unrelated
to the node's static reading. A node and its linked agent now carry one
reading, sampled from the agent's series under the agent's real keys,
and both histories seed from that series, so the current reading
continues the line.
Exercise the production renderer and router with final containing source and shipped Markdown. Verify keyboard/touch links, focused fragments and preserved-state guidance; inspect all six native captures. Retain the original source and pre-execution browser failures, and the corrected composition test, without replaying unchanged suites.
Contract-Neutral: Source-bound browser proof only; no additional product or subsystem contract change.
Change-source: pulse-maintainer
Select each rendered workflow by its unique label instead of a position. Keep every copied-command safety assertion from current source and the memory distinction from the PBS candidate; their merge changed row order, not guidance semantics.
Contract-Neutral: Documentation regression selectors only; no public behaviour or subsystem contract change.
Change-source: pulse-maintainer
Preserve cb778998d7 identity and its unchanged frontend runtime. Resolve duplicate drawer receipt, contract and regression assertions to the already-qualified canonical versions; neither a merged receipt nor synthetic proof is native recovery.
Change-source: pulse-maintainer
Preserve exact Delivery geometry-repair commits atop the reconciled drawer source and its own-parent browser receipt. Require each recovered reading to be visible without mistaking decorative table edges for clipped text.
Change-source: pulse-maintainer