Commit Graph

731 Commits

Author SHA1 Message Date
rcourtman 3b566f59d1 Keep organization browser fixtures within server operation contracts
Arrange activated organizations before the first workspace load and retain ownership when preparation fails. Give activation and graceful tenant deletion explicit request bounds matching the existing server deadlines, while preserving overall journey deadlines and failure verdicts.

Attempt every owned cleanup and retain the final native backend log before teardown removes its runtime. Controlled fixture and backend lifecycle tests pass, and all twelve organization-route cases pass across Chromium, mobile Chrome and mobile Safari with retries disabled.
2026-10-25 02:52:03 +00:00
rcourtman 12d050a5be Wait for resolved workspace routes before browser journeys
A mounted cookie shell can still be waiting for its default workspace
redirect. Admitting that entry races the next deep link in WebKit. Wait
for the destination and retain controlled missing-admission and resource
snapshot coverage, including rejection of the old helper predicate.

Use the shared content-owner geometry audit for infrastructure onboarding
and assert SPA route changes without waiting for the document load event.
2026-10-25 01:41:31 +00:00
rcourtman 7a211a6f92 fix(e2e): audit scroll position and width in one snapshot
Finish content that reflows after native settings traversal before judging
its width. Measure bottom position and horizontal overflow together, and
keep unchanged-extent scroll resets as failures.

Native Chromium and WebKit controls reproduce the separate-read race,
verify the newly revealed footer, and retain overflow and reset detection.
2026-10-25 01:38:54 +01:00
rcourtman 56125b9e21 test(e2e): verify receipt upload conditions by their behavior
Evaluate the stable upload expressions for clean passes, retained failed
attempts and cancellation. Preserve failure receipts and pre-probation
ordering while allowing recovered retry diagnostics and completed JUnit.
Negative controls reject missing failure retention and ignored cancellation.
2026-10-25 01:01:11 +01:00
rcourtman 72f6d2cf7d fix(e2e): synchronize editor commits and retain retry diagnostics
Judge consuming panels after their protected document has mounted, and
give the delayed-token regression its own bootstrap page. Leave the whole
Alerts editor before checking for a staged change, including its desktop
focus and card Save contracts. Keep the existing panel timeouts.

Preserve failed-attempt HTML diagnostics when a first retry succeeds and
retain small JUnit results for every completed tier. Upload stable evidence
before probation starts. Integrate the published node disk observation
repair before qualification.
2026-10-25 00:33:48 +01:00
rcourtman c0c54de765 fix(e2e): await authenticated bootstrap in cookie-only fixtures
Fresh password login must await the mounted workspace before a caller
opens an onboarding route. Own and revoke the bootstrap regression token
without replacing the primary credential, and bootstrap update API tests
once per worker when CI provides cookies alone.

Opt the synthetic shared-IP stack into a finite development update budget
without changing production, authentication or configuration limits.

Observe gated panels through actual gate readiness. Keep the fixed 24h
growth assertion on its native header and select the retained LXC drawer
with the fixture's canonical resource identity. Integrate the published
filesystem-observation and issue-topic repairs before qualification.
2026-10-24 23:50:14 +01:00
rcourtman 3f5788f738 merge: preserve published backup and intake test repairs
Current main strengthens completed-restore-point calendar selection and
filter reset coverage, and recognises declared Pro runtime artifacts during
issue intake. Preserve those published contracts in the verified E2E slice.
2026-10-24 22:44:18 +01:00
rcourtman 708e8f94fb merge: reconcile current monitoring and E2E contracts
Preserve published absent-disk, completed-backup and accessible-name fixes
alongside the verified drawer and resource-provenance changes.

Follow native inventory disclosures, full settings scroll geometry and
shared disk-history responses so browser proofs exercise the current UI
without weakening row, layout, signature or chart-latency budgets.
2026-10-24 22:39:27 +01:00
pulse-triage[bot] f51fca0c92 Find the selected calendar day by its updated accessible name
Selection appends selected to the calendar button name. Assert that selected name rather than continuing to resolve the unselected-button locator.

