Repair held-notification governance proof

Bind the combined delivery-attempt and held-event activity surface to the alerts, API, and frontend contracts. Add recognized state and presentation proofs and record desktop, refresh, and narrow-browser verification for the current feature commit.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot] 2026-08-26 22:52:10 +01:00
parent 954ea1050a
commit 3fd5e1a50c
6 changed files with 70 additions and 26 deletions

View file

@ -1863,7 +1863,15 @@ newest-first record of real alert delivery attempts with plain-language
outcome labels, destination names resolved from the loaded webhook configs,
failure classes, and secret-redacted error text. The card names its retention
window and says that test sends skip the queue, and an unreadable log renders
as unavailable rather than empty. Test-send results that report
as unavailable rather than empty. The same card interleaves alert-owned
`notification_suppressed` and `notification_deferred` evidence from
`GET /api/alerts/events` with those attempts, ordered by the recorded event or
attempt time. Held rows name the affected resource, alert type, and
plain-language policy reason even when no delivery attempt exists. The event
read is independent and fail-soft: an unavailable event log removes held rows
without delaying, hiding, or marking the notifications-owned attempt log as
unavailable. Refreshing delivery evidence starts both reads from one operator
action while preserving that failure isolation. Test-send results that report
`deliveryPaused` surface as a warning toast, never plain success, across the
email, Apprise, and webhook test actions in `useAlertDestinationsTabState`
and `useAlertWebhookDestinationsState`. Delivery evidence remains

View file

@ -4454,7 +4454,12 @@ event store returns `[]` rather than `null`. The event payload is evidence of
recorded lifecycle and notification-decision seams only. It must not dispatch,
acknowledge, resolve, or otherwise mutate alert or notification state, and the
current absence of a fired lifecycle event must not be inferred as a firing
that never happened.
that never happened. `frontend-modern/src/api/alerts.ts` owns the typed client
projection and shared `arrayOrEmpty` normalization. The Destinations surface
requests only the two held-notification event types over the same seven-day
window as its delivery-attempt log, with an explicit bounded limit. That event
request runs independently of `GET /api/notifications/delivery-log`; failure
of either API must not recast the other response as empty or unavailable.
The generated PVE setup-script temperature wrapper is part of the API contract
for legacy SSH sensor collection. Discovery uses non-opening `smartctl --scan`

View file

@ -434,6 +434,15 @@ bulk diagnosis snapshot per overview refresh, wraps beside started-at and
threshold metadata at narrow widths, and does not create a second card or
page-level banner. Acknowledged cards omit the redundant row, and unavailable
diagnosis data leaves the existing alert card intact.
The Destinations delivery-activity surface follows the same ownership split:
alerts own the `AlertDeliveryLogCard` composition inside the shared `Card`,
button, badge, list, and responsive wrapping primitives. Its single
newest-first list may mix notification delivery attempts with alert-policy held
events, but each row retains its owning outcome vocabulary and evidence
tooltip. At narrow widths, resource, reason, and relative-time fields wrap or
truncate inside the card without creating page-level horizontal overflow, and
the shared refresh action remains independently usable while the bounded list
scrolls.
The legacy pricing handoff page may also route its visible redirect title and
manual-link copy through the catalog, but `Pulse Account`, route paths, feature
keys, query parameters, public URLs, and purchase-return state remain