Commit Graph

5827 Commits

Author SHA1 Message Date
pulse-triage[bot] ee618fb993 Guard canonical VM Discovery during guest-read deferrals
Use the existing guest safety signals in the canonical resource drawer, including typed and legacy PVE facets. Keep saved Discovery evidence readable and the backup precaution visible without admitting a manual rescan while paused.

Contract-Neutral: performance-and-scalability; the workload helper input is narrowed without changing its decisions, metrics, render path or performance contract.
Change-source: pulse-maintainer
2026-10-05 17:16:03 +01:00
pulse-triage[bot] e52cf4be50 Incorporate batch-start upstream badge repairs
Change-source: pulse-maintainer
2026-10-05 16:00:31 +01:00
rcourtman 8106de0ab0 Keep Docker update and Kubernetes node status badges whole
The Docker container Updates column and the Kubernetes Nodes Status
column hold badges that cannot truncate, and both were cut at the
cell edge at tablet widths.

Docker containers size columns by layout mode with weights that
renormalize over whichever optional columns show (State, Restarts,
Host, Engine). Updates got 54-76px between a 34rem container and the
md breakpoint, where the phone wrap rule no longer applies, so Update
(74px) and Current (69px) were cut from 573 to 800px. The column now
takes its room only from the CPU bar, which never shows a sublabel,
and the collapsed actions menu, so every other column keeps its width
in every layout and column set and the memory bar keeps its used/total
sublabel. The 74px states fit in every layout and column set at the
layout's narrowest table. The 100px states (Check failed, Updating...,
Completed) fit in most layouts but can still clip at a layout's
narrow end when several optional columns show. Wide rows also gain the room their expanded
lifecycle controls need. A model test checks every layout and column
set.

Kubernetes Nodes Status shared the tablet band equally (51px of room
at 573px) and had 8 percent at md (53px at 768px), so Degraded (64px)
was cut. The band now sizes each column for its header and Degraded
at a 34rem table, and md moves 2.5 points from CPU to Status, keeping
the visible total, so Node, Cluster, Roles, Memory and Capacity keep
their widths everywhere. Degraded, NotReady and Unknown fit from
544px; Unschedulable (89px) fits from about 900px.
2026-10-05 15:27:53 +01:00
pulse-triage[bot] 9b057cb141 Retain current upstream Docker badge sizing alongside reviewed maintenance
Incorporate the scoped-read upstream identity through the completed bounded refresh; preserve all reviewed commit identities and existing source evidence.

Change-source: pulse-maintainer
2026-10-05 15:26:24 +01:00
pulse-triage[bot] 9daeed13d8 Incorporate current upstream layout and Docker editing repairs
Preserve the complete reviewed publication batch and upstream commit identities before final-source validation.

Change-source: pulse-maintainer
2026-10-05 15:03:27 +01:00
rcourtman 9874a1c0d5 Merge remote-tracking branch 'origin/main' into fix/docker-images-update-badge 2026-10-05 14:45:01 +01:00
rcourtman dca46d8fca Keep the Docker image update badge readable at tablet widths
The Images table's Update check badge needs about 122px with its cell
padding for its longest labels ("Update available", "Managed by
Pulse"). Between the phone projection and the md breakpoint every
non-name column took an equal 17.5 percent share, which left the
column 100px at a 600px viewport, and the 16 percent md width left it
111px at 768px. The badge was cut at the cell edge with a stray
ellipsis dot, and the "UPDATE CHECK" header clipped at 600px.

The table now declares tablet-band widths through the sortable
header's bandWidth (Update check 23, Size 12; Host and Used by keep
their 17.5) and moves 3 points of md width to Update check, one each
from Host, Used by and Size. The longest size values ("1023 MB",
"9.99 GB") still fit both narrower Size columns.