Contract-Neutral: Test-only locator for the existing calendar selection state; no product contract changes.
Change-source: pulse-maintainer
2026-10-24 21:47:08 +01:00
pulse-triage[bot] 1b32222549 Keep backup layout checks aligned with completed restore points
The protected backup completion repair renamed the activity chart and inventory counter. The normal E2E run now spends four two-minute waits looking for retired copy. Exercise the current completed-point calendar and backup-entry inventory without reverting truthful product labels, lowering timeouts or skipping coverage. Retain the year-long containment and PBS-column assertions, and verify selecting and clearing a day.

Contract-Neutral: Test-only selector and filter-state assertions for the existing backup completion contract; no runtime, API, route, schema or permission change.
Change-source: pulse-maintainer
2026-10-24 21:46:48 +01:00
rcourtman 58f9398a41 fix(e2e): preserve accessible controls and deep drawer navigation
Preserve source provenance in REST-loaded resources so owning-snapshot
consumers retain provider context and host placement. Keep visible control wording in accessible names and retain readable command
and navigation text in both themes. Token fixtures now await mounted browser
bootstrap before handing control to the next journey.

Measure bounded platform table items together with their inline details so
scrolling down a tall drawer cannot unmount the resource being inspected.
Retain regression coverage for bootstrap timing, drawer state and scroll
extent, responsive controls, Patrol and availability, and align navigation
assertions with current read-only capabilities and composed resource queries.
Provider fixtures retain one authoritative inventory across transport updates.
2026-10-24 21:41:34 +01:00
pulse-triage[bot] 55bee44d30 Patch portal Vitest and preserve counted navigation names
Align the portal runner and mocker with the main UI's 4.1.12 security floor and retain its generated source binding. Keep the already repaired main-UI dependency graph unchanged. Use the updated integration checker without dropping WCAG assertions: desktop and mobile labels now contain their visible badge text, with mixed alert severity retained in the accessible description. Add maintained floor and naming coverage and bind the consuming desktop/phone proof to this parent.

Change-source: pulse-maintainer
2026-10-24 13:17:03 +01:00
pulse-triage[bot] 88c5bf42b2 Align Linux auth snapshots with current Settings navigation
Retain the unchanged Authentication form, reflect Plans and Billing, External agents and organisation billing, and remove the retired Assistant affordances. Use reviewed exact-source captures after reproducing the original3545-pixel mismatch with its native DejaVu renderer; do not alter Darwin baselines, thresholds, masks or authentication.

Contract-Neutral: Current-navigation Linux browser baseline repair only; no product, API, route, access or capability contract change.
Change-source: pulse-maintainer
2026-10-24 08:15:55 +01:00
pulse-triage[bot] d4cc3effe4 Share the live billing plan path between first-session checks
Use the existing pricing handoff destination rather than constructing a URL from the internal tab identifier. Keep the consuming Current plan heading assertion so a missing route cannot pass.

Contract-Neutral: Browser-test path correction only; no product route, access or commercial contract delta.
Change-source: pulse-maintainer
2026-10-24 07:40:12 +01:00
pulse-triage[bot] ba7c97fb97 Check the real Plans and Billing route during Settings smoke
Require each consuming panel to finish loading; an unrelated heading on the removed system-pro route previously let Page Not Found satisfy the smoke test.

Contract-Neutral: Browser-test target and readiness assertion repair only; no runtime, route, access or commercial contract changes.
Change-source: pulse-maintainer
2026-10-24 07:38:48 +01:00
pulse-triage[bot] 567fcb9607 Wait for each Settings panel's own completed content
Use route-specific consuming headings, including the existing commercial billing shell, rather than requiring every Settings surface to use the same card primitive.

