Commit Graph

12506 Commits

Author SHA1 Message Date
pulse-triage[bot] d79f7e545b Pin bulk registry metadata freshness and allocation ownership
Retain the pre-change fresh-clone oracle for every derived field, incremental ingestion and detached reads. Expose repeated canonical derivation in a 1000-resource bulk read before altering production code.

Refs: #2199

Contract-Neutral: Add independent regression controls and paired measurements; runtime and public contracts are unchanged.
Change-source: pulse-maintainer
2026-10-05 02:50:40 +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
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
pulse-triage[bot] 8c85a176db Retain independently landed guest monitoring batch in canonical history
Compose the exact upstream merge of PR2472 additively after bounded refresh ceaba22d265cc28a2998eb211569e0b3549f1e6955d927d47f4804d29188cd95. Preserve all reviewed newer PBS and fractional-CPU work for the next publication batch.

Change-source: pulse-maintainer
2026-10-05 02:11:25 +01:00
pulse-triage[bot] 1d4c3aeb6e Keep deferred guest readings, alerts and History truthful (#2472)
## What changes and why
Keep guest monitoring truthful while reads are deferred: retained
memory/filesystem values must not become new alert decisions, new
History observations, current filesystem health, or continuous chart
lines across missing readings. Failed or empty metadata refreshes retain
the last useful observation time rather than manufacturing freshness.
Independent current readings and measured-zero recovery keep their
existing behaviour.

Manual guest Discovery pauses during the existing backup/read
precaution, preserves saved evidence, and keeps delayed outcomes
attached to their original guest and run. The published drawer-header
link to a saved web interface remains available separately from live
Discovery. The existing TrueNAS guide and shipped copy keep credentials
and responses private and bound individual requests.

The guest work follows the prolonged freeze reported in #2439 and
reproduced downstream observation/lifecycle gaps. It does not identify
the freeze's cause or prove native recovery. The guidance repair follows
inspection of unsafe existing recipes. No new collector, schema,
retention policy, threshold or product surface is introduced by this
batch.

## Included source and reconciliation
Current published base `efe6fc21ae10a6bf173cc17e6203aaf6c97dc130` →
proposed head `1914f5fb7b278b5fc4cc10a292e909a10714a2f8` (39 introduced
commits, including additive integrations).

- TrueNAS guidance: `cadfd1f4e1d9f909a45977f94aadd4f1324e82ef` →
`d589407a743a12fe492e93785d9e24c12bbb4fb5`.
- Discovery pause/outcome ownership:
`2cb3f6a9043e0bab9c54c5b5ef57b3e1cb994781` →
`bbaee0a3f43dc7906011be5c78d684f9a1327bae`, including additive recovery
and lifecycle controls.
- Alert admission: `b0f8b96c8a159ac242b85f2d09f8dfffd5c29c7a` →
`0fd7768e9d1379f8aa0126b33d4047b4c52c0d87`.
- History writer admission: `a15920eaebea00ab8c353ddd3861b9cd7ff7d379`.
- Filesystem presentation: `2525d76c04a9834c2130e97c1a529e164a9c7796` →
`5b75f21159fda3c01fbe6688aa9cfde68779fba8`.
- Metadata freshness: `f1e221a0fb9b0804f200c13490f8526424cb7e1c`.
- Missing-observation chart presentation:
`0ad41e4c9a309ce459dd717d16d343b46efcac8a` →
`5e7e49650fcdf5131b7c5006fe487336ab660e15`.
- Platform-aware Discovery fixture:
`a2608c9fadf76c242527a636ee08968fa16ddde8`; TrueNAS recipe
reconciliation `1f0d12af85ec7c2ad8df391b8e6958e80fa98179`; additive
upstream/header composition and content-bound browser receipts through
`b01dad904c3436e70bc01588ea1546fffaa05dc6`; batch-start upstream merge
`f1c7e413bac2e3306d2169bcd069c60325e56d5f`, then exact bounded
refreshed-upstream merges `07112b0e3ab2be174a5ac7a11f87ac0837edceb0` and
`1914f5fb7b278b5fc4cc10a292e909a10714a2f8`.

The previous proposal head `6a20d106242598bd6b466e9ae888ea931d284b30` is
completed-failed, not still validating. Native run `37239183481`
incorrectly required a Linux/PVE capability on Windows/macOS; Build and
Test `37239183545` extracted zero wrapped TrueNAS recipes. Reviewed
additive fixtures correct both without weakening runtime safety. The old
head cannot land independently, so this update includes those
corrections and the coherent observation batch. Every accepted commit
identity and all ancestry are retained. Published cluster labels, saved
guest links, unique demo workload names the newer storage priority/alert
explanations, and the published Alerts overview are preserved. Bounded
refresh receipt
`2916978f4e4b49d084752e973e19a5c0f7dd19f0bf4ac60cc31875876318528d`
completed at the exact observed upstream without changing source; the
subsequent full-SHA merge composes it additively. A second successful
bounded refresh
`59f1939979347921d99e262398d5347077bfce6faf6f42535050840a3a19820b`
incorporates the subsequently published Alerts overview in the same way.
Neither is a replay of a failed or uncertain attempt.

## Validation and remaining gates
Retained evidence includes connected alert/API/producer/recovery
controls (`source-p58_phvc`), Discovery/component/build/browser checks
(`source-gy5x8buj`), installer/docs controls (`source-7s0iorys`,
`source-uo6rxs61`), metadata connected/race/vet/build proof
(`source-ji23nb_c`), and ten connected suites plus focused safety
races/vet and native-target compilation (`source-seboen4h`). Browser
content receipts cover the final seven changed frontend runtime files,
including the composed saved-link/safety header and chart gaps.

The History presentation proof `source-ualisb1k` completed 22,571
frontend tests across 1,234 files, types/lint/format/build and
bundle/integrity checks; its overall exit 1 from trailing nonexistent
optional test paths remains recorded, not converted into a whole-command
pass. Four browser groups/32 checks and eight inspected captures
separately passed. Earlier reproductions, fixture failures and
reporting-limit failures remain evidence.

Publication-gate checks:
- `source-qt6m6mf_`: seven connected TrueNAS recipe controls, full mock
suite, scoped real agent/guest safety, alert observation and
metadata/History tests pass. Backend/docs source is byte-identical in
the final composition; this evidence was not repeated after
frontend-only upstream advances.
- `source-xy1lnmgt`: types pass and 281 of 283 scoped frontend controls
pass; two first-case History tests hit the unchanged 5,000ms timeout.
Exit 1 is retained and the following build did not run. No functional
assertion failure or cause was established.
- One predeclared single-worker/file-serial comparison,
`source-17bch24o`, passes all 23 controls in those two files with
unchanged source, assertions and timeouts. This establishes isolated
functional behaviour, not a diagnosis or clearance of parallel CI.
- `source-dvlfnm5t`: refreshed storage composition passes types, 1,177
tests/56 files and the real production/embed build. The event-parser
line-bound flag is recorded; the complete 26,474 raw bytes independently
match the receipt.
- Final exact-head `source-sjjtzjqm`: types, scoped published Alerts
overview/translation/presentation controls and the real production/embed
build pass. Complete raw output is independently hash-matched and the
guest stopped.
- All executed receipts, including the failed scoped run, retain
complete output and completed guest stop. Provenance, clean source,
diff/ancestry checks, all 24 introduced non-merge commits' parent-bound
canonical guards using only their original recorded trailers, and the
final seven-file browser-content receipt guard pass.

Required exact-head administrative source review and GitHub checks must
complete before landing; this update is not a blind failed-job retry or
a CI waiver. Native overlap, independent thaw, fresh writes on every
covered filesystem, workload liveness, truthful alert delivery and safe
restoration of only prior-active services/timers remain separate. UI
clearance, saved values, an OK backup or these source tests are not
recovery, a containing release or installed/reporter acceptance.

Related to #2439


[How Pulse handles
triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
2026-10-05 01:09:46 +00:00
pulse-triage[bot] 1fbea3dd33 Preserve upstream workload editing alongside reviewed monitoring repairs
Add the published bulk web-link editor and alerting guest Attention count without changing the checking PR2472 head or any accepted commit. The newer local range remains for the next batch.

Change-source: pulse-maintainer
2026-10-05 02:05:08 +01:00
rcourtman a36f643510 Count alerting guests under Attention on the Proxmox overview (#2480)
The guest status chips put a running guest with an open warning or
critical alert under Running, because the Attention bucket looked only
at resource status and failed availability probes. With seven running
guests over a memory threshold the chips still read "Attention 0". The
bucket now also takes running guests whose canonical health names an
open alert. Backup age stays out: it has its own column and tab.

Two smaller fixes on the same page. The nodes table repeated one cluster
name in a Cluster column on every row; with a single cluster the column
is dropped and the header names the cluster, also while searching. The
VM disk "Unavailable" label was amber for every reason, mostly a missing
guest agent or a stopped VM, and its explanation was screen-reader only;
it is now muted unless the read is genuinely broken, with the reason on
hover.

Verified in a browser on a mock estate (receipt included); full frontend
suite passes apart from the known Mac-only agentInstallCommand cases.
2026-10-05 01:55:49 +01:00
pulse-triage[bot] aece6b5217 Keep copied API requests private, bounded and one-shot
Save every existing reference response privately, including errors and partial POST results. Preserve private header files, reject unsafe preparation and URLs, and stop on redirects or transport errors without retries. Exercise all eight copied GET/POST examples against real synthetic HTTP/TLS peers, including the old response exposure.

Contract-Neutral: Harden existing API documentation recipes and their shipped mirror with connected tests; no runtime, endpoint, authentication, scope, action, dependency or permission contract changes.
Change-source: pulse-maintainer
2026-10-05 01:52:58 +01:00
rcourtman aed2f6c17d Add a bulk web-link editor to the workloads table (#2477)
Saved web-interface links make Pulse a quick way to reach the service a
guest runs, but each link had to be typed into one guest drawer at a
time. This adds one place to set many at once. It ships as a named bet
with no external ask behind it yet.

**What users get**
- An **Edit links** action in the workloads table header. It appears on
the Proxmox and vSphere guest tables, which share that surface.
- A panel listing every guest in the current filtered view (node
selection and filters carry over). Each row shows the guest's type, ID,
node, its saved link, and an IP-based placeholder.
- An **All / Without a link** filter, a count of guests that have a
link, and one Save for every change. Clearing a field removes that link.
- Invalid links block the save with the shared validator's message on
their row. A failed save stays on its row. Closing the panel keeps
unsaved drafts, and the trigger shows "(unsaved)".
- Read-only sessions do not see the action.

**How it fits**
- Saves go through the existing guest metadata API and metadata-changed
event, the same path as the drawer field, so the table updates at once.
- `getWorkloadGuestMetadataRecord` is now the single lookup for a row's
saved link, in both the table and the editor.
- Editor rows only follow live inventory while the panel is open, and
they keep unchanged row objects across ticks. A closed editor adds no
per-tick work, and an open one never remounts the input being typed in.
`WorkloadsSurface.performance.contract.test.tsx` pins this.

**Verification**
- Private mock stack at 1280, 1024 and 375px, covering node scope,
filters, invalid entry, add, correct, remove, and close and reopen.
Receipt: `frontend-modern/browser-verification/743cc04a20d534ac.json`.
- 13 new tests in `workloadWebLinksModel.test.ts` and
`WorkloadWebLinksDialog.test.tsx`.
- Full frontend lint, plus `src/features`, `src/hooks`, `src/__tests__`,
`src/components/shared`, `src/components/Workloads` and
`src/components/Storage`: 515 files and 8,675 tests pass.
2026-10-05 01:48:48 +01:00
pulse-triage[bot] 36fc9fbf89 Make agent copy-ownership expectations independent
Freeze the source expectation as serialized bytes before mutating returned records. A broken clone cannot change both the tested state and its reference, so module, update and applied-config alias regressions must be detected.

Change-source: pulse-maintainer
2026-10-05 01:45:52 +01:00
pulse-triage[bot] 50b6df0f1b Integrate reviewed fractional container CPU presentation
Accept exact Web candidate 902bba393f with retained connected/static/build and parent-bound browser proof. Keep raw metrics, sorting and alerts unchanged; source acceptance is not native or reporter resolution.

Change-source: pulse-maintainer
2026-10-05 01:43:13 +01:00
pulse-triage[bot] aa0ce19555 Integrate recorded upstream quiet older-agent notice
Preserve the batch-start published frontier alongside local reviewed integrations; leave any later reconciliation to the publication gate.

Change-source: pulse-maintainer
2026-10-05 01:43:05 +01:00
rcourtman 7097a83099 Turn the older-agent notice into one quiet line (#2479)
Every Proxmox, Docker, Kubernetes, TrueNAS, vSphere and Machines tab
opened with a three-line amber warning about hosts on an older Pulse
agent, listing names and a Show all button above the monitoring data.
An outdated agent is maintenance, not an incident, and the warning
competed with real problems for attention on every visit.

The notice is now one sentence in the info tone with the upgrade link
inline. The affected names sit behind a "Which hosts?" toggle, so every
name is still one click away and the inventory starts higher on the
page.

Verified in a browser at 1440 and 390 (receipt included); full frontend
suite passes apart from the known Mac-only agentInstallCommand cases.
2026-10-05 01:39:03 +01:00
pulse-triage[bot] e2241074f8 Merge reviewed PBS private diagnostic guidance
Accept the exact two-commit product-intelligence candidate with retained copied-command and Docs proof; browser rendering remains unverified.

Change-source: pulse-maintainer
2026-10-05 01:36:34 +01:00
pulse-triage[bot] 39906a220a Compare agent lookup evidence independently of registry build time
The unchanged-parent allocation controls fail as intended. Its semantic oracle also compared separate wall-clock registry construction timestamps. Retain all source timestamps and canonical payloads while excluding only Resource.UpdatedAt from the full-reference comparison.

Change-source: pulse-maintainer
2026-10-05 01:22:51 +01:00
pulse-triage[bot] 1914f5fb7b Preserve published Alerts overview alongside reviewed guest safety repairs
Compose the second successfully observed upstream advance additively, preserving reviewed ancestry and the existing alert observation contracts.

Change-source: pulse-maintainer
2026-10-05 01:21:18 +01:00
pulse-triage[bot] 187e5daaa8 Keep agent identity lookups scoped to relevant inventory
Avoid cloning and ingesting twenty known non-host Kubernetes metadata kinds in temporary per-report matching registries, while preserving all publication and canonical matching. Clone only the selected native record for exact host reads and detach mutable host update, module and config state. Pin reference equivalence, live report publication, ownership and allocation scaling with connected controls.

Change-source: pulse-maintainer
2026-10-05 01:17:08 +01:00
rcourtman e25a5653c3 Count alerting guests under Attention on the Proxmox overview
The guest status chips put a running guest with an open warning or
critical alert under Running, because the Attention bucket looked only
at resource status and failed availability probes. With seven running
guests over a memory threshold the chips still read "Attention 0". The
bucket now also takes running guests whose canonical health names an
open alert. Backup age stays out: it has its own column and tab.

Two smaller fixes on the same page. The nodes table repeated one cluster
name in a Cluster column on every row; with a single cluster the column
is dropped and the header names the cluster, also while searching. The
VM disk "Unavailable" label was amber for every reason, mostly a missing
guest agent or a stopped VM, and its explanation was screen-reader only;
it is now muted unless the read is genuinely broken, with the reason on
hover.

Contract-Neutral: Workload status bucket and disk label read existing health and disk-read fields; no performance-path change, so performance-and-scalability.md is unaffected.
2026-10-05 01:16:52 +01:00
rcourtman efe6fc21ae Make the Alerts overview answer what is broken first (#2476)
The overview is where a notification lands, but each active alert was a
tall tinted card with five buttons, every card repeated "Notification
delivery not turned on", and a three-row stats table sat above the list,
so three alerts fit on a 1440x900 screen and about one on a phone.

When delivery is off the overview now says so once, with the shared
paused-delivery banner (overview wording, a link to set up destinations,
Turn on delivery), and rows drop the per-alert line for those global
holds. Alert-specific holds such as cooldown or quiet hours still show.
Rows are compact: severity on a left edge, a locale-aware start age on
the overview's minute clock, Acknowledge, Snooze and Investigate
visible,
and Timeline and monitoring policy behind a More disclosure. A summary
line counts open alerts by severity beside the heading; the override
count, which is configuration, leaves the overview.

The banner copy now comes from the en/de/es catalogs, and with alerts
switched off it no longer claims Pulse is still detecting them (the
destinations tab said the same). The banner title was near invisible
(text-amber-900/25) and is readable again.

Verified in a browser on a mock estate (19 active alerts, delivery not
activated) at 1440x900 and 390x844 dark, in English and German;
More/Timeline/Less exercised. Five alerts now fit above the fold at
1440x900, up from three. Ledger: rcourtman/pulse-pro
FEATURE_REQUESTS.md, Answer-first presentation across platform pages.
2026-10-05 01:16:14 +01:00
pulse-triage[bot] 902bba393f Complete the fractional CPU test resource identity
Supply the required displayName in the new connected row/drawer fixture after exact-source TypeScript validation caught the omission. This changes only test data; production content and its parent-bound browser receipt remain unchanged.

Change-source: pulse-maintainer
2026-10-05 01:14:25 +01:00
rcourtman 4a215d4029 Load the bulk web-link panel on first open
The editor pushed the WorkloadsSurface chunk to 71.44 kB gzip, past
its 70.23 kB budget. Main already sat at 68.80 kB, so loading every
row of a panel most sessions never open was the wrong cost to put on
the table.

The table-header trigger now keeps only the open flag and unsaved
drafts and lazy-loads the panel, whose state and row model live in a
separate 3.9 kB chunk. The table's saved-link lookup moves to its own
small module so the table does not pull the editor's model back in.
WorkloadsSurface builds at 69.13 kB. Drafts still survive closing the
panel, and typing a link back to its saved value no longer counts as an
unsaved change.
2026-10-05 01:14:16 +01:00
pulse-triage[bot] 07112b0e3a Compose published storage presentation with reviewed guest observation repairs
Incorporate the exact bounded refreshed upstream while preserving the complete reviewed batch and original source identities.

Change-source: pulse-maintainer
2026-10-05 01:12:45 +01:00
pulse-triage[bot] bedb245c72 Reproduce fleet-sized work in agent identity lookups
Compare complete canonical host views with a full-snapshot reference and pin current replacement. Measure unrelated Kubernetes metadata and peer-host allocation growth before repairing report lookups.

Change-source: pulse-maintainer
2026-10-05 01:08:54 +01:00
rcourtman f47e88e75b Lead the storage table with what is filling up, and say why (#2478)
The storage table's default priority order compared only the incident
priority, which is zero for almost every record, then broke ties by name
with the sort direction applied, so the default view was reverse
alphabetical: an 89%-full pool sat second and an 85% one twelfth. Rows
with an open alert were tinted with no reason, while the alert engine
already knew "projected to fill in about 4 days" or "over the 85%
limit".

The default order now puts open alerts first by severity, then the
record's incident priority, then usage, with ties reading A to Z under
every sort key. A highlighted row says why in its State cell: "Full in
~3
days" from the forecast alert's metadata, "Over 85% usage limit" for a
threshold alert, otherwise the alert text, in a compact form on phones.

A Ceph pool folded into the storage that mounts it used to drop its
alerts with it, so the surviving row lost the highlight. Consolidation
now carries the folded pools' alert identities onto that row.

Verified in a browser on a mock estate at 1440x900 and 390x844 (receipt
included). Ledger: rcourtman/pulse-pro FEATURE_REQUESTS.md, Answer-first
presentation across platform pages.
2026-10-05 01:08:15 +01:00
pulse-triage[bot] f1c7e413ba Integrate published demo workload names into reviewed guest safety batch
Preserve every accepted commit and compose the exact current published frontier before publication.

Change-source: pulse-maintainer
2026-10-05 01:04:27 +01:00
rcourtman fc737b2355 Turn the older-agent notice into one quiet line
Every Proxmox, Docker, Kubernetes, TrueNAS, vSphere and Machines tab
opened with a three-line amber warning about hosts on an older Pulse
agent, listing names and a Show all button above the monitoring data.
An outdated agent is maintenance, not an incident, and the warning
competed with real problems for attention on every visit.

The notice is now one sentence in the info tone with the upgrade link
inline. The affected names sit behind a "Which hosts?" toggle, so every
name is still one click away and the inventory starts higher on the
page.
2026-10-05 01:02:30 +01:00
pulse-triage[bot] 7f95e40259 Keep fractional container CPU labels truthful
Distinguish small positive CPU and History percentages from actual zero, and explain the existing host-capacity scale in container tables and drawers. Preserve raw values, sorting, collection and alert thresholds; cover desktop and phone rendering with a parent-bound browser receipt and connected tests.

Change-source: pulse-maintainer
2026-10-05 00:58:56 +01:00
rcourtman ab59317358 Point two alert overview source guards at the new layout
The overview change moved the summary line into the active-alerts
section, dropped the override count and gave alert cards a neutral
background with a severity edge. Two guard and coverage tests still
pinned the old stats table placement, the override field and the tinted
card classes, so the Frontend check failed on the pull request.
2026-10-05 00:52:24 +01:00
rcourtman 15ffd92e43 Lead the storage table with what is filling up, and say why
The storage table's default priority order compared only the incident
priority, which is zero for almost every record, then broke ties by name
with the sort direction applied, so the default view was reverse
alphabetical: an 89%-full pool sat second and an 85% one twelfth. Rows
with an open alert were tinted with no reason, while the alert engine
already knew "projected to fill in about 4 days" or "over the 85% limit".

The default order now puts open alerts first by severity, then the
record's incident priority, then usage, with ties reading A to Z under
every sort key. A highlighted row says why in its State cell: "Full in ~3
days" from the forecast alert's metadata, "Over 85% usage limit" for a
threshold alert, otherwise the alert text, in a compact form on phones.

A Ceph pool folded into the storage that mounts it used to drop its
alerts with it, so the surviving row lost the highlight. Consolidation
now carries the folded pools' alert identities onto that row.
2026-10-05 00:45:19 +01:00
pulse-triage[bot] 50941e431a Compile the copied PBS request controls against addressable recipes
Retain the guide recipe array before selecting its request slice; the initial exact-source proof rejected a temporary array slice before running any tests.

Contract-Neutral: Correct test compilation only; existing PBS documentation and runtime contracts are unchanged.
Change-source: pulse-maintainer
2026-10-05 00:45:13 +01:00
pulse-triage[bot] bcbf7f0992 Keep PBS credentials, diagnostics and installer preparation private
Fail closed before editing unsafe credential paths, ignore curl configuration and retain diagnostic responses privately. Bound requests, reject redirects and publish the local installer path only after a complete HTTPS 200 download without overwriting existing files. Exercise the copied recipes against synthetic TLS peers and file failures.

Contract-Neutral: Harden existing PBS documentation recipes and their shipped mirror; no runtime, API, permission, installation contract or dependency change.
Change-source: pulse-maintainer
2026-10-05 00:41:26 +01:00
rcourtman 967e51701e Add a bulk web-link editor to the workloads table
Saved web-interface links make Pulse a quick way to reach the service
a guest runs, but each link had to be typed into one guest drawer at a
time. Richard asked for a faster way to set them up; it ships as a
named bet with no external ask behind it yet.

An Edit links action in the workloads table header opens one panel
listing every guest in the current filtered view with its saved link.
Links save in one pass through the existing guest metadata API and
metadata-changed event, so the table updates at once. Invalid links
block the save with the shared validator's message on their row, a
failed save stays on its row, and closing the panel keeps unsaved
drafts. Read-only sessions do not see the action.

The table and the editor now share one lookup for a row's saved link.
Editor rows only follow live inventory while the panel is open, so a
closed editor adds nothing to the per-tick workload path.
2026-10-05 00:36:42 +01:00
pulse-triage[bot] b01dad904c Merge reviewed missing-observation drawer History presentation
Preserve exact Web candidate and retained browser content receipts alongside the canonical frontier.

Change-source: pulse-maintainer
2026-10-05 00:28:08 +01:00
pulse-triage[bot] 8ccb82a7f9 Merge reviewed platform-aware guest Discovery verification
Resolve the prior non-Linux skip in favor of the exact reviewed real-registration refusal fixture. Preserve candidate a2608c9 and runtime safety contracts.

Change-source: pulse-maintainer
2026-10-05 00:28:07 +01:00
rcourtman 53e2d27ab4 Stop repeating Kubernetes workload names in the demo (#2475)
The demo scenario renamed every generated deployment to one of four
curated names and every pod to one of ten, cycling by index. With the
default 14 deployments and 40 pods per cluster the Kubernetes overview
listed checkout-api four times in one namespace, and the curated
pending and crash-looping pods appeared more than once. Kubernetes
itself refuses duplicate names in a namespace, so the public demo
looked broken.

Ten more healthy services fill out the default deployment count, a
numeric suffix keeps any larger count unique, and pods past the curated
story become healthy ReplicaSet-style replicas of the cluster's own
deployments on ready nodes, so each curated failure appears once.

Checked on a mock stack: the Kubernetes overview lists 14 distinct
deployments and every pod name once, with the curated pending pod shown
once. The new test covers the default, 30/60, 0/40 and 15/631 shapes, a
single crash loop across the estate, healthy repeats, ready-node
placement and name stability across a metric refresh.
2026-10-05 00:28:00 +01:00
rcourtman ddd6ba04c6 Make the Alerts overview answer what is broken first
The overview is where a notification lands, but each active alert was a
tall tinted card with five buttons, every card repeated "Notification
delivery not turned on", and a three-row stats table sat above the list,
so three alerts fit on a 1440x900 screen and about one on a phone.

When delivery is off the overview now says so once, with the shared
paused-delivery banner (overview wording, a link to set up destinations,
Turn on delivery), and rows drop the per-alert line for those global
holds. Alert-specific holds such as cooldown or quiet hours still show.
Rows are compact: severity on a left edge, a locale-aware start age on
the overview's minute clock, Acknowledge, Snooze and Investigate visible,
and Timeline and monitoring policy behind a More disclosure. A summary
line counts open alerts by severity beside the heading; the override
count, which is configuration, leaves the overview.

The banner copy now comes from the en/de/es catalogs, and with alerts
switched off it no longer claims Pulse is still detecting them (the
destinations tab said the same). The banner title was near invisible
(text-amber-900/25) and is readable again.
2026-10-05 00:22:22 +01:00
pulse-triage[bot] 7b2a9c322e Prune the superseded incorrectly named publication receipt
The correctly fingerprinted receipt already preserves the exact browser evidence. Remove only the new invalid duplicate in a separate additive pruning commit; preserve all reviewed history and production source.

Change-source: pulse-maintainer
2026-10-05 00:20:24 +01:00
pulse-triage[bot] deac1ca8e3 Bind composed drawer evidence to its content fingerprint
Correct the new publication receipt filename and immediate parent binding without rerunning or changing its verified production bytes. The initial invalid receipt remains historical evidence, not coverage.

Change-source: pulse-maintainer
2026-10-05 00:20:19 +01:00
pulse-triage[bot] 482a2614e3 Record browser proof for composed guest drawer safety and saved link
Verify exact combined production drawer after additive published upstream integration: Chromium desktop and WebKit phone keep saved service access distinct from backup/read precautions and explicit Discovery admission. Eight inspected captures and synthetic safe/absent/unsafe URL controls; no native guest or service operation.

Change-source: pulse-maintainer
2026-10-05 00:19:18 +01:00
pulse-triage[bot] 70493f5e1c Compose the published guest drawer link with reviewed safety controls
Preserve exact upstream drawer-header Open action and every reviewed guest-observation commit. The existing Discovery precaution remains separate from the saved service link.

Change-source: pulse-maintainer
2026-10-05 00:14:56 +01:00
rcourtman 4488a42bcc Open a guest's saved web interface from its drawer header (#2474)
Phone and narrow workload rows hide the adjacent web link so guest names
stay distinguishable. On a phone that left a saved service reachable
only from the URL field on the drawer's Manage tab, three taps deep and
behind a settings form.

The guest drawer header now carries an Open action whenever a URL is
saved. It is built from the shared `WebInterfaceLink` and the
drawer-header action class, so the service is one tap from the expanded
row with a 44px phone target (32px from the `sm` breakpoint up). Rows
are unchanged: showing the row link at 393px truncated names until
`checkout-web-01` and `checkout-web-02` read the same.

- Renders only for a saved URL. Unsafe or malformed values show the
existing warning, never a link.
- Opening it does not collapse the drawer.
- Adds no fetch, polling or per-row work.

Verified on a private mock stack at 375, 393 and 1280px widths (receipt
`frontend-modern/browser-verification/758aa0a8df357dc4.json`).
`GuestDrawer.test.tsx` covers target and rel, the no-URL and whitespace
cases, the unsafe-URL warning, and that the drawer stays open.

Refs #1556.
2026-10-05 00:10:23 +01:00
pulse-triage[bot] 1f0d12af85 Match safety fixtures to private responses and native platforms
PR2472 build run 37239183545 extracts no wrapped TrueNAS recipes; exercise all three current blocks and retain synthetic HTTP response bodies only in private files, including 201 save and error controls. Native run 37239183481 expects a Linux QGA capability on macOS and Windows; assert non-Linux agents do not advertise it and scope the connected PVE fixture to its actual Linux runtime. Production safety and documentation remain unchanged.

Contract-Neutral: Test-only reconciliation of already-reviewed private-response recipes and existing Linux-only guest-execution capability; no product contract change.
Change-source: pulse-maintainer
2026-10-05 00:08:47 +01:00
pulse-triage[bot] 4e81b4b2c5 Integrate published workload cluster labels without rewriting guest repairs
Preserve reviewed guest-observation ancestry and the human-authored vSphere label repair at the exact upstream frontier.

Change-source: pulse-maintainer
2026-10-05 00:07:43 +01:00
rcourtman e6167ef616 Label vSphere host groups with their cluster, not a VM (#2473)
On the vSphere overview every ESXi host group header carried a chip
naming the host's first VM (esxi-01.lab.local [etl-batch-01]) where the
cluster belongs. The workload adapter took the cluster from
getPreferredResourceClusterName, which falls back to the resource's own
name. That fallback suits a cluster resource, but a vSphere VM keeps its
cluster in vmware.clusterName, which the helper never reads, so the VM
became its own cluster. Standalone Proxmox guests had the same problem
in their context label.

Workloads now take the cluster only from an explicit source: the vSphere
facet, then the existing explicit helper. The grouping instance keeps
its old fallback chain, so group keys do not move.

Verified in a browser on a mock estate at 1440 and 390 widths; receipt
included.
2026-10-05 00:03:01 +01:00
rcourtman b8554bdd78 Stop repeating Kubernetes workload names in the demo
The demo scenario renamed every generated deployment to one of four
curated names and every pod to one of ten, cycling by index. With the
default 14 deployments and 40 pods per cluster the Kubernetes overview
listed checkout-api four times in one namespace, and the curated
pending and crash-looping pods appeared more than once. Kubernetes
itself refuses duplicate names in a namespace, so the public demo
looked broken.

Ten more healthy services fill out the default deployment count, a
numeric suffix keeps any larger count unique, and pods past the curated
story become healthy ReplicaSet-style replicas of the cluster's own
deployments on ready nodes, so each curated failure appears once.

Contract-Neutral: Mock fixture naming only: demo Kubernetes deployments and pods get unique names; no runtime contract delta.
2026-10-05 00:00:14 +01:00
pulse-triage[bot] 3dd9d29ccf Integrate reviewed guest metadata observation freshness
Preserve exact Core candidate f1e221a0fb. Retained source-ji23nb_c proves failed and unusable refresh controls, connected suites, focused races, vet and builds. Existing canonical-only frontend changes are disjoint; no frontend resolution or new browser proof is needed. Native guest recovery remains with Delivery.

Change-source: pulse-maintainer
2026-10-04 23:58:22 +01:00
rcourtman 26871ef1ee Open a guest's saved web interface from its drawer header
Phone and narrow workload rows hide the adjacent web link so guest
names stay distinguishable. On a phone that left a saved service
reachable only from the URL field on the drawer's Manage tab, three
taps deep and behind a settings form.

The guest drawer header now carries an Open action whenever a URL is
saved, built from the shared WebInterfaceLink and drawer-header action
class, so the service is one tap from the expanded row with a 44px
phone target. Rows are unchanged: showing the row link at 393px
truncated names until checkout-web-01 and checkout-web-02 read the
same.

Refs #1556.
2026-10-04 23:49:55 +01:00
rcourtman be4469e522 Label vSphere host groups with their cluster, not a VM
On the vSphere overview every ESXi host group header carried a chip
naming the host's first VM (esxi-01.lab.local [etl-batch-01]) where the
cluster belongs. The workload adapter took the cluster from
getPreferredResourceClusterName, which falls back to the resource's own
name. That fallback suits a cluster resource, but a vSphere VM keeps its
cluster in vmware.clusterName, which the helper never reads, so the VM
became its own cluster. Standalone Proxmox guests had the same problem
in their context label.

Workloads now take the cluster only from an explicit source: the vSphere
facet, then the existing explicit helper. The grouping instance keeps
its old fallback chain, so group keys do not move.

Contract-Neutral: Behavioral bug fix: workload cluster labels stop falling back to the workload's own name; no contract delta.
2026-10-04 23:49:40 +01:00
pulse-triage[bot] 5e7e49650f Keep missing drawer History readings out of continuous trends
Split series at actual in-panel stored times without that metric, retaining every isolated and measured-zero observation. Explain gaps visibly and accessibly without guessing cadence, outage cause or duration. Live recovery cannot fill stored gaps. Production drawer browser proof and connected controls preserve source/access isolation, exact-time inspection, independent readings and the request budget.

Change-source: pulse-maintainer
2026-10-04 23:40:10 +01:00
pulse-triage[bot] f1e221a0fb Keep failed guest metadata refreshes from renewing evidence
Retain metadata values and the last useful observation time through failed, empty and unusable refreshes. Apply the existing retry backoff separately instead of making retained identity new guest-agent evidence or a fresh complete-cache hit. Preserve useful partial responses, normal cache hits and OS failure policy, with HTTP polling and recovery controls.

Contract-Neutral: Behavioural correction to existing guest metadata observation timestamps and retry scheduling; no schema, API, route, field, guest command, admission, duration, retention or numeric source-selection contract delta.
Change-source: pulse-maintainer
2026-10-04 23:34:19 +01:00