A clip sweep on a mock stack from 390 to 1440px (15 widths) found the
update badge clipped at 600, 640, 700 and 768px before and nowhere
after. A probe of all six labels against the narrowest Update check
cell found none clipping at any width, and no other column clipped
more often than before. The base already carries the Used by
block-truncate span from #2514, so Used by was measured as it now
renders.
2026-10-05 14:41:49 +01:00
rcourtman 5186d4c560 Bulk-edit Docker container links and hide edits from read-only tokens (#2515)
Follow-up to rcourtman/Pulse#2477.

**Docker containers get the bulk editor**
The strongest demand for saved links (#1556, #624) came from Docker
users, but the editor only reached Proxmox and vSphere guests. The
Docker containers table header now has the same **Edit links** panel,
worded for containers.
- Rows are keyed through `toDiscoveryConfig`, the container drawer's own
metadata target, so bulk and drawer saves read and write the same
`app-container:<host>:name:<name>` record. This includes Docker running
inside Proxmox LXCs.
- The editor now takes a source. Workload tables pass live guests, so
the row model still loads only with the panel. Other tables pass
ready-made rows.
- The Docker table lazy-loads the trigger. Without that, Rollup merged
it into the chunk the Docker and workloads pages share, renamed that
chunk, and broke the `DrawerDiskListCard` bundle budget.

**Read-only tokens no longer see edits that would fail**
Metadata writes require `monitoring:write` for API-token sessions (the
backend's `EnsureScope`). Browser sessions always pass, because metadata
routes have no role check. A kiosk-style `monitoring:read` token saw
edit controls that every save refused with 403. The session store now
mirrors the gate from the security status `tokenScopes`
(`sessionCanWriteMonitoringMetadata()`):
- the bulk editor's **Edit links** button is hidden for such sessions;
- the shared web-interface field shows the saved URL with open and copy,
plus a one-line explanation, but no input, Save, Remove, or "Use this"
suggestion.

**Fewer refetches**
Saves now dispatch their metadata-changed events together after the
writes. `useUnifiedResources` coalesces onto one in-flight refetch, so a
bulk save costs two resource refetches whether it changes 2 links or 4.
Before this, it cost one per link.

**Verification**
- Private mock stack, Docker page and Proxmox page, at 1280 and 375px.
- Real token sessions with the admin bypass off: a `monitoring:read`
token sees no edit affordances, and a `monitoring:read+write` token
saves a container link.
- Receipt: `frontend-modern/browser-verification/e8946b639f30703c.json`.
- Production build: `WorkloadsSurface` 69.08 kB, `Docker` 28.56 kB,
`DrawerDiskListCard` unchanged; no violations.
- Full frontend lint, plus 841 test files (15,618 tests) across
features, hooks, components and stores.
2026-10-05 14:40:18 +01:00
pulse-triage[bot] 5a11eadd41 Reconcile batch-start upstream governance cleanup
Preserve reviewed local integrations and the upstream removal of unused subsystem default proof lists.

Change-source: pulse-maintainer
2026-10-05 14:22:58 +01:00
rcourtman 1358c465f5 Bulk-edit Docker container links and hide edits from read-only tokens
The bulk web-link editor only reached Proxmox and vSphere guests, but the
strongest demand for saved links (#1556, #624) came from Docker users. The
Docker containers table now offers the same Edit links panel, keyed through
the container drawer's own metadata target so bulk and drawer saves share
one record. The trigger is lazy-loaded so it does not merge into the chunk
the Docker and workloads pages already share.

Metadata writes require monitoring:write for API-token sessions, so a
kiosk-style read-only token saw edit controls that every save refused. The
session store now mirrors that gate from the security status token scopes:
the bulk editor is hidden and the shared web-interface field shows the saved
URL without input, Save, Remove, or suggestion adoption. Browser sessions
are unaffected because the backend does not check roles on metadata writes.

Saves now dispatch their metadata-changed events together after the writes,
so a bulk save costs two resource refetches instead of one per link.
2026-10-05 14:12:23 +01:00
rcourtman ff21393c80 Truncate platform summary cells inside their own column
Follow-up to #2509, which fixed the Kubernetes tables. Docker, Proxmox
and vSphere summary cells still wrapped long values in a capped
inline-block span (max-w-48 truncate, max-w-[18rem] truncate, or
truncate inline-block). The cap ignored the column width of these
fixed-layout tables, so a long value ran past a narrower cell with no
ellipsis (a swarm service image by 225px at 700 wide, volume mountpoints
by 51px at 1440), and the inline-block sat about 2px above the row's
text line.

A block truncate span fills the cell, ends in an ellipsis inside it and
sits on the row line. The Docker service Update cell keeps its phone
wrap and truncates inside its column from md instead of at a 10rem cap.

The guardrail from #2509 now covers every platform table source that
carried the pattern, and the coverage table test pins the Node cell.
2026-10-05 14:11:17 +01:00
rcourtman c000972ac9 Require empty subsystem default proof lists the guard never reads
Every subsystem must declare require_explicit_path_policy_coverage, so
build_verification_requirements never falls back to a rule's default
verification policy; an unmatched runtime file becomes a path-policy gap
instead. The default test_prefixes and exact_files were therefore never
consulted, yet 13 of 16 rules carried them (93 files and one prefix),
and authors kept adding proofs there as if they counted.

92 of the 93 files were already proof on some path policy, and
api-contracts' default prefix is on three of its own policies. The one
orphan, internal/api/router_bench_test.go, benchmarks the api-contracts
router rather than any performance-and-scalability runtime, so no policy
should take it; it stays an owned file only.

The registry drops the lists, registry_audit requires them empty and
points authors at the path policy instead, and the canonical protocol
says so. The protocol also stops promising same-subsystem tests "when
the registry explicitly allows them", which the audit no longer permits.

No verdict changes: build_verification_requirements returns identical
requirements for all 2746 owned runtime paths, and for an uncovered
path, under the old and new registry.
2026-10-05 13:50:34 +01:00
pulse-triage[bot] 5b560521e2 Join Router-owned limiter workers during shutdown
Capture all endpoint limiters under their Router owner and seal late worker
admission. Concurrent shutdown joins each cleanup worker without resetting
request budgets or stopping another Router. Integration fixtures use the real
shutdown lifecycle before monitor teardown.

Contract-Neutral: Router worker ownership and concurrent shutdown only; HTTP payloads, limits and windows, auth, tenant selection, revocation and persistence contracts are unchanged.
Change-source: pulse-maintainer
2026-10-05 13:20:08 +01:00
pulse-triage[bot] 2787b4eabd Integrate reviewed same-generation broadcast resource and History capture
Change-source: pulse-maintainer
2026-10-05 13:03:31 +01:00
pulse-triage[bot] 15e8c5ccf6 Integrate reviewed container CPU guidance
Accept exact PI commit 0c283d2dd5 with retained focused source and Docs browser proof. Preserve conditional runtime-host examples and passive comparison safeguards; this is documentation maintenance, not native collection or alert-delivery acceptance.

Change-source: pulse-maintainer
2026-10-05 12:54:47 +01:00
pulse-triage[bot] dfc1b2e8bb Incorporate batch-start upstream Kubernetes layout repair
Preserve the exact upstream history present at coordination start before integrating reviewed CPU help.

Change-source: pulse-maintainer
2026-10-05 12:54:37 +01:00
pulse-triage[bot] 9cc8523881 Compare complete broadcast health at one evaluation instant
The five predeclared diagnostic cases retain a real 1m versus 2m health-age counterexample between separate wall-clock evaluations. Give the independent content oracle and production projection the same private health clock without removing any JSON field; pin minute-boundary age advancement and original LastSeen. Production samples real UTC at the unchanged post-read evaluation point.

Contract-Neutral: Internal health-clock test seam preserves the real UTC evaluation point, public resource/history fields, source precedence, agent identity/lifecycle, tenant/revocation and safety contracts; no wire or permission delta.
Change-source: pulse-maintainer
2026-10-05 12:17:19 +01:00
pulse-triage[bot] 0c283d2dd5 Explain container CPU scales and passive comparisons
Document host-capacity normalisation, version-qualified rounding and the difference between collected readings and delivered alerts. Keep comparisons on ordinary workload observations rather than forced load, threshold changes or diagnostic reruns.

Contract-Neutral: Existing container CPU semantics and safety guidance only; no runtime, API, threshold, permission or lifecycle contract changes.
Change-source: pulse-maintainer
2026-10-05 12:13:26 +01:00
pulse-triage[bot] 8661c1fc65 Integrate reviewed keyboard and touch access to Workloads backup evidence
Preserve the exact Web candidate and its own-parent browser receipt. Retained connected source checks and desktop/touch evidence cover the existing read-only disclosures without changing collection or backup operations.

Change-source: pulse-maintainer
2026-10-05 12:04:21 +01:00
rcourtman b0341768c8 Stop Kubernetes Config and Deployments tables clipping names
Between the phone projection and the md column widths (a 34rem container
below a 768px viewport) the Configuration and Deployments tables split
their width evenly, so names were cut to a few letters beside short
counts. Headers can now declare a percent width for that band through
bandWidth / platformTableBandWidthStyle, and both tables size names
first.

With one cluster in view every scope cell repeated the cluster name and
crowded out the namespace that tells rows apart, so scope cells show the
namespace alone and keep the full cluster/namespace scope on the title
and for assistive technology. Several clusters keep the combined label.

Deployments Desired returns only with wide tables, since Ready already
reads ready over desired, and Ready keeps its denominator until Desired
is visible. On a phone Age takes Ready's spare width so "18h ago" fits.

Summary cells used a capped inline-block span that ignored the column
width: long values spilled past narrow cells with no ellipsis and sat
above the row's text line. A block span fills the cell, ellipsizes there
and aligns with its neighbours.
2026-10-05 12:01:15 +01:00
pulse-triage[bot] 02e6a90374 Make completed-backup evidence accessible in Workloads
Use native read-only disclosure buttons for both backup entry points, with the shared Dialog preserving named completion evidence, focus and guest row action ownership. Keep existing freshness and uncertainty semantics, collection and backup operations unchanged. Include connected regression tests, the subsystem contract and inspected desktop/phone browser verification.

Change-source: pulse-maintainer
2026-10-05 11:41:55 +01:00
pulse-triage[bot] 54de7bdca7 Capture fresh broadcast resources and history targets together
Resolve canonical source mappings once per complete projection while preserving detached resource content and target selection after host coalescing. Bind resources and targets to the same locked generation, including absence and continuity overlays, and avoid another owned outer-slice copy. No timestamp cache or native CPU/RSS claim. Retain cold, clean and dirty full-content controls and paired complete-projection measurements.

Contract-Neutral: Internal bulk-read and copy-ownership repair preserves existing public resource/history fields, source precedence, agent identity/lifecycle, tenant/revocation and safety contracts; no wire or permission delta.
Change-source: pulse-maintainer
2026-10-05 11:25:57 +01:00
pulse-triage[bot] 76c106c732 Incorporate batch-start upstream main before Delivery review
Change-source: pulse-maintainer
2026-10-05 11:04:58 +01:00
rcourtman 3af37a8862 Stop Kubernetes names clipping at tablet widths (#2506)
Kubernetes names clipped badly between about 600 and 900px wide. At
700px node names read "Pr…" and deployment names two letters.

**Why:** between a 544px table container and a 768px viewport, platform
tables show their phone-hidden columns again, but `md:w-[…]` widths are
viewport media queries and don't apply yet. So every visible column took
an equal share. A seven-column Kubernetes table left its name 83px, with
the chevron and status dot inside it. From 768px the Kubernetes name
widths (14–19%) still cut common node, service and event names.

**Fix:**
- The shared table shell keeps the phone 30% name anchor in that band.
Tables sized by a weighted colgroup are unaffected.
- Kubernetes name columns get room for typical names at 768px. The Nodes
columns are rebalanced so Capacity fits at 1100px and wider.
- Generated names (pods, a pod's node, controllers) truncate their head
and keep the trailing segment that tells siblings apart:
`checkout-a…-c7z2p`, `prod…-02`. The tail never outgrows its cell.
Deployment names keep plain end truncation.

**Measured** with a clip sweep over every Kubernetes tab at 600–1440px:
- Identity-column clips fall from 284 to 186. Most of the remainder are
pod heads truncated by design.
- The Nodes table has no name clipping at any width.
- In the band, TrueNAS Storage and a vSphere resource table go from 14
name clips to 0, with no new clips on other platforms.
2026-10-05 11:00:20 +01:00
pulse-triage[bot] d7a305922a Merge reviewed Core guest metadata writer and shutdown safety
Change-source: pulse-maintainer
2026-10-05 10:56:58 +01:00
rcourtman 1ced3fa995 Stop Kubernetes names clipping at tablet widths
Between a 544px table container and a 768px viewport, platform tables
show their phone-hidden columns again, but md:w widths are viewport media
queries and do not apply yet, so every visible column took an equal share.
A seven-column Kubernetes table left its name 83px, with the chevron and
status dot inside it, so node names read "Pr..." and deployment names two
letters. From 768px the Kubernetes name widths (14 to 19 percent) still
cut common node, service and event names.

The shared table shell now keeps the phone 30 percent name anchor in that
band. Tables sized by a weighted colgroup are unaffected. Kubernetes name
columns get room for typical names at 768px, with the Nodes columns
rebalanced so Capacity fits at 1100px and wider. Generated names (pods,
the node a pod runs on, controllers) truncate their head and keep the
trailing segment that tells siblings apart, and that tail never outgrows
its cell.
2026-10-05 10:29:03 +01:00
rcourtman cb9b3e82bc Retire the same-subsystem test wildcard the guards never honoured
staged_verification_files_for_requirement() matches
allow_same_subsystem_tests against a subsystem's
owned_prefixes/owned_files, but both commit guards passed it the
impacted entry, which carried neither. Since the v6 import (778a2577b6)
a same-subsystem test never satisfied a requirement, while
subsystem_lookup.py (which passes the registry rule) and the guard's own
BLOCKED message ("same-subsystem test/spec files are also accepted")
said it would.

Honouring the 12 flags would have loosened the guard well past their
apparent intent. Every rule requires explicit path-policy coverage, so
the five rule-level flags are never consulted, and on the seven path
policies the flag reaches every test the subsystem owns: a
mutation-registry change would accept any internal/ai or AI Chat test
(~455) instead of its 4 listed proofs, and a frontend Actions change any
Go test under internal/unifiedresources. Six of the seven already list
their own directory in test_prefixes.

So the strictness stays and the tools now agree on it: the registry sets
the 12 flags to false (what has always been enforced), registry_audit
rejects true and points at test_prefixes/exact_files, and the impacted
entry carries the rule's ownership so the completion and commit-shape
guards read the flag the same way subsystem_lookup does.

No requirement accepts a proof it rejected before. subsystem_lookup
stops reporting matches the guard refused: a new internal/hostagent test
no longer claims three agent-lifecycle policies.
2026-10-05 10:27:17 +01:00
pulse-triage[bot] 5e51069048 Allow explicit recovery of retained guest metadata after failed close
Keep admission sealed and reuse a still-running close observer. A later explicit shutdown attempt may persist retained state after a completed write failure; successful close remains idempotent. This avoids a permanent offboarding dead end after an ordinary filesystem repair without an automatic spin retry or overlapping writes.

Contract-Neutral: Internal JSON writer recovery behaviour only; public routes, fields, permissions, identity format, private file mode and atomic persistence are unchanged.
Change-source: pulse-maintainer
2026-10-05 09:31:01 +01:00
pulse-triage[bot] 244d322dce Coalesce guest identity writes and retain incomplete tenant shutdown
Admit detached metadata in order, merge identity fields without restoring stale
operator edits, and persist complete snapshots with one owned writer. Seal late
writes and return shutdown failures before organisation data or offboarding is
removed. Preserve existing drain budgets, file format, tenant boundaries and
atomic persistence. Add controlled burst, ordering, write-error, blocked-close
and real deletion controls.

Contract-Neutral: Behavioural repair of existing JSON persistence and organisation deletion; no route, field, permission, identity format, schema or provider authority change. Shutdown failure uses the existing HTTP error envelope. Internal ownership methods and explanatory contract text change, not the public contract shape.
Change-source: pulse-maintainer
2026-10-05 09:21:40 +01:00
pulse-triage[bot] 5127e10164 Preserve reviewed monitoring work alongside upstream TrueNAS storage explanations
Incorporate exact current upstream additively without rewriting accepted candidates. Retain truthful History, private guidance and source ownership controls.

Change-source: pulse-maintainer
2026-10-05 08:27:33 +01:00
pulse-triage[bot] b21969de1a Integrate reviewed private and non-destructive NAS installation guidance
Change-source: pulse-maintainer
2026-10-05 08:06:40 +01:00
pulse-triage[bot] f3c315a1fd Incorporate batch-start published Audit Webhooks guidance
Change-source: pulse-maintainer
2026-10-05 08:06:22 +01:00
rcourtman 615c03de55 Merge remote-tracking branch 'origin/main' into feat/truenas-storage-health-reasons 2026-10-05 07:53:47 +01:00
pulse-triage[bot] e32304902b Incorporate batch-start published security guidance
Preserve the exact published frontier alongside reviewed canonical work. No publication or deployment is performed by this merge.

Change-source: pulse-maintainer
2026-10-05 07:51:04 +01:00
rcourtman 93652f453a Point Audit Webhooks visitors to alert notifications (#2500)
Audit Webhooks is the only webhook page in Settings, so people who want
alerts in Discord or Slack land there. In #1344 a user tried to add a
Discord webhook from it and filed a bug when that didn't work. Alert
delivery lives in Alerts, Notifications, which Settings never mentions.

The panel now opens, gated or enabled, with one line saying these
webhooks carry security events only, linking to alert notifications.

Verified at 1440 and 390. The link lands on /alerts/notifications
without a page reload.
2026-10-05 07:51:04 +01:00
rcourtman 8c2083ad65 Call plain HTTP critical only when Pulse is publicly reachable (#2499)
The Security Overview tagged the HTTPS tile red and Critical on every
install, directly above a hardening card that calls HTTPS Recommended on
a private network and says local HTTP is acceptable. The same flag
counted plain HTTP as a missing critical control in the posture score,
so a typical LAN install read 55 percent.

The tile now uses the hardening card's rule: critical once the instance
is publicly reachable, recommended otherwise. A private install with a
password and protected exports reads 79 percent (still Moderate). A
public one still shows HTTPS as Critical.

Verified at 1440 and 390 on a private-network instance.
2026-10-05 07:41:05 +01:00
rcourtman 146595b848 Merge remote-tracking branch 'origin/main' into feat/truenas-storage-health-reasons 2026-10-05 07:39:46 +01:00
pulse-triage[bot] 5fbc773563 Integrate reviewed alert reconciliation and precise lookup controls
Retain exact Core commits 4768058216 and d500b4f211. Reviewed callback release ordering, metadata-specific measurement boundary and retained race, vet and build proof; unrelated JSON drain failure remains Core-owned.

Change-source: pulse-maintainer
2026-10-05 07:37:52 +01:00
pulse-triage[bot] acdd8b7a65 Incorporate the batch-start published drawer frontier
Preserve existing reviewed integrations and published attention-reason presentation without re-parenting source commits.

Change-source: pulse-maintainer
2026-10-05 07:37:50 +01:00
rcourtman 09f07d8514 Drop the storage table from the title-case helper consumers
The shared-template rule required every TrueNAS table to use the shared
title-case helper. The storage table used it only for the risk-level
pill, which the Health reason replaced, so it no longer formats any raw
provider value and the required-consumer check failed. The scope-wide
guard against a local titleCase helper still covers the file.
2026-10-05 07:37:46 +01:00
rcourtman d8b8541f37 Merge remote-tracking branch 'origin/main' into fix/audit-webhooks-point-to-notifications 2026-10-05 07:25:28 +01:00
pulse-triage[bot] 34a568ef65 Keep constrained NAS install guidance private and non-destructive
Match QNAP guidance to existing data-volume relocation, create private per-attempt staging and preserve diagnostic logs and identity. Exercise copied commands for preparation and installer failures without an appliance operation.

Contract-Neutral: Clarifies existing installer storage and private staging guidance; no runtime, permission or data-contract change.
Change-source: pulse-maintainer
2026-10-05 07:25:14 +01:00
rcourtman e37a692086 Point Audit Webhooks visitors to alert notifications
Audit Webhooks is the only webhook page in Settings, so people looking to
send alerts to Discord or Slack land there. Issue 1344 tried to add a
Discord webhook from it and filed a bug when that did not work. Alert
delivery lives in Alerts, Notifications, which Settings never mentions.

The panel now opens, gated or enabled, with one line saying these webhooks
carry security events only and linking to alert notifications.
2026-10-05 07:23:30 +01:00
rcourtman d2e2243dcc List every reason a resource needs attention in its drawer (#2498)
On a phone the TrueNAS Storage Health column is hidden, so the row
drawer is where a user learns why a row is amber. It fell short in three
ways:

- A read-only dataset said only "Observed state Degraded", because a
read-only dataset raises no incident.
- A pool showed one of its two incidents, because the health presenter
read only the rollup, plus a generic "Resource Health Issue" line.
- When an open alert matched the first reason, the drawer dropped every
other reason.

The fix:

- The shared health presenter keeps every incident summary.
- It adds a TrueNAS dataset's state, through a small shared util the
storage table will also use.
- It uses the rollup's category label only when nothing more specific
exists.
- The Overview's Needs attention list skips only the reasons an open
alert already states, ignoring a trailing full stop.

Verified on the phone and desktop drawers for the read-only dataset and
the degraded pool, and on the Machines table, which is unchanged.
2026-10-05 07:20:45 +01:00
pulse-triage[bot] 3c95617bd1 Integrate reviewed truthful guest History presentation
Preserve the exact reviewed Web commits and their own-parent browser receipts alongside the supplied main frontier.

Change-source: pulse-maintainer
2026-10-05 07:20:38 +01:00
pulse-triage[bot] 757ae22ece Integrate reviewed private Metrics History guidance
Preserve the exact reviewed documentation candidate and its retained privacy/query proof; no runtime or storage changes.

Change-source: pulse-maintainer
2026-10-05 07:14:39 +01:00
rcourtman 731cd84b11 Merge remote-tracking branch 'origin/main' into fix/security-https-severity 2026-10-05 07:05:07 +01:00
pulse-triage[bot] c635e0dda0 Preserve reviewed maintenance alongside current upstream presentation
Additively incorporate the exact observed main frontier without advancing PR2486 or rewriting accepted work. The newer canonical range remains deferred pending its existing source-check and composition-proof routes.

Change-source: pulse-maintainer
2026-10-05 07:04:09 +01:00
rcourtman 85bf454ba3 Call plain HTTP critical only when Pulse is publicly reachable
The Security Overview tagged the HTTPS tile red and Critical on every
install, directly above a hardening card that calls HTTPS Recommended on
a private network and says local HTTP is acceptable. The same flag also
counted plain HTTP as a missing critical control in the posture score, so
a typical LAN install read 55 percent.

The tile now uses the hardening card's rule: critical once the instance
is publicly reachable, recommended otherwise. A private install with a
password and protected exports reads 79 percent, still Moderate, and a
public one still shows HTTPS as Critical.
2026-10-05 07:03:03 +01:00
rcourtman b7e8eb8beb List every reason a resource needs attention in its drawer
On a phone the TrueNAS Storage Health column is hidden, so the row drawer
is where a user learns why a row is amber, and it fell short. A read-only
dataset said only Observed state Degraded, because it raises no incident.
A pool showed one of its two incidents, because the health presenter read
only the rollup, plus a generic Resource Health Issue line. And when an
open alert matched the first reason, the drawer dropped every other one.

The presenter now keeps every incident summary, adds a TrueNAS dataset's
state (the provider's only reason for a read-only dataset, read through a
shared util), and uses the rollup's category label only when nothing more
specific exists. The Overview's Needs attention list skips only the
reasons an open alert already states, ignoring a trailing full stop.
2026-10-05 06:54:42 +01:00