Change-source: pulse-maintainer
2026-10-24 06:55:12 +01:00
pulse-triage[bot] bb903ef7d6 Keep Settings actions visible and browser fixtures isolated
Wrap bounded Settings header actions without covering the title. Detect clipped audit controls, keep the isolated Attention resource lookup inside its fixture, and measure completed Settings panels in a cookie-backed fresh document.

Contract-Neutral: Responsive layout and browser-fixture/assertion repairs only; no API, authorisation, route or capability contract changes.
Change-source: pulse-maintainer
2026-10-24 06:45:55 +01:00
pulse-triage[bot] 95e7d8e719 Check the selected backup subject's actual evidence explanation
The restored batch assertion exposes two further stale copy assumptions: posture explanations no longer have client state prefixes, and absent restore evidence now distinguishes incomplete history from a readable empty list. Compare the selected row with its actual server response and require the current qualified evidence messages. Preserve compact rows and mobile containment.

Contract-Neutral: Browser assertions only; existing runtime explanations, access boundaries and recovery semantics are unchanged.
Change-source: pulse-maintainer
2026-10-24 04:38:37 +01:00
pulse-triage[bot] e28d6e12ac Verify complete bounded backup posture batches for large estates
The default mock estate exceeds one 200-workload batch. Read the independent paginated fixture inventory and require the exact request count, bounded unique subjects and complete partition instead of assuming every fleet needs one request. Preserve evidence disclosure and mobile containment assertions.

Contract-Neutral: Browser test correction only; no runtime, API, recovery authority or product contract change.
Change-source: pulse-maintainer
2026-10-24 04:34:30 +01:00
rcourtman 28172a907b Retire the Assistant chat window; alert Investigate runs Patrol
Pulse Assistant was a chat drawer beside the monitoring UI. Operators who
want to talk to their infrastructure already use Claude Code, Codex, or
another MCP client, and Pulse MCP gives those agents the same governed
tools. Keeping a second, weaker chat in the web app cost a 66 kB chunk,
a launcher on every page, hand-off buttons on alerts, findings, approvals
and drawers, and thousands of lines of OpenCode-parity drawer code, for a
feature the maintainer judged ineffective.

This removes the browser chat and everything that only fed it:

- The drawer, its launcher (desktop and phone), the command-palette
  Assistant commands, the Escape and blocking-dialog shell plumbing, and
  the chat store, client, dev stream fixture and generated SSE types.
- Every "Open in Assistant", "Explain with Assistant", "Discuss" and
  "Ask Assistant" hand-off on alerts, incident timelines, Patrol findings,
  approvals, run history, the attention workbench and resource drawers,
  with their context models and the chat-only helpers they used.
- The Assistant settings page and its session maintenance section. The
  page becomes "External agents" at /settings/pulse-intelligence/agents;
  the old /assistant path, ?tab=assistant and system-ai-assistant redirect
  there with the hash kept.

Alert Investigate now starts a targeted Patrol run (resource, alert ID and
type) and says where the findings land, and it ignores repeat clicks while
the request is in flight. The run route needs an admin with ai:execute, so
security status gains settingsCapabilities.patrolRun, derived from the same
snapshot as the other admin capabilities but following the route for
org-scoped admins, organization-bound tokens and a cookie beside a token,
and Investigate is offered only where it is true. The Patrol
tool transcript block moves to components/patrol. A small aiAvailability
store holds the session assistantEnabled fact that gates Patrol entry
points and Investigate; it now clears and refreshes on organization switch,
refreshes when organization loading settles on another org and after
provider removal, and ignores answers that arrive after a newer one.

The backend chat service stays: Patrol investigations run on it and
Pulse Mobile chat uses it until 31 March 2027, so /api/ai/chat, the
session endpoints and the stream contract are unchanged. A new contract
snapshot pins the steer_applied event that only the deleted TypeScript
projection used to cover.

highlight.js, used only by the chat's code highlighter, leaves the
dependencies, as does the DOMPurify carve-out that kept its fence hints.

