Refs #1510
Refs #1501
Refs #1507
Refs #1442
- persist scoped workloads status filters across platform navigation
- derive host memory pressure from available memory
- reapply system settings after every monitor reload path
- bound PBS backup snapshot polling workers during large backup scans
Capacity forecasts (days-to-full, current usage, trend) were previously
computed deterministically but only fed into LLM prompt text. They never
reached the finding as structured data, so the frontend could not render a
verified urgency signal and the model's speculation was the only thing the
operator saw.
This persists CapacityForecast on Finding (marshal-mirror pair) and stamps
it post-analysis via a service join (StampCapacityForecasts). The forecast
filter now also keeps stable-high (>=80%) pools so the deterministic "no
fill trend" reading wins over model speculation, and fixes isQuiet wrongly
treating stable (-1) trends as filling.
Frontend maps the forecast through the UnifiedFinding view model and renders
a deterministic urgency line (Filling up / Stable / days-to-full · % used)
in the expanded finding detail.
Note: forecasts only populate for resources whose usage is ingested into
metrics history (Proxmox/Ceph storage, nodes, guests). Agent-host storage
(unraid pools) is not yet ingested as a time-series and remains a follow-up
to activate the feature for those pools.
Refs lane: protection-posture-attention-queue
The isEditableTarget early-return blocked Cmd+K when focus was in any
input, textarea, or select element. The command palette shortcut must
work from anywhere — it is the primary keyboard navigation path.
Move the Cmd+K check before the editable-target guard.
Rapid clicks on the copy button accumulated setTimeout callbacks that
continued firing after component unmount. Clear the previous timer
before setting a new one, and clean up on unmount.
Adds an 'Ack all (N)' button next to the '+N related' toggle on grouped
alerts. Acknowledges the primary and all related alerts in one action
using the existing bulkAcknowledge API endpoint, without touching
unrelated alerts.
Alerts that share a resource ancestor (e.g., ZFS pool + device within
that pool) are now grouped on the alerts overview page. The primary
alert (highest severity, most recent) is shown by default with a
'+N related' toggle that expands to reveal the related alerts.
Grouping uses resourceId nesting: alerts with 3+ path segments are
sub-components and share the group key of their parent (first 2
segments). Alerts on different subsystems remain separate.
Single-alert groups render exactly as before — no visual change when
there's nothing to group.
getAlertStyles now accepts an optional nodeMatch parameter. Node table
rows pass their node name so storage/topology/disk alerts (which have
a different resourceId than the node) correctly highlight the affected
node row. Previously ZFS pool errors on minipc were invisible on the
overview page.
Alert resource names are now clickable links that navigate to the
appropriate platform overview page (Proxmox, Docker, Machines, etc.)
based on the alert's resource type. Lets users jump directly from an
alert to the affected resource for investigation.
When the latest Patrol run is available, the healthy empty state body
now includes the coverage summary (e.g. 'Checked 42 resources.') as a
prefix, giving the user immediate freshness and coverage context on a
calm day instead of just 'no action needed'. Addresses checklist L51-53.
- Sort active alerts by severity (critical before warning) then recency
- Add explicit Critical/Warning text badge on each alert card
- Show 'limit: 90%' annotation for threshold-based alerts
- Add critical count breakdown to stats card
Makes alerts more scannable and actionable at a glance.
The backend UnifiedFinding model and API already return ai_confidence
as a 0-1 float for AI-enhanced findings, but the frontend
UnifiedFinding type in aiIntelligence.ts never mapped it.
Added aiConfidence to the UnifiedFinding interface, mapped it from
the API ai_confidence field in normalizeUnifiedFindingRecord, and
rendered it on the expanded finding card as a compact trust
indicator: 'Pulse confidence: High (87%)' / 'Moderate' / 'Low'.
Only shown when aiConfidence > 0 — patrol findings without AI
enhancement do not show a confidence line.
Addresses checklist L48-50: 'Recommendations expose trust
scaffolding: evidence, confidence/reason, scope or blast radius,
proposed action, approval requirement, verification result, and
attempt history.'
Shows probe status (Up/Down), latency, method, target, last-checked
time, and error details for guests that already have an availability
probe. Sits alongside the suggestion card which only shows when no
probe exists yet.
BrainCircuitIcon from lucide-solid was used as JSX inside the
module-level GUEST_COLUMNS constant. In SolidJS, component JSX
compiles to createComponent(), which was being called at module
evaluation time — outside any reactive root — triggering the
console warning: 'computations created outside a createRoot or
render will never be disposed'.
Replaced with an inline SVG matching the pattern used by all other
column icons in the same file. Removed the lucide-solid import.
Availability probe badges (latency, failed, timed out) previously
rendered inline in the Name column. This moves them to a dedicated
'Avail' column right after Name with center-aligned badge layout
(kind: 'badge'), giving users:
- Vertical scannability: latency values align in a clean column
instead of floating at variable x-positions after guest names
- Conceptual separation: Name answers 'what is this?', Availability
answers 'is this up?'
Removes AvailabilityProbeCell from both the Name column and the OS
column fallback. The column is always visible (min layout: mobile)
across all view modes (all, vm, system-container, container,
app-container).
Verified via Playwright: 'Avail' header renders after 'Name', 31 cells
populated, jellyfin shows '6ms' in its own column.
hasMeaningfulDiscoveryContext returned false for records without deep
scan data (empty service_type, no facts, no ports), which prevented the
GuestDrawerOverview from rendering the availability probe suggestion
card — even when suggested_availability_probe was populated.
Add hasSuggestedProbe to the meaningful context check so the suggestion
card renders for guests that have a backfilled probe suggestion but
haven't been deep-scanned yet.
Verified via Playwright: bazarr (no existing probe, no deep scan data)
now shows the suggestion card with HTTP :6767 at 192.168.0.78.
The alertsActivation store (config, activation state, active alerts,
error) was not reset on org switch. Stale config from the previous
org (thresholds, activation state) persisted until the next page
navigation triggered refreshConfig.
The patrol polling effect did not depend on activeOrgID, so it
continued using the old interval without immediately loading new
org data. With the intelligence state now cleared on org switch,
this caused up to 30s of empty findings until the next poll cycle.