Commit Graph

5769 Commits

Author SHA1 Message Date
pulse-triage[bot] ca255a0e3f Keep retained guest readings truthful in canonical History
Share the original memory observation policy with the dedicated guest drawer and carry filesystem deferrals through the existing History presentation. Preserve measured zero, stored samples, source and access isolation, and same-ID read budgets. Record fresh eight-state browser proof; native thaw and workload recovery remain independent.

Change-source: pulse-maintainer
2026-10-05 06:42:55 +01:00
pulse-triage[bot] ea99f6ef65 Incorporate supplied upstream frontier for diagnostic-test review
Retain the batch-start main frontier before integrating the independently reviewed documentation-test candidate. No publication or deployment.

Change-source: pulse-maintainer
2026-10-05 05:58:53 +01:00
rcourtman 94ac386abf Make availability checks agree across Settings and Machines (#2493)
Settings said "2 down" where Machines said "1 offline, 3 need
attention" for the same checks. Settings counted any failed latest
probe as down, while Machines and the alert engine count a check offline
only once it has failed its threshold number of times in a row.

Settings now classifies each check with the Machines status of its
resource when that is loaded, and otherwise reads the target the way the
availability poller does, so both pages report the same counts in the
same words. A check that is failing but not yet offline is amber, with
the threshold on hover.

The Machines table shows 24h uptime beside the latest result (it existed
only in the Fleet view), and only when most of the window had a
determinate answer, refreshing every five minutes. Failures read "3 in a
row" instead of "3/2", polling cadence moves to the widest tables, and
the duplicate Manage link is gone.
2026-10-05 05:51:46 +01:00
pulse-triage[bot] ecd693faf7 Integrate reviewed token-aware permission help and composed webhook proof
Change-source: pulse-maintainer
2026-10-05 05:36:35 +01:00
pulse-triage[bot] e4dde6563a Incorporate supplied upstream frontier for this candidate batch
Change-source: pulse-maintainer
2026-10-05 05:35:30 +01:00
rcourtman c4b3db4058 Show Mail Gateway alerts on the gateway they belong to (#2490)
A gateway Proxmox reported online could be failing its job: mail held
in the queue past the configured age. The Mail Gateway table ignored
alerts, so that gateway rendered green and counted as Healthy while the
problem sat only on the Alerts page. Alerts are keyed by the PMG
instance id and rows by the unified id, so nothing joined them.

Rows now match unacknowledged alerts across the gateway's identity
aliases. An alerted, reachable gateway reads and filters as needing
attention (red when an alert is critical) and names the alert type under
its name. Its expansion leads with the exact alert message. On phones,
six tracks truncated "mail-gateway-eu" and "mail-gateway-us" to the same
text; the node count moves into the expansion so names stay whole.
2026-10-05 05:32:49 +01:00
rcourtman 53029b08ea Make availability checks agree across Settings and Machines
Settings said "2 down" where Machines said "1 offline, 3 need
attention" for the same checks. Settings counted any failed latest
probe as down, while Machines and the alert engine count a check offline
only once it has failed its threshold number of times in a row.

Settings now classifies each check with the Machines status of its
resource when that is loaded, and otherwise reads the target the way the
availability poller does, so both pages report the same counts in the
same words. A check that is failing but not yet offline is amber, with
the threshold on hover.

The Machines table shows 24h uptime beside the latest result (it existed
only in the Fleet view), and only when most of the window had a
determinate answer, refreshing every five minutes. Failures read "3 in a
row" instead of "3/2", polling cadence moves to the widest tables, and
the duplicate Manage link is gone.
2026-10-05 05:31:04 +01:00
pulse-triage[bot] 221a86057e Integrate reviewed pass-local system grouping index
Preserve exact Core candidate ab15c4db8a and its two prerequisite commits. Retained connected proof and complete cost samples support allocation and scaling gains, not native CPU/RSS relief.

Change-source: pulse-maintainer
2026-10-05 05:21:49 +01:00
rcourtman 73c9e15491 Merge remote-tracking branch 'origin/main' into fix/mail-gateway-says-why 2026-10-05 05:08:03 +01:00
rcourtman b10b52021e Move the Mail Gateway drawer note into the drawer hierarchy clause
The note sat before the same frontend-primitives heading another lane used and conflicted with main. Taking main's file with the note folded into the existing object-drawer clause lets main merge cleanly.
2026-10-05 05:06:28 +01:00
pulse-triage[bot] e02f949b09 Preserve reviewed monitoring repairs with current upstream overviews
Compose exact upstream a82a8e0474 additively without changing accepted commits. Resolve the append-only registry-test conflict by retaining both the reviewed metadata invalidation control and upstream stale-health control. Existing PR2486 remains unchanged while normal source-check corrections are pending.

Change-source: pulse-maintainer
2026-10-05 05:05:48 +01:00
rcourtman 43c38253b6 Explain backup protection in plain words
The Coverage tooltip and expansion render the posture explanation
verbatim, and it read like the model: "a current subject-linked
backup", "older than the configured freshness window", "a newer
provider failure", "a stronger protection claim".

Each explanation now says what Pulse found in plain words and stays true
to its branch: the stale case names the window ("the newest confirmed
backup is older than 7 days"), the failure case no longer claims a
timing it cannot know, and partial history without a backup no longer
says a backup exists. The window formatter never rounds a sub-hour or
fractional window up. The frontend fallbacks for checking, unrated and
unknown rows and the snapshot-only tooltip use the same voice.
2026-10-05 05:03:08 +01:00
rcourtman a82a8e0474 Lead the Kubernetes overview with the nodes that are not Ready (#2489)
The Kubernetes overview said "2/3 nodes" in amber on the cluster row
but no surface on the page named the node, and active health signals
rendered at the bottom, after every healthy deployment, pod and
controller. On the Nodes tab a node's state was a hover title on a
dot that screen readers never heard.

Health signals and the nodes that are not Ready, cordoned or degraded
now lead the overview, each only while it has rows, using the existing
Kubernetes alerts and nodes tables. The full node inventory stays on
the Nodes tab, and the attention list keeps its own sort. The nodes
table names the state in a Status column beside the name, as kubectl
does, and announces it on phones where that column is demoted.
2026-10-05 04:40:56 +01:00
rcourtman 20eed2127b Show Mail Gateway alerts on the gateway they belong to
A gateway Proxmox reported online could be failing its job: mail held
in the queue past the configured age. The Mail Gateway table ignored
alerts, so that gateway rendered green and counted as Healthy while the
problem sat only on the Alerts page. Alerts are keyed by the PMG
instance id and rows by the unified id, so nothing joined them.

Rows now match unacknowledged alerts across the gateway's identity
aliases. An alerted, reachable gateway reads and filters as needing
attention (red when an alert is critical) and names the alert type under
its name. Its expansion leads with the exact alert message. On phones,
six tracks truncated "mail-gateway-eu" and "mail-gateway-us" to the same
text; the node count moves into the expansion so names stay whole.
2026-10-05 04:34:24 +01:00
rcourtman 6df55d0d01 Say when a Docker host goes silent, and stop repeating host columns (#2482)
A Docker host whose agent stopped reporting kept showing its last CPU,
memory and disk bars as if they were live, with only an orange dot to
hint otherwise. The tables now read the backend's telemetry_stale
reason: that host's metric cells are dimmed, Uptime shows how long it
has been silent, and its container group header says "No report for 1h".

Health could only carry that reason when nothing outranked it, so a
silent host with an offline alert lost the signal. The verdict still
leads with the alert, and a stale source now adds a trailing
telemetry_stale reason. The first reason, which the state summary
reports, is unchanged.

Grouped by host, the containers table also repeated the host name and
engine on every row, about a quarter of its width. Those columns are
dropped in grouped mode and the group header names the engine once;
flat mode keeps them, and a saved sort on either hidden column no longer
reorders grouped rows.

Verified in a browser on a mock estate at 1440 and 390 with the rebuilt
backend (receipt included). Go: internal/unifiedresources, internal/api
summary and internal/monitoring health tests pass; full frontend suite
passes apart from the known Mac-only agentInstallCommand cases.
2026-10-05 04:32:23 +01:00
pulse-triage[bot] ab15c4db8a Index only possible grouping owners and exercise real pass boundaries
Maximum-priority roots cannot be better than any group in a snapshot, so leave them out of the temporary owner indexes while retaining every resource and group. Correct new fixtures to respect existing attachment semantics: differently ranked hosts may already merge, and an agent's first-pass IP attachment must remain ambiguous until its two owners merge. Cover equal-priority Proxmox cost before any timing run.

Contract-Neutral: Candidate-only priority pruning and faithful regression fixtures preserve all stored/published resources, identity, strict attachment ambiguity, evidence precedence, public schemas and counted-system admission.
Change-source: pulse-maintainer
2026-10-05 04:29:10 +01:00
rcourtman b3fefdba2c Make Patrol and Actions views linkable (#2488)
Patrol's Inbox, Protection and Activity views and the Actions Open and
History views lived in component state. A bookmark, a shared link or a
reload always opened the default view, and back/forward did nothing.

Each view is now a route: /patrol, /patrol/protection,
/patrol/activity, /actions and /actions/history. Tabs navigate without
scrolling the page. Lifecycle-driven switches in Actions (a deep-linked
review whose action has settled) replace history instead of pushing.
The Patrol finding handoff scrolls to the findings once Activity has
mounted. The Inbox's ?attention= selection is read from the real address
when leaving the Inbox and restored on return, because the attention
workbench writes it straight to history and the router's copy can be
stale.
2026-10-05 04:26:54 +01:00
pulse-triage[bot] 5e967c49f5 Merge reviewed token-aware Proxmox permission help
Change-source: pulse-maintainer
2026-10-05 04:15:03 +01:00
pulse-triage[bot] b67a0ab573 Retain reviewed main work alongside upstream Notifications presentation
Change-source: pulse-maintainer
2026-10-05 04:14:38 +01:00
pulse-triage[bot] ff46264503 Reuse sorted owner buckets within each system-grouping pass
Build complete hostname/IP/form owner indexes once in priority order, visit only strictly better owners and reject once two distinct qualifying roots prove ambiguity. Preserve exact/short/IP evidence precedence, metadata freshness, exclusions and all resources. Bind the immediate-parent algorithm and enumerate targets independently; exercise real provider grouping and connected Infrastructure output.

Contract-Neutral: Pass-local representation and cost only; complete inventory, strict better-priority and ambiguity rules, evidence ordering, identity, public schemas, observations and alert policy are unchanged and covered by exhaustive and connected reference controls.
Change-source: pulse-maintainer
2026-10-05 04:14:27 +01:00
rcourtman 42ce399baf Lead the Kubernetes overview with the nodes that are not Ready
The Kubernetes overview said "2/3 nodes" in amber on the cluster row
but no surface on the page named the node, and active health signals
rendered at the bottom, after every healthy deployment, pod and
controller. On the Nodes tab a node's state was a hover title on a
dot that screen readers never heard.

Health signals and the nodes that are not Ready, cordoned or degraded
now lead the overview, each only while it has rows, using the existing
Kubernetes alerts and nodes tables. The full node inventory stays on
the Nodes tab, and the attention list keeps its own sort. The nodes
table names the state in a Status column beside the name, as kubectl
does, and announces it on phones where that column is demoted.
2026-10-05 04:11:16 +01:00
rcourtman 27f020f033 Lead Notifications with where alerts go (#2487)
A user opening Notifications wants to know where their alerts go and
how to send them to Discord, Telegram or email. The page opened on nine
"held, delivery not turned on" rows that repeated the paused banner,
then a fully expanded but disabled SMTP form and Apprise form, with
webhooks (where Discord, Telegram and ntfy live, and the destination
issues ask about most) near the bottom.

Unless delivery is degraded, destinations now lead: webhooks first,
described by the services they reach, then email and Apprise, then the
delivery log. A degraded queue still keeps its log directly under the
recovery controls. A switched-off email or Apprise destination is one
line saying what turning it on does, with "Show settings" to inspect the
form without enabling it. A new webhook opens on the service choice
instead of the generic JSON form, and setup steps keep their line
breaks.

Delivery health now sets its snapshot and availability in one batch.
Set separately, the attention flag briefly read a half-updated pair and
unmounted the warning mid-refresh.
2026-10-05 04:08:21 +01:00
pulse-triage[bot] 70c71ad5b8 Merge reviewed mutation-bound registry metadata materialization
Accept exact Core commits with connected suites, races, copying and freshness controls. Retain the cold List-only cost regression and native CPU/RSS limitations; this is not whole-estate relief.

Change-source: pulse-maintainer
2026-10-05 03:51:34 +01:00
pulse-triage[bot] 93e6dc670a Retain reviewed main work alongside initial upstream vSphere guidance
Incorporate the upstream frontier present at coordination start without rewriting reviewed candidate history.

Change-source: pulse-maintainer
2026-10-05 03:51:12 +01:00
rcourtman c2811cca6d Merge remote-tracking branch 'origin/main' into feat/docker-silent-hosts 2026-10-05 03:50:49 +01:00
rcourtman 55cd60ff85 Move this branch's unified-resources note off the end of the file
Every lane appends to the end of this contract, so a note there conflicts with each merge to main. Taking main's file with the note placed beside the Docker sections lets main merge cleanly now and later.
2026-10-05 03:49:14 +01:00
rcourtman 7a102fc57f Make Patrol and Actions views linkable
Patrol's Inbox, Protection and Activity views and the Actions Open and
History views lived in component state. A bookmark, a shared link or a
reload always opened the default view, and back/forward did nothing.

Each view is now a route: /patrol, /patrol/protection,
/patrol/activity, /actions and /actions/history. Tabs navigate without
scrolling the page. Lifecycle-driven switches in Actions (a deep-linked
review whose action has settled) replace history instead of pushing.
The Patrol finding handoff scrolls to the findings once Activity has
mounted. The Inbox's ?attention= selection is read from the real address
when leaving the Inbox and restored on return, because the attention
workbench writes it straight to history and the router's copy can be
stale.
2026-10-05 03:46:05 +01:00
pulse-triage[bot] 3c249ecacf Make Proxmox permission help token-aware and backup-safe
Remove the user placeholder command that Bash treats as file redirection. Diagnose the configured account and privilege-separated token on the affected scope without broader grants, token rotation or guest probes. Clarify that API-only guest reads still use the backup channel and preserve the monitoring-outage precaution in the existing help. Connected shipped-Markdown controls bind both entry points to the generated token/ACL contract.

Contract-Neutral: Existing help and regression controls only; no runtime, schema, collector, token, ACL, navigation or dependency contract change.
Change-source: pulse-maintainer
2026-10-05 03:43:34 +01:00
pulse-triage[bot] e99c31472e Merge reviewed passive temperature diagnostics
Retain exact candidate 4cb1c8a232 with bounded private readings, restricted SSH trust and non-clobbering cleanup guidance. Existing help only; exact-source installer, sensor and Docs proof retained.

Change-source: pulse-maintainer
2026-10-05 03:34:45 +01:00
rcourtman 76a1d8df49 Lead Notifications with where alerts go
A user opening Notifications wants to know where their alerts go and
how to send them to Discord, Telegram or email. The page opened on nine
"held, delivery not turned on" rows that repeated the paused banner,
then a fully expanded but disabled SMTP form and Apprise form, with
webhooks (where Discord, Telegram and ntfy live, and the destination
issues ask about most) near the bottom.

Unless delivery is degraded, destinations now lead: webhooks first,
described by the services they reach, then email and Apprise, then the
delivery log. A degraded queue still keeps its log directly under the
recovery controls. A switched-off email or Apprise destination is one
line saying what turning it on does, with "Show settings" to inspect the
form without enabling it. A new webhook opens on the service choice
instead of the generic JSON form, and setup steps keep their line
breaks.

Delivery health now sets its snapshot and availability in one batch.
Set separately, the attention flag briefly read a half-updated pair and
unmounted the warning mid-refresh.
2026-10-05 03:28:48 +01:00
pulse-triage[bot] bbe2649d91 Merge reviewed bounded passive VM diagnostics
Retain exact candidate 3a0a7f6302. Reviewed helper limits, corruption handling, private failures and mirrored guidance; retained exact-source controls and Docs build evidence cover the unchanged four-file content.

Change-source: pulse-maintainer
2026-10-05 03:25:35 +01:00
rcourtman b38289b838 Merge remote-tracking branch 'origin/main' into feat/docker-silent-hosts 2026-10-05 03:10:44 +01:00
rcourtman 5f183749cc Move this branch's frontend-primitives note off the end of the file
Every lane appends to the end of this contract, so a note there conflicts with each merge to main. Taking main's file with the note placed beside the platform-window section lets main merge cleanly now and later.
2026-10-05 03:09:10 +01:00
rcourtman 2ea6b8bb83 Merge remote-tracking branch 'origin/main' into feat/vsphere-overview-health 2026-10-05 03:08:20 +01:00
rcourtman 47598c0290 Move this branch's frontend-primitives note off the end of the file
Every lane appends to the end of this contract, so a note there conflicts with each merge to main. Taking main's file with the note placed beside the platform-page sections lets main merge cleanly now and later.
2026-10-05 03:06:45 +01:00
pulse-triage[bot] e3652756fc Retain reviewed monitoring repairs alongside upstream alert and backup guidance
Compose the exact current upstream head additively, preserving reviewed local ancestry and independently landed alert and backup presentation.

Change-source: pulse-maintainer
2026-10-05 03:05:13 +01:00
pulse-triage[bot] 4cb1c8a232 Make temperature diagnostics passive, bounded and private
Replace automatic hardware detection with existing-driver reads, keep SSH forced-key trust intact, and prevent incomplete legacy cleanup downloads from replacing a saved helper. Validate the copied commands against synthetic tools and HTTPS peers.

Contract-Neutral: Existing help and copied-command safety only; sensor collection, authentication, installer interfaces and runtime schemas are unchanged.
Change-source: pulse-maintainer
2026-10-05 03:00:54 +01:00
pulse-triage[bot] 51ef7eddda Derive canonical bulk-read metadata once per registry mutation
Keep full inventory and arbitrary clone refresh. Detach materialized identity and policy under the existing registry lock, invalidate between batch records and on stale-source transitions, and keep List-only reads independent of typed view construction. Compare every field and wire payload with an independent fresh-clone oracle across all demo providers.

Refs: #2199
Change-source: pulse-maintainer
Contract-Neutral: Registry-internal copying and invalidation repair existing freshness and ownership guarantees; canonical resource fields, wire schemas, identity rules, policy derivation, telemetry and alert evaluation are unchanged.
2026-10-05 02:59:48 +01:00
rcourtman 5b7a9df8ac Lead alert thresholds with each group's default limits (#2484)
The Thresholds page opened on a ten-select CPU evaluation grid, and
every resource group started collapsed showing only a name and a count,
so the limits that decide what alerts were invisible until a group was
opened one at a time.

Each collapsed group header now states its defaults ("CPU 80% · Memory
85% · Disk 90%"), built by one helper from the same columns and defaults
the group's table edits. It drops metrics the engine treats as off and
hides the line while the group is disabled. Rules whose zero means a
fallback are stated as whole rules with their effective values: Docker's
restart loop and memory-limit, and backup age by its alerting days
rather than the dashboard-only fresh/stale hours.

CPU averaging becomes one collapsed line stating the effective window
and how many profile overrides exist, with the same selects inside.
Docker and Machines list their groups before Docker-only rules and the
SMART card.
2026-10-05 02:57:28 +01:00
rcourtman dc0691ab69 Restore the platform staleness contract note
Re-adds this branch's frontend-primitives note after taking main's file for a clean merge.
2026-10-05 02:49:42 +01:00
rcourtman 384bfacdfe Merge remote-tracking branch 'origin/main' into feat/docker-silent-hosts 2026-10-05 02:49:42 +01:00
rcourtman 698593426b Take main's frontend-primitives contract ahead of the merge
Main appended frontend-primitives notes at the same place this branch did. Taking main's file here lets main merge cleanly. The staleness note is restored right after the merge.
2026-10-05 02:48:07 +01:00
rcourtman 3cd0e7e0eb Restore the vSphere overview incident-table contract note
Re-adds this branch's frontend-primitives note after taking main's file for a clean merge.
2026-10-05 02:45:06 +01:00
rcourtman 2819b2caeb Merge remote-tracking branch 'origin/main' into feat/vsphere-overview-health 2026-10-05 02:45:05 +01:00
rcourtman 3998582278 Take main's frontend-primitives contract ahead of the merge
Main appended frontend-primitives notes at the same place this branch did. Taking main's file here lets main merge cleanly. The vSphere note is restored right after the merge.
2026-10-05 02:45:05 +01:00
pulse-triage[bot] 3a0a7f6302 Fail closed on oversized or corrupt passive VM reads
Bound the existing passive preflight before Bash can discard NULs or accept unlimited configuration output. Preserve producer errors independently, isolate the byte reader from Python startup hooks, and keep the copied helper and mirrored help private and off the guest-agent channel.

Contract-Neutral: Operator diagnostics and existing help only; Proxmox polling, guest-agent coordination, APIs, storage and service behaviour are unchanged.
Change-source: pulse-maintainer
2026-10-05 02:44:26 +01:00
pulse-triage[bot] 630ace5654 Merge reviewed private bounded API guidance
Integrate exact candidate aece6b5217. Retained installer/vet and scoped Docs receipts cover the unchanged documentation recipes and tests; no runtime or product-surface change.

Change-source: pulse-maintainer
2026-10-05 02:39:30 +01:00
rcourtman 0f66f5c136 Lead alert thresholds with each group's default limits
The Thresholds page opened on a ten-select CPU evaluation grid, and
every resource group started collapsed showing only a name and a count,
so the limits that decide what alerts were invisible until a group was
opened one at a time.

Each collapsed group header now states its defaults ("CPU 80% · Memory
85% · Disk 90%"), built by one helper from the same columns and defaults
the group's table edits. It drops metrics the engine treats as off and
hides the line while the group is disabled. Rules whose zero means a
fallback are stated as whole rules with their effective values: Docker's
restart loop and memory-limit, and backup age by its alerting days
rather than the dashboard-only fresh/stale hours.

CPU averaging becomes one collapsed line stating the effective window
and how many profile overrides exist, with the same selects inside.
Docker and Machines list their groups before Docker-only rules and the
SMART card.
2026-10-05 02:34:42 +01:00
pulse-triage[bot] 7331f3579d Merge reviewed scoped agent identity lookups
Preserve exact Core candidate history and complete published monitoring inventory while removing unrelated temporary metadata copies.

Change-source: pulse-maintainer
2026-10-05 02:32:33 +01:00
rcourtman 4c266391c3 Say what backup health counts mean and drop per-source age columns
"17 attention / 10 unprotected" were counts without a rule, and users
have asked what Pulse treats as stale. The Backup health strip now
carries one line built from the server's posture policy window that
names the causes internal/recovery/posture.go evaluates for attention,
unprotected and unknown. Nothing renders until the policy loads, so the
page never shows a guessed window.

The coverage table showed up to four time columns (last backup, PBS
snapshot, PVE file, guest snapshot). A fresh green guest snapshot beside
an amber stale backup read as protection that posture does not grant.
Rows now carry the one counted backup age. The row expansion keeps the
newest point and the newest completed point of every source in its
bounded evidence list, so neither a run of snapshots nor a running or
failed job can hide the latest usable backup.
2026-10-05 02:12:17 +01:00