Contracts, registry and readiness proofs drop the retired surfaces; the
ai-runtime contract loses about 1,600 lines of drawer rules while keeping
every backend session, stream and provider rule. The production build
ships about 100 kB less gzipped JavaScript.
2026-10-23 00:15:04 +01:00
rcourtman 5d96811f3b test(e2e): run licence activation against the offline issuer
Spec 10 skipped on every run: it issued and revoked real licences through
the production licence server and needed an admin token no workflow had.
Its selectors had also rotted against the current plan page ("Existing
purchases", "Activate Key", "No Pro license is active"), so licence
activation, the path every paying customer takes, had no running browser
coverage.

The in-memory Ed25519 issuer behind the Organization provisioning job now
mints a second ephemeral key whose grants carry the Pro plan. The spec
pastes that key into the plan page's license recovery field, checks the
Pro state in the UI and the entitlements API, and clears it back to
Community through the UI. The offline CI job runs it with the same
wrapper, so no production credentials or signing material are involved.
Spec 11's plan-panel matcher drops the labels that no longer exist.

Contract-Neutral: Adds a CI step running an existing spec through the existing offline issuer wrapper; E2E image distribution and installability are unchanged.
2026-10-22 12:18:10 +01:00
rcourtman 02e53bc777 build: move to Go 1.26.10 and Vite 6.4.5 for October advisories
Go 1.26.10 (20 October) distrusts the compromised eMudhra intermediate
CAs in crypto/x509 (CVE-2026-111943). Binaries built with 1.26.9 still
accept chains through them, so every verified outbound TLS connection
Pulse makes (licence, updates, webhooks, AI providers) stays open to
interception by a holder of those keys. govulncheck does not flag a
trust-store change as a called symbol, so the scheduled scan stayed
green while the gap existed.

Advance the governed toolchain floor and every pin together: go.mod,
the toolchain installer and release-script guards, the source-built
container stages (manifest-list digests for golang:1.26.10-alpine and
the Debian dev container image), the root-pair diagnostic, and their
tests.

Vite 6.4.3 bundles a launch-editor with three advisories
(GHSA-587h-7wmj-h5pm, GHSA-r825-w8mm-5pxw, GHSA-698v-4r3x-3vcv) that
failed the daily advisory watch. 6.4.4 bundles the fixed launch-editor
and 6.4.5 adds the dev-server server.fs query check. Both reach only
the local dev server, not the built product. The lockfile changes only
the vite entry, and dependencySecurity.test.ts now pins the floor.
2026-10-21 15:19:02 +01:00
rcourtman 49d437331e commercial: give the Pro plan card a price, groups and a clear action
The Pro comparison card on Plans & Billing was a half-width box of small grey text: no price, every feature at the same weight, and a small outline link as the only way to buy. It now has a header with the plan name, a one-line tagline, the price and a primary View plans button, then the features in three labelled groups with check marks: for your team, for larger estates, and Patrol and history.
2026-10-21 11:49:17 +01:00
rcourtman e306ce7b46 commercial: let free installs find Plans & Billing and buy Pro
A free self-hosted install had no way to buy from inside Pulse. Plans &
Billing was unlisted, the plan page showed only the current plan unless an
upgrade prompt had sent the operator there, and those prompts are hidden on
free installs. Plan-locked lines in Settings said "Higher license plan
required" without saying where the plan lives.

Plans & Billing is now listed for every install that does not hide
commercial surfaces, and its plan page shows a free install the Pro
comparison and its purchase action. Plan-locked lines in Settings link to
it. Proactive surfaces stay quiet: no badges, banners, trial prompts or
upgrade calls to action on monitoring pages, and demo and white-label
runtimes still hide everything commercial.

Purchase start also failed for plain-HTTP installs on a LAN address, the
default homelab setup, because there is no secure address to return the
signed purchase token to. Those installs now get a handoff that finishes
on the website, which shows and emails the activation key; no return token
is minted or sent over plain HTTP.
2026-10-21 10:21:16 +01:00
rcourtman 52c0c831e8 licensing: send in-app Buy to the licence server purchase page
Every Buy, Upgrade and Renew action opened the Pulse Account portal on cloud.pulserelay.pro, which has returned a Cloudflare 522 since hosted Cloud was hibernated on 2026-06-01, so no one could buy from inside Pulse. The licence server now serves the same handoff-to-checkout page at https://license.pulserelay.pro/buy, using the existing portal handoff and checkout session APIs, so payment still returns to the instance and activates it.
2026-10-21 09:17:45 +01:00
rcourtman 45a82ea03c Merge current notification reliability repairs into maintenance
Preserve the landed L6 source, response-verdict controls and ownership evidence
alongside the maintenance source repairs. Final protected checks and native
qualification must cover this combined source before landing.
2026-10-18 17:21:17 +01:00
rcourtman 17527049ea Align notification operator checks with retained-failure copy
Terminal failures can stop early and do not prove retry-budget exhaustion.
Update the existing operator qualification expectation to match the shared
retention description already exercised in the browser.
2026-10-18 15:15:53 +01:00
rcourtman 2fc54a5a1f Merge pending maintenance repairs with current main
Preserve selected memory freshness and the VM/LXC interpretation.
Retain both native tool contracts and current API concurrency controls.
Qualify this source separately from release and installed recovery.

Contract-Neutral: Integrate already-governed parents without a new contract change. Incoming verification files already match main. Fresh integration tests and source-bound browser proof cover the combined memory and installer surfaces.
2026-10-18 15:11:28 +01:00
rcourtman a224a1a195 Measure aggregate reporting outcomes and repeat use
Record successful response writes, scheduled generation, file saves and SMTP
outcomes in a durable content-free tally. Distinct active days include manual
exports, while saved-schedule periods deduplicate retries and monthly reuse.

Publish bounded scalars through the existing opt-out-controlled heartbeat and
report missing coverage explicitly. Preserve pricing and customer entitlements.
2026-10-17 21:10:17 +01:00
rcourtman 84226ad7bc Count successful history reads beyond seven days
Measure delivered extended history before changing free and paid features.
Count only successful responses containing an older metric point and retain
only bounded daily totals. Expose the rolling sum through schema v19 and
Preview with matching privacy disclosure and explicit report coverage.
2026-10-16 19:21:03 +01:00
rcourtman aae71f50e2 Name the notification switch the same in both states
The Alerts overview header switch was labelled "Notifications enabled"
or "Notifications paused" depending on its own position. Beside an off
switch, "Notifications paused" reads as "paused: no", the opposite of
the truth, which can leave someone expecting alerts that are never
sent. The paused banner below said the reverse, so the reader had to
reconcile two signals.

The switch is now labelled "Send notifications" in every state (German
and Spanish too), and that visible label names the checkbox, so the
switch position alone carries the state. The paused banner and the pause
toast still say Pulse keeps detecting alerts, which keeps detection and
delivery distinct as the 2026-07-18 change intended. The sr-only
"Toggle external notifications" name and the two state keys are gone,
spec 01 finds the switch by its new name, and the troubleshooting and
webhook guides name the switch instead of the old state label.
2026-10-16 10:37:14 +01:00
rcourtman 84539aad35 Match the History Resource button by its full name in E2E
PR 2968 named each Alerts > History row control after its alert, so a
Timeline button now reads "Timeline for Resource Health on app-01, ...".
Specs 36 and 28 looked the Resource button up with Playwright's
substring name match on "Resource", which also matches a Timeline button
whenever the alert's title contains that word: spec 36 failed on mobile
with a strict-mode violation. Both specs now match the Resource button's
own name, "Resource incidents for ...".
2026-10-15 13:38:45 +01:00
pulse-triage[bot] 5050ee55ba Compose published drawer refinements with reviewed maintenance
Change-source: pulse-maintainer
2026-10-14 15:08:41 +01:00
rcourtman b6e1fd18bc Give agent, container and Docker host drawers the Proxmox Overview
The Proxmox guest and node drawers lead with alerts, lift anything wrong
into Worth checking, show the charts, one facts line and a closed Details
section. The other object drawers still opened large always-visible
cards: an agent's Operator Context card holding only an IP, a
container's digests and label inventory, five Docker host cards that
mostly restated the row.

The shared resource drawer and the Docker host drawer now follow the
same Overview. A "No active alerts" line, rows lifted in front, the
charts, a facts line that adds what the row lacks (container image and
Compose service; host CPUs, RAM and disk used of total, address), and
every inventory section, provider Platform details included, under one
closed Details.

Lifting follows evidence, not only colour: an available image update
carries an explicit lift flag; an offline resource's state is
danger-toned with when it was last seen, so it is never hidden behind
Details; a row the resource's own alert already states stays in Details
instead of repeating it. Facts state used amounts only for an online,
current reading. An availability endpoint keeps its check cards in
front, since they are its whole reading.

Reviewed twice by Sol from before/after screenshots at desktop and
phone width; the second pass confirmed the first round's findings
resolved and led to the alert de-duplication.
2026-10-14 14:00:23 +01:00
pulse-triage[bot] 9085539f03 Gate ordinary E2E on auth renderer controls
Run the existing credential-free diagnostic regressions in tier admission before dependency installation or image/shard work. Check the actual workflow wiring alongside the read-only collector and unchanged strict goldens.

Contract-Neutral: Invoke existing auth-renderer regression controls in CI; no public contract, dependency, golden or threshold changes.
Change-source: pulse-maintainer
2026-10-14 07:18:13 +01:00
pulse-triage[bot] bd6de2bed3 Retain actual auth renderer facts beside strict goldens
Current hosted E2E stays green with an adverse probation auth comparison, while local auth pixels use a different observed font. Attach actual heading font selection, browser and viewport identity, and complete loaded stylesheet hashes before each existing strict comparison. Keep diagnostic gaps explicit, omit page/account/URL/CSS contents, and never change styles, baselines, thresholds or assertions.

Contract-Neutral: Add read-only test diagnostics for existing auth goldens; application, permission, deployment, screenshot and security contracts are unchanged.
Change-source: pulse-maintainer
2026-10-14 05:57:02 +01:00
pulse-triage[bot] f90a3da1c7 Keep the full Pulse Mobile retirement notice readable on phones
Current 390px consuming pixels showed the free-tier notice still inside a two-line sales gate, clipping the phone-alert alternatives. Use the shared labelled InlineNotice for that existing guidance, retain the entitled configuration and pairing controls, and target the actual notice rather than the hidden mobile page subtitle. No offer, entitlement, billing, configuration or service change is introduced.

Change-source: pulse-maintainer
2026-10-14 03:21:16 +01:00
pulse-triage[bot] 5384298c17 Use the current scoped phone review navigation label
The current source renders Next issue inside Review queue navigation; the phone proof still requested the old Next decision label. Preserve the scoped navigation, disabled previous control, focus, containment and reload checks while selecting the current button.

Contract-Neutral: Test-only selector update preserves the existing phone navigation and Patrol contracts.
Change-source: pulse-maintainer
2026-10-14 03:15:30 +01:00
pulse-triage[bot] e19d17af53 Exercise Patrol evidence through its current keyboard disclosure
Current consuming proof found the retained observation text hidden inside the deliberate Evidence and history disclosure. Check that boundary, open it by keyboard, keep every evidence, protection and lifecycle assertion, and attach the actual expanded detail. The synthetic shell also supplies the existing empty active-alert array rather than an invalid catch-all object.

Contract-Neutral: Test-only keyboard disclosure and typed fixture repair preserves Patrol and alert runtime contracts.
Change-source: pulse-maintainer
2026-10-14 03:13:40 +01:00
pulse-triage[bot] a1824f157a Supply the real digest shape in the Patrol attention fixture
The isolated current-source consumer entered its error boundary when Activity parsed the fixture catch-all empty object as a successful weekly digest. Supply the existing empty history fields, with no fabricated verified work, so Activity navigation remains tested alongside the unchanged acknowledgement, evidence and failure controls.

Contract-Neutral: Test-only fixture supplies the existing Patrol digest schema; runtime and operational contracts are unchanged.
Change-source: pulse-maintainer
2026-10-14 03:12:00 +01:00
pulse-triage[bot] 5e2bd40c87 Keep phone reload proof aligned with the resource-qualified Patrol title
The original detail assertion now matches the current resource-first title, but the same phone journey still required its obsolete title after reload. Assert the same canonical identity across both navigations without changing the fixture title or reducing detail, overflow, focus or adverse-state controls.

Contract-Neutral: Test-only selector repair preserves the existing Patrol title and operational contracts.
Change-source: pulse-maintainer
2026-10-14 03:06:29 +01:00
pulse-triage[bot] 30bce19ac5 Retain existing paid-phone controls in the navigation journey
After following the real entitled sidebar, read the existing Mobile controls and retirement date without pairing a phone or changing configuration. Keep new-sale prompts absent.

Contract-Neutral: Existing-flow browser assertions only; no licence, mobile service or offer changes.
Change-source: pulse-maintainer
2026-10-14 02:18:36 +01:00
pulse-triage[bot] 9e81bd661e Align browser guards with retirement and current navigation
Preserve auth pixels, hidden-form and entitlement controls while pinning the visual runtime/org inventory. Exercise the existing Mobile retirement notice separately from sales gates, and retain scoped Coverage links and resource-qualified Patrol decisions. Supply the real runtime providers to the existing PBS snapshot fixture.

Contract-Neutral: Test and browser-fixture repair only; no runtime, entitlement, retirement or monitoring contract changes.
Change-source: pulse-maintainer
2026-10-14 01:38:16 +01:00
pulse-triage[bot] 1a27471600 Reconcile published Overview charts with reviewed recovery guidance
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
2026-10-14 00:08:44 +01:00
rcourtman 5168ae6460 Chart history on Overview in Docker host and resource drawers
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.
2026-10-13 23:30:46 +01:00
rcourtman 77131c19b1 Show each bucket's min-max range behind drawer chart lines
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.
2026-10-13 22:59:35 +01:00
rcourtman 070d0a36fb Chart drawer history on Overview and drop the History tab
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.
2026-10-13 22:15:36 +01:00
rcourtman 160701bb42 Drop guest row captions that repeat an empty cell
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.
2026-10-13 21:08:59 +01:00
pulse-triage[bot] ff1e59ff33 Make the table-edge geometry control demonstrate its intended clipping
The first native pass verifies the complete canonical memory journey but exposes a faulty positive geometry control: collapsed borders alone did not reduce its target intersection. Make the synthetic table wider than its clipping container while keeping every text line safely inset. Preserve all negative clipping/hidden/empty controls and use no ratio tolerance; this diagnoses the control, not the product layout.

Contract-Neutral: Integration geometry control only; production frontend, memory semantics, safety behaviour and dependency graphs are unchanged.
Change-source: pulse-maintainer
2026-10-13 16:54:02 +01:00
pulse-triage[bot] 94cdf4d1da Check clipping on the actual memory text ancestors
Include nested value spans in the unclipped-text proof, not just their enclosing cells. Add controls for an internally clipped value and a hidden child whose line boxes still exist; retain the viewport and navigation requirements.

Contract-Neutral: Integration geometry proof only; production frontend, memory semantics, safety behaviour and dependency graphs are unchanged.
Change-source: pulse-maintainer
2026-10-13 16:46:23 +01:00