diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index c8dc2476ce..5d10a49ac1 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -97,7 +97,7 @@ All backend code lives under `cmd/`, `internal/`, and `pkg/`. The binary is asse
9. **Recovery Engine (`internal/recovery`)**
- Aggregates backup data (PBS snapshots, ZFS snapshots, replication tasks) into a unified recovery point timeline.
- - Provides faceted queries: filter by type, source, status. Rollup summaries for dashboards.
+ - Provides faceted queries: filter by type, source, status, and source health.
- API: `/api/recovery/points`, `/api/recovery/series`, `/api/recovery/facets`, `/api/recovery/rollups`.
10. **Audit Logging (`pkg/audit`)**
@@ -137,7 +137,6 @@ Navigation is organised by **task**, not by platform:
| `/storage` | Storage | Proxmox storage, ZFS pools, Ceph |
| `/recovery` | Recovery | Backups, snapshots, replication |
| `/ceph` | Ceph | Detailed Ceph cluster view |
-| `/dashboard` | Dashboard | Summary panels and metrics |
| `/alerts/*` | Alerts | Alert rules, active alerts, history |
| `/ai/*` | AI Intelligence | Patrol findings, investigations, forecasts |
| `/settings/*` | Settings | Configuration, security, diagnostics, reporting, AI, relay |
diff --git a/README.md b/README.md
index 23093c350d..45355c3ce5 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,11 @@
## π Overview
-Pulse is a modern, unified dashboard for monitoring your **infrastructure** across Proxmox, Docker, Kubernetes, and TrueNAS. It consolidates metrics, alerts, and AI-powered insights from all your systems into a single, beautiful interface.
+Pulse is a modern, unified monitoring workspace for your **infrastructure** across Proxmox, Docker, Kubernetes, and TrueNAS. It consolidates metrics, alerts, and AI-powered insights from all your systems into a single, beautiful interface.
Designed for homelabs, sysadmins, and MSPs who need a "single pane of glass" without the complexity of enterprise monitoring stacks.
-
+
## π§ Unified Navigation
@@ -94,7 +94,7 @@ docker run -d \
rcourtman/pulse:vX.Y.Z
```
-Access the dashboard at `http://:7655`.
+Open Pulse at `http://:7655`.
## Local Development
diff --git a/docs/RBAC.md b/docs/RBAC.md
index bbd09d6c91..d8943ff23d 100644
--- a/docs/RBAC.md
+++ b/docs/RBAC.md
@@ -176,7 +176,7 @@ A typical team configuration:
|------|------|--------|
| alice | `admin` | Full access to everything |
| bob | `operator` | Can view nodes/VMs and manage alerts |
-| carol | `viewer` | Read-only access to dashboards and metrics |
+| carol | `viewer` | Read-only access to monitoring views and metrics |
| monitoring-bot | API token with `alerts:read` scope | Automated alert polling |
---
diff --git a/docs/release-control/v6/internal/records/infrastructure-default-landing-dashboard-retirement-2026-04-29.md b/docs/release-control/v6/internal/records/infrastructure-default-landing-dashboard-retirement-2026-04-29.md
new file mode 100644
index 0000000000..7e75c07c64
--- /dev/null
+++ b/docs/release-control/v6/internal/records/infrastructure-default-landing-dashboard-retirement-2026-04-29.md
@@ -0,0 +1,44 @@
+# Infrastructure Default Landing Dashboard Retirement
+
+Date: 2026-04-29
+Lane: First-session post-RC polish
+Follow-up: `first-session-post-rc-polish`
+Assertion: `infrastructure-default-landing-surface`
+
+## Outcome
+
+Pulse v6 now treats Infrastructure as the authenticated landing surface. The old Dashboard route is retired instead of preserved as a compatibility wallboard: primary navigation no longer includes Dashboard, root runtime routing sends authenticated operators to Infrastructure, and first-session/setup completion handoffs now point into Infrastructure or Add infrastructure.
+
+The Dashboard-specific overview stack is also removed rather than rebranded locally. Workload table code that still belongs to the product is owned under `frontend-modern/src/components/Workloads/`, and the deleted Dashboard overview API (`/api/resources/dashboard-summary`) is absent from the router, handler inventory, client API, and route tests.
+
+## Proof
+
+- `npm --prefix frontend-modern run type-check`
+ - Result: pass.
+- `npm --prefix frontend-modern run lint`
+ - Result: pass; ESLint, theme audit, and canonical platform audit completed.
+- `npm --prefix frontend-modern test -- src/components/Workloads src/pages/__tests__/Workloads.helpers.test.ts src/utils/__tests__/frontendResourceTypeBoundaries.test.ts src/utils/__tests__/workloadEmptyStatePresentation.test.ts src/utils/__tests__/workloadGuestPresentation.test.ts src/__tests__/App.architecture.test.ts src/__tests__/AppLayout.test.tsx src/routing/__tests__/navigation.test.ts`
+ - Result: pass, 36 files and 563 tests.
+- `go test ./internal/api -run 'Test(RouterRouteInventory|RouteInventoryContractCoversAllRouteModules|RouterFrontendRouteInventory|ResourceList|ResourceGet|ResourceAndStorageResponses|ResourceContract|ApplyResource|ComputeResource|UnsupportedResourceType|ParseResource|SecurityStatus|SecurityTokens|RouterCSRF|AdminEndpoints|SSO|OIDC|SAML|MagicLink|HandlePublicMagicLink|EstablishOIDCSession|EstablishSAMLSession|BuildSSOOIDCCallbackURL|SanitizeOIDCReturnTo|RedirectOIDC|RedirectSAML|Contract_Resource|Contract_Security|Contract_ResetFirstRunSecurity)' -count=1`
+ - Result: pass.
+- `python3 scripts/release_control/contract_audit.py --pretty`
+ - Result: pass.
+- `python3 scripts/release_control/status_audit.py --pretty`
+ - Result: pass.
+- `python3 scripts/release_control/registry_audit.py --pretty`
+ - Result: pass.
+- `python3 scripts/release_control/canonical_completion_guard.py`
+ - Result: pass.
+- `python3 scripts/release_control/canonical_completion_guard_test.py`
+ - Result: pass, 136 tests.
+- `python3 scripts/release_control/subsystem_lookup_test.py`
+ - Result: pass, 181 tests.
+- Browser proof on the local v6 app:
+ - Authenticated `/` redirected to `/infrastructure`.
+ - `/infrastructure` rendered the Infrastructure heading with no Dashboard primary-nav tab.
+ - `/dashboard` rendered the Not Found page with no Workloads surface and no Dashboard primary-nav tab.
+
+## Verification Residual
+
+- `go test ./internal/api -count=1`
+ - Result: fail outside this slice. `TestSLO_WorkloadCharts` exceeded its strict local p95 SLO under package load (`p95=92.83075ms` against a 90ms target), and `TestSLO_WorkloadsSummaryCharts` exceeded the same local p95 SLO (`p95=135.267ms` against a 90ms target). The focused API route/resource/auth contract tests above are green.
diff --git a/docs/release-control/v6/internal/status.json b/docs/release-control/v6/internal/status.json
index 9a97b8605b..34153adf39 100644
--- a/docs/release-control/v6/internal/status.json
+++ b/docs/release-control/v6/internal/status.json
@@ -2896,21 +2896,6 @@
"performance-and-scalability"
],
"evidence": [
- {
- "repo": "pulse",
- "path": "frontend-modern/src/components/Dashboard/__tests__/Dashboard.performance.contract.test.tsx",
- "kind": "file"
- },
- {
- "repo": "pulse",
- "path": "frontend-modern/src/components/Dashboard/Dashboard.tsx",
- "kind": "file"
- },
- {
- "repo": "pulse",
- "path": "frontend-modern/src/components/Dashboard/workloadSelectors.ts",
- "kind": "file"
- },
{
"repo": "pulse",
"path": "frontend-modern/src/components/Infrastructure/__tests__/UnifiedResourceTable.performance.contract.test.tsx",
@@ -2931,6 +2916,21 @@
"path": "frontend-modern/src/components/Infrastructure/UnifiedResourceTable.tsx",
"kind": "file"
},
+ {
+ "repo": "pulse",
+ "path": "frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx",
+ "kind": "file"
+ },
+ {
+ "repo": "pulse",
+ "path": "frontend-modern/src/components/Workloads/workloadSelectors.ts",
+ "kind": "file"
+ },
+ {
+ "repo": "pulse",
+ "path": "frontend-modern/src/components/Workloads/WorkloadsSurface.tsx",
+ "kind": "file"
+ },
{
"repo": "pulse",
"path": "internal/api/http_metrics.go",
diff --git a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md
index d6d9bb4d23..d222543716 100644
--- a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md
+++ b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md
@@ -307,16 +307,16 @@ helper instead of carrying lifecycle-local background or hover classes.
That same presentation-only boundary must preserve canonical millisecond timestamps when it serializes chart points, so lifecycle-adjacent first-host and fleet surfaces do not misread rounded chart samples as duplicate or restarted heartbeat evidence.
The same rule now applies to storage summary interaction. Shared sticky-card or row-hover focus behavior on infrastructure, workloads, and storage may reuse the canonical chart transport, but lifecycle-adjacent install, enrollment, and fleet surfaces must not treat highlighted summary series or sticky-shell state as agent freshness or setup progress.
The same rule now applies to infrastructure-summary metric filters. Shared
- dashboard and infrastructure consumers may narrow the canonical
+ infrastructure and other route-owned consumers may narrow the canonical
`/api/charts/infrastructure` payload with a `metrics` query for
presentation hot paths, but lifecycle surfaces must not reinterpret
omitted disk or network series as missing lifecycle telemetry, missing
agent capabilities, or reduced fleet freshness truth.
- The same rule now applies to compact dashboard summary payloads. Shared
- `internal/api/resources.go` summary routes may collapse resource counts,
- problem rows, and top-resource rankings for dashboard hot paths, but
- lifecycle surfaces must not treat `/api/resources/dashboard-summary` as
- install inventory authority, enrollment proof, or fleet freshness truth.
+ The same rule now applies to retired compact dashboard summary payloads.
+ Shared `internal/api/resources.go` routes must not restore
+ `/api/resources/dashboard-summary` as a compatibility read; lifecycle
+ surfaces must continue to use install inventory, enrollment proof, and
+ fleet freshness truth from their owning contracts.
The same presentation-only boundary now covers compact storage summary
chart reads as well. Shared `/api/charts/storage-summary` transport may
request only the canonical `used` and `avail` storage series needed for the
@@ -597,8 +597,8 @@ helper instead of carrying lifecycle-local background or hover classes.
platform-management shell. The secondary agent handoff must land on
`/settings/infrastructure?add=agent`.
When the first host reports successfully, the install workflow must treat
- that as a completion handoff with direct navigation into `/dashboard` and
- `/settings/infrastructure/operations` instead of leaving operators on a
+ that as a completion handoff with direct navigation into `/infrastructure`
+ and `/settings/infrastructure/operations` instead of leaving operators on a
generic lookup result. When the workspace starts from zero active connected
infrastructure and install commands are available, the same lifecycle path
must auto-watch the canonical `/api/state` projection for the first
diff --git a/docs/release-control/v6/internal/subsystems/ai-runtime.md b/docs/release-control/v6/internal/subsystems/ai-runtime.md
index 399e2fabd6..9e79209a4f 100644
--- a/docs/release-control/v6/internal/subsystems/ai-runtime.md
+++ b/docs/release-control/v6/internal/subsystems/ai-runtime.md
@@ -247,7 +247,7 @@ assistant drawer may dock and push the authenticated shell only when the
viewport is wide enough to preserve a usable primary operating surface; once
the available viewport drops below that shell threshold, the drawer must
become an overlay owned by `frontend-modern/src/components/AI/Chat/index.tsx`
-instead of compressing Infrastructure, Dashboard, Storage, or other primary
+instead of compressing Infrastructure, Workloads, Storage, or other primary
runtime pages into an unusable narrow column or forking page-local layout
exceptions.
The closed assistant launcher follows the same shared-shell rule. While the
@@ -875,19 +875,19 @@ The `/api/ai/intelligence/changes` endpoint should also route through the
canonical unified-intelligence recent-change accessor before any
patrol-local detector fallback, so the API surface reads the same unified
timeline source that powers the summary payload.
-Dashboard Pulse Brief context follows the same monitoring-first AI boundary:
-Pulse may surface an Assistant-ready operator paragraph on the dashboard, but
-the first render must be fact-bound to governed dashboard, Patrol, storage,
-recovery, and alert summaries and must pass those facts as structured context
-when the operator asks Assistant to continue. Future server-generated dashboard
-briefs must keep that structured fact contract and policy boundary rather than
-letting an unbounded prompt become the dashboard's source of truth.
-The dashboard-to-Assistant handoff must also keep its execution mode scoped to
-the request. When a Pulse Brief opens Assistant from the dashboard, the drawer
-may prefill the governed dashboard prompt and context, but the submitted chat
-request must set `autonomous_mode:false`, preserve the operator's persistent
-Assistant control-level setting, and disclose the temporary approval-required
-mode in the drawer instead of showing the generic Autonomous warning.
+Retired dashboard Pulse Brief context follows the same monitoring-first AI
+boundary in negative space: `frontend-modern/src/features/dashboardOverview/`
+and the Dashboard route must not be restored just to create an Assistant-ready
+operator paragraph. Future overview or brief surfaces need a governed product
+owner first, must pass fact-bound structured context from owning Infrastructure,
+Workloads, Patrol, storage, recovery, and alert summaries, and must not let an
+unbounded prompt become a route's source of truth.
+Future route-to-Assistant handoffs must also keep their execution mode scoped
+to the request. When an overview brief opens Assistant, the drawer may prefill
+only governed prompt/context data, but the submitted chat request must set
+`autonomous_mode:false`, preserve the operator's persistent Assistant
+control-level setting, and disclose the temporary approval-required mode in
+the drawer instead of showing the generic Autonomous warning.
Those backend AI and Patrol change summaries should derive their canonical
labels and provenance fragments from
`internal/unifiedresources/change_presentation.go`, so the resource-model
diff --git a/docs/release-control/v6/internal/subsystems/alerts.md b/docs/release-control/v6/internal/subsystems/alerts.md
index abf4eb6c8a..37b75547f2 100644
--- a/docs/release-control/v6/internal/subsystems/alerts.md
+++ b/docs/release-control/v6/internal/subsystems/alerts.md
@@ -25,7 +25,7 @@ operator-facing alert routing behavior for live runtime alerts.
3. `internal/alerts/canonical_metric.go`
4. `internal/alerts/canonical_lifecycle.go`
5. `internal/alerts/unified_incidents.go`
-6. `frontend-modern/src/components/Alerts/RecentAlertsPanel.tsx`
+6. `frontend-modern/src/features/alerts/AlertOverviewActiveAlertsSection.tsx`
7. `frontend-modern/src/utils/alertOverviewPresentation.ts`
8. `frontend-modern/src/utils/alertResourceTablePresentation.ts`
9. `frontend-modern/src/utils/alertDestinationsPresentation.ts`
@@ -501,31 +501,25 @@ inline in `frontend-modern/src/features/alerts/OverviewTab.tsx`.
The canonical shared alert-acknowledgement runtime owner is now
`frontend-modern/src/features/alerts/useAlertAcknowledgementState.ts`, which
owns optimistic single/bulk acknowledge control flow, restore behavior, and
-notification feedback for both
-`frontend-modern/src/features/alerts/useAlertOverviewState.ts` and
-`frontend-modern/src/components/Alerts/RecentAlertsPanel.tsx`.
+notification feedback for `frontend-modern/src/features/alerts/useAlertOverviewState.ts`
+and the alert overview render shells.
`frontend-modern/src/features/alerts/useAlertOverviewState.ts` now owns the
derived alert read-model and Last 24 Hours stat refresh for
`frontend-modern/src/features/alerts/OverviewTab.tsx`, while composing that
shared acknowledgement owner instead of keeping its own alert mutation fork.
-Future overview or dashboard recent-alert action behavior should extend that
-shared acknowledgement hook instead of putting acknowledge mutations back into
-either render shell.
+Future overview action behavior should extend that shared acknowledgement hook
+instead of putting acknowledge mutations back into render shells.
Render-heavy alert overview ownership now routes through
`frontend-modern/src/features/alerts/AlertOverviewStatsCards.tsx`,
`frontend-modern/src/features/alerts/AlertOverviewActiveAlertsSection.tsx`,
and `frontend-modern/src/features/alerts/AlertOverviewAlertCard.tsx` instead
of rebuilding stats-card, active-alert, and timeline-card presentation inline
inside `frontend-modern/src/features/alerts/OverviewTab.tsx`.
-Dashboard recent-alert rendering and dashboard alert summary/tone copy now
-route through that same alert overview presentation owner and the alert-owned
-`frontend-modern/src/components/Alerts/RecentAlertsPanel.tsx` surface instead
-of living as a dashboard-page-local panel plus a second dashboard-only alert
-presentation helper.
-That same dashboard recent-alert surface must rank structural health warnings
-above state-only warning messages such as powered-off, stopped, or paused
-workloads before falling back to recency, so chosen workload state does not
-hide active infrastructure or storage problems on the first dashboard screen.
+The retired dashboard recent-alert panel must not be reintroduced as a
+parallel alert surface. Alert summary/tone copy belongs to the alert overview
+presentation owner, and any future compact alert surface must compose the
+shared alert read-model and acknowledgement hook rather than creating a
+dashboard-only panel.
Alert threshold and schedule surfaces must now also treat
`discoveryTarget` as optional frontend input and keep grouping-card state on
diff --git a/docs/release-control/v6/internal/subsystems/api-contracts.md b/docs/release-control/v6/internal/subsystems/api-contracts.md
index ba7c8b6ef3..f9fed41d4a 100644
--- a/docs/release-control/v6/internal/subsystems/api-contracts.md
+++ b/docs/release-control/v6/internal/subsystems/api-contracts.md
@@ -428,22 +428,21 @@ the canonical monitored-system blocked payload.
`internal/api/router_routes_monitoring.go`, `internal/api/router.go`,
`internal/api/types.go`, and `internal/api/contract_test.go` must route
optional infrastructure-summary `metrics` filters through one governed
- transport contract, so dashboard-specific consumers can request only CPU
- and memory without inventing a second summary endpoint or silently widening
- back to disk/network payloads. The same contract must carry those requested
- metric filters through the shared guest-chart batch loader in
+ transport contract, so route-owned consumers can request only the series
+ they render without inventing a second summary endpoint or silently
+ widening back to disk/network payloads. The same contract must carry those
+ requested metric filters through the shared guest-chart batch loader in
`internal/monitoring/monitor_metrics.go` instead of fetching the full guest
metric set and trimming after the API payload is already assembled.
-37. Keep the compact dashboard overview route canonical on that same shared API
- surface. `internal/api/resources.go`,
- `internal/api/router_routes_monitoring.go`,
- `frontend-modern/src/api/resources.ts`,
- `frontend-modern/src/hooks/useDashboardOverview.ts`, and frontend dashboard
- consumers must route KPI cards, problem-resource rows, governed resource
- labels, top-infrastructure identity, and canonical metrics-target join keys
- through `/api/resources/dashboard-summary` instead of reconstructing that
- shell from the paginated `/api/resources` list payload or guessing how
- dashboard trend identities map onto infrastructure chart series.
+37. Keep the retired compact dashboard overview route absent from that same
+ shared API surface. `internal/api/resources.go`,
+ `internal/api/router_routes_monitoring.go`, and
+ `frontend-modern/src/api/resources.ts` must not restore
+ `/api/resources/dashboard-summary`, `useDashboardOverview`, or frontend
+ dashboard consumers as compatibility paths for KPI cards, problem-resource
+ rows, governed resource labels, top-infrastructure identity, or metrics-
+ target join keys. New summary payloads must be owned by their product
+ route and pinned in the API contract there.
38. Keep mock and demo chart reads on the same canonical unified snapshot as
the rest of the API surface. `internal/api/router.go`,
`internal/api/contract_test.go`, and chart consumers must route
@@ -594,7 +593,7 @@ the canonical monitored-system blocked payload.
boundary: when
`frontend-modern/src/components/Settings/useInfrastructureInstallState.tsx`
receives a successful connected-agent lookup result, the canonical install
- flow must expose direct navigation into `/dashboard` and
+ flow must expose direct navigation into `/infrastructure` and
`/settings/infrastructure/operations` rather than leaving the operator on a
transport-only status readout.
21. Keep the shared first-host detection contract explicit on `/api/state` as
@@ -699,7 +698,7 @@ the canonical monitored-system blocked payload.
the status payload flips `hasAuthentication` to `false`, preserves
`bootstrapTokenPath`, and allows browser-owned first-session proof to
re-enter the real setup wizard instead of silently falling back to an
- authenticated dashboard state. That recovery transport may expose the
+ already-authenticated app state. That recovery transport may expose the
bootstrap token file path, but it must not emit the token value into
automatic runtime logs.
30. Keep shared SSO test and metadata-preview transport fail-closed: SAML
@@ -924,7 +923,7 @@ that internal grant.
That same shared API contract now also owns browser-proofed read separation.
Non-billing browser journeys such as
`tests/integration/tests/11-first-session.spec.ts`,
-`tests/integration/tests/journeys/01-smoke-bootstrap-login-dashboard.spec.ts`,
+`tests/integration/tests/journeys/01-smoke-bootstrap-login-infrastructure.spec.ts`,
and `tests/integration/tests/journeys/03-relay-pairing.spec.ts` may call
`/api/license/runtime-capabilities` for feature truth, but they must assert
zero browser requests to `/api/license/entitlements`. Billing activation,
@@ -1604,9 +1603,9 @@ That correlations route now reads through the canonical AI intelligence
facade first, so the handler and its payload keep the detector behind one
shared access layer instead of routing directly to Patrol-local correlation
state.
-That store now also owns the dashboard load bundle used by the Patrol page,
-so the page refresh path stays aligned on one store-owned orchestration layer
-instead of re-encoding the AI bundle inline.
+That store now also owns the Patrol page load bundle, so the page refresh path
+stays aligned on one store-owned orchestration layer instead of re-encoding
+the AI bundle inline.
The AI summary page now also renders the canonical
`frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx`
card for policy posture, so sensitivity, routing, and redaction counts are
diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md
index 9524437d25..c612ca9947 100644
--- a/docs/release-control/v6/internal/subsystems/cloud-paid.md
+++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md
@@ -267,7 +267,7 @@ runtime gating as separate unlinked claims.
they must not turn `trial_eligible`, `trial_eligibility_reason`, or an
expired trial marker into a default Pro CTA or banner.
17. Add or change monitored-system ledger, disclosure, or admission-preview presentation through `frontend-modern/src/components/Settings/MonitoredSystemLedgerPanel.tsx`, `frontend-modern/src/components/Settings/MonitoredSystemAdmissionPreview.tsx`, `frontend-modern/src/components/Commercial/MonitoredSystemDefinitionDisclosure.tsx`, and `frontend-modern/src/utils/monitoredSystemPresentation.ts`
-18. Add or change paid relay settings and pairing presentation through `frontend-modern/src/components/Settings/RelaySettingsPanel.tsx`, `frontend-modern/src/components/Settings/RelayPairingSection.tsx`, and `frontend-modern/src/components/Settings/useRelaySettingsPanelState.ts`. The Dashboard shell must not carry a Relay onboarding card or equivalent blanket upsell β relay discovery stays inside its owning settings surface.
+18. Add or change paid relay settings and pairing presentation through `frontend-modern/src/components/Settings/RelaySettingsPanel.tsx`, `frontend-modern/src/components/Settings/RelayPairingSection.tsx`, and `frontend-modern/src/components/Settings/useRelaySettingsPanelState.ts`. The retired Dashboard shell must not be restored to carry a Relay onboarding card or equivalent blanket upsell β relay discovery stays inside its owning settings surface.
Public demo and other read-only presentation policy states must suppress
relay setup and upsell onboarding instead of inviting pairing or commercial
action from a governed non-manageable surface.
@@ -359,11 +359,11 @@ runtime gating as separate unlinked claims.
RBAC, SSO, audit logging, reporting, and agent profiles may remain present,
but they are secondary included value and must not displace that operator
outcome framing on owned commercial surfaces.
-24. Keep public-demo dashboard bootstrap route-owned on the adjacent
+24. Keep public-demo route bootstrap owned on the adjacent
commercial/runtime boundary. `frontend-modern/src/useAppRuntimeState.ts`
- may prewarm shared infrastructure summary caches for non-dashboard routes,
- but public-demo dashboard arrival must not front-run a broader
- infrastructure-summary fetch than the route actually renders. Commercial
+ may prewarm shared infrastructure summary caches for route-owned surfaces,
+ but public-demo arrival must not front-run a broader infrastructure-summary
+ fetch than the route actually renders. Commercial
posture on `v6-demo` therefore stays governed by the route-owned
presentation policy and summary scope rather than by app-shell-wide
bootstrap heuristics. That same app-shell boundary must also keep the
@@ -641,7 +641,7 @@ contract, but shared billing and upgrade surfaces now hide or suppress
themselves from the resolved `presentationPolicy` payload instead of teaching
mock mode, response-header inference, or frontend-only feature flags to
bypass the real licensing model. That includes settings billing tabs,
-public-demo banner and monitored-system/trial nudges, dashboard relay
+public-demo banner and monitored-system/trial nudges, app-wide relay
paywalls, Patrol upgrade CTAs, and history-lock upsells. Demo readiness
therefore means presentation isolation, not a license exemption.
That same public-demo boundary now also owns route-level commercial
@@ -713,12 +713,12 @@ surfaces such as `frontend-modern/src/components/Settings/useProLicensePanelStat
may still force refresh through the same shared store when plan, activation, or
recovery actions mutate commercial truth.
Non-billing browser journeys must also stay off
-`/api/license/entitlements` entirely. Dashboard, infrastructure, alerts,
+`/api/license/entitlements` entirely. Infrastructure, Workloads, alerts,
first-session gated routes, and relay settings must take feature truth from
`/api/license/runtime-capabilities` or already loaded commercial posture, and
the governed browser proof in
`tests/integration/tests/11-first-session.spec.ts`,
-`tests/integration/tests/journeys/01-smoke-bootstrap-login-dashboard.spec.ts`,
+`tests/integration/tests/journeys/01-smoke-bootstrap-login-infrastructure.spec.ts`,
and `tests/integration/tests/journeys/03-relay-pairing.spec.ts` must continue
to assert zero browser-shell entitlement requests outside owned billing flows.
That same authenticated-shell commercial boundary may surface prerelease
@@ -1375,12 +1375,12 @@ That same authenticated route shell also owns the canonical post-auth landing
path. `frontend-modern/src/App.tsx` and
`frontend-modern/src/pages/RuntimeHome.tsx` must send authenticated `/`
through the runtime-home landing contract first: existing operators and
-self-hosted sessions land on the governed dashboard route, while hosted
-workspaces with no connected infrastructure forward into the canonical
-infrastructure onboarding contract before the workspace normalizes back to the
-single `/settings/infrastructure` shell. That same shared landing contract
-must not regress into a root-only redirect straight to the infrastructure
-workspace or a dashboard-only shortcut that strands first-time hosted tenants.
+self-hosted sessions land on the governed Infrastructure route, while hosted
+workspaces with no connected infrastructure stay on the same Infrastructure
+and Add infrastructure ownership path before the workspace normalizes back to
+the single `/settings/infrastructure` shell. That same shared landing contract
+must not regress into a root-only settings redirect or a dashboard-only
+shortcut that strands first-time hosted tenants.
That same landing contract also owns authenticated `/login`: once the browser
has a valid session, `frontend-modern/src/App.tsx` must route `/login`
through that same runtime-home landing boundary instead of leaving the
@@ -1580,10 +1580,11 @@ license state for Community users and leave discovery of paid tiers to
surfaces outside the plan page.
That same no-funnel rule extends beyond Settings -> Plan. The self-hosted
frontend must not render blanket trial/upgrade marketing to Community users
-from the main dashboard shell, the setup wizard completion screen, or any
+from the main app shell, the setup wizard completion screen, or any
app-wide surface that fires without the user having explicitly engaged with
-a paid feature. In particular the Dashboard overview may not carry a
-`RelayOnboardingCard` paywall or equivalent `Start trial` prompt, the
+a paid feature. In particular the retired Dashboard overview must not be
+restored to carry a `RelayOnboardingCard` paywall or equivalent `Start trial`
+prompt, the
`SetupCompletionPanel` may not carry a `Monitor from Anywhere` Relay trial
block, and no time-triggered "active use" nudge such as `ActiveUseTrialNudge`
may auto-appear for Community users. Feature-gated discovery that fires only
@@ -1673,10 +1674,10 @@ owns relay config/status polling and pairing runtime, and
`frontend-modern/src/components/Settings/RelayPairingSection.tsx` owns the QR
pairing surface. Future relay settings work must extend that split instead of
pulling polling and QR-generation lifecycle back into the shell component.
-The Dashboard shell must not host a Relay onboarding card or equivalent
-blanket Relay upsell. Relay discovery belongs to the owning Settings surface
-above; the Dashboard stays a monitoring-first view with no app-wide paywall
-onboarding composed into it.
+The retired Dashboard shell must not be restored to host a Relay onboarding
+card or equivalent blanket Relay upsell. Relay discovery belongs to the owning
+Settings surface above; Infrastructure and Workloads stay monitoring-first
+views with no app-wide paywall onboarding composed into them.
That relay pairing boundary now also includes backend-owned mobile credential
lifecycle: when the settings surface generates a mobile pairing QR, it must ask
the server for a fresh scoped Pulse Mobile relay access token, fetch the
@@ -2096,7 +2097,7 @@ canonical browser bootstrap signal, and shared billing or upgrade surfaces
must hide or suppress themselves from that contract rather than teaching mock
mode, response-header inference, or frontend-only feature flags to bypass the
real licensing model. That includes settings billing tabs, public-demo banner
-and monitored-system/trial nudges, dashboard relay paywalls, Patrol upgrade
+and monitored-system/trial nudges, app-wide relay paywalls, Patrol upgrade
CTAs, and history-lock upsells. Demo readiness therefore means presentation
isolation, not a license exemption.
That same bootstrap owner must also avoid protected pre-auth noise. When auth
diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md
index 3cc01339e9..1351608d31 100644
--- a/docs/release-control/v6/internal/subsystems/deployment-installability.md
+++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md
@@ -247,9 +247,10 @@ server-side update execution surfaces.
7. Keep managed-runtime first-session helpers deterministic: shared browser
helpers under `tests/integration/tests/helpers.ts` may only drive the live
setup wizard through the current managed runtime after refreshing the
- canonical dev reset route, and any helper changes that rely on hot-dev
- browser/backend behavior must keep a managed-runtime recovery proof updated
- in the same slice.
+ canonical dev reset route, authenticated completion must expect the
+ Infrastructure landing path rather than the retired `/dashboard` route, and
+ any helper changes that rely on hot-dev browser/backend behavior must keep a
+ managed-runtime recovery proof updated in the same slice.
8. Keep root-level Playwright wrapper routing on the canonical managed browser
truth. `playwright.config.ts`, `tests/integration/playwright.config.ts`,
and `tests/integration/tests/runtime-defaults.ts` must resolve the same
@@ -690,7 +691,8 @@ requests together with `page.request` or other direct API helper calls.
Managed runtime recovery and browser bootstrap proofs therefore need to keep
helper coverage that demonstrates browser-shell request tracking remains
trustworthy when the same test also performs direct health or security-status
-API probes.
+API probes, and that authenticated bootstrap does not fall back to the retired
+Dashboard route.
`scripts/hot-dev-bg.sh` must also supervise `scripts/hot-dev.sh` in an isolated
child session so an unexpected owner-process death cannot leave orphaned
watchers or health monitors behind. When the supervisor replaces the managed
diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md
index 954963ffaf..1c003b9c60 100644
--- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md
+++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md
@@ -99,10 +99,10 @@ work extends shared components instead of creating new local variants.
73. `frontend-modern/src/utils/reportableResourceTypes.ts`
74. `frontend-modern/src/utils/reportingResourceTypes.ts`
75. `frontend-modern/src/utils/problemResourcePresentation.ts`
-76. `frontend-modern/src/utils/dashboardEmptyStatePresentation.ts`
-77. `frontend-modern/src/utils/dashboardGuestPresentation.ts`
-78. `frontend-modern/src/utils/dashboardKpiPresentation.ts`
-79. `frontend-modern/src/utils/dashboardTrendPresentation.ts`
+76. `frontend-modern/src/utils/workloadEmptyStatePresentation.ts`
+77. `frontend-modern/src/utils/workloadGuestPresentation.ts`
+78. `frontend-modern/src/utils/emptyStatePresentation.ts`
+79. `frontend-modern/src/utils/semanticTonePresentation.ts`
80. `frontend-modern/src/components/Toast/Toast.tsx`
81. `frontend-modern/src/utils/toast.ts`
82. `frontend-modern/src/utils/semanticTonePresentation.ts`
@@ -194,10 +194,10 @@ work extends shared components instead of creating new local variants.
icon components may keep their standalone labels, but the nav must treat
those icons as decorative inside tab buttons so names come from the tab
label plus meaningful badge counts, not duplicated icon titles.
- Dashboard overview primitives under `frontend-modern/src/features/` must keep
- grouped resource labels operator-readable: count-led labels may aggregate
- repeated resources, but uncountable or category-like resource types such as
- storage must use resource wording instead of naive pluralization.
+ Shared grouped-resource presentation primitives must keep grouped resource
+ labels operator-readable: count-led labels may aggregate repeated resources,
+ but uncountable or category-like resource types such as storage must use
+ resource wording instead of naive pluralization.
Infrastructure filter chrome under `frontend-modern/src/features/infrastructure/`
must use mode-oriented labels for table presentation controls: grouped table
mode is `Grouped`, not `Cluster`, because cluster remains a
@@ -536,9 +536,8 @@ work extends shared components instead of creating new local variants.
16. Keep assistant availability bootstrap on the shared app-shell boundary.
`frontend-modern/src/useAppRuntimeState.ts`,
`frontend-modern/src/App.tsx`,
- `frontend-modern/src/stores/aiChat.ts`,
- `frontend-modern/src/components/AI/Chat/index.tsx`, and
- `frontend-modern/src/hooks/useDashboardActions.ts` must consume the
+ `frontend-modern/src/stores/aiChat.ts`, and
+ `frontend-modern/src/components/AI/Chat/index.tsx` must consume the
backend-owned `/api/security/status.sessionCapabilities.assistantEnabled`
fact instead of probing `/api/settings/ai` or `/api/ai/*` during ordinary
route bootstrap. Closed assistant chrome and non-AI settings panels may
@@ -674,7 +673,7 @@ work extends shared components instead of creating new local variants.
instead of importing generic commercial presentation helpers directly into
hosted settings route shells.
8. Keep first-session dashboard empty-state copy on
- `frontend-modern/src/utils/dashboardEmptyStatePresentation.ts`, and make
+ `frontend-modern/src/utils/workloadEmptyStatePresentation.ts`, and make
infrastructure setup guidance name the canonical destination explicitly
instead of falling back to generic settings CTA labels.
9. Keep the live first-session wizard on the canonical three-step runtime
@@ -722,10 +721,11 @@ work extends shared components instead of creating new local variants.
and the `Add infrastructure` entry point on it, not by a second landing route,
so first-time operators and returning operators see one consistent
infrastructure surface by default.
-14. Keep dashboard onboarding copy on the shared presentation owner in
- `frontend-modern/src/utils/dashboardEmptyStatePresentation.ts`. Both the
- infrastructure empty state and the dashboard route's no-resources state
- must route first-time operators into the canonical
+14. Keep Infrastructure and Workloads onboarding copy on the shared
+ presentation owner in
+ `frontend-modern/src/utils/workloadEmptyStatePresentation.ts`. Both the
+ infrastructure empty state and the Workloads no-resources state must route
+ first-time operators into the canonical
`/settings/infrastructure?add=pick` source picker, describe platform API
inventory and Pulse Agent telemetry as equal source strategies, and avoid
falling back to either passive βnothing here yetβ wording or the retired
@@ -778,14 +778,14 @@ work extends shared components instead of creating new local variants.
storage summary emphasis, and workloads summary emphasis must all route through
that helper instead of maintaining page-local copies of the same hover/focus
rules.
- `frontend-modern/src/App.tsx` must land `/` on the dashboard shell and let
- the governed dashboard empty state route first-time operators into the
- `Add infrastructure` source picker, instead of preserving a separate
- root-only jump to `/infrastructure` or an agent-only install jump that
- drifts from the rest of the onboarding contract.
+ `frontend-modern/src/App.tsx` must land `/` on the Infrastructure route and
+ let the governed Infrastructure empty state route first-time operators into
+ the `Add infrastructure` source picker, instead of preserving a separate
+ root-only compatibility shell or an agent-only install jump that drifts from
+ the rest of the onboarding contract.
The same entry-shell contract must also canonicalize authenticated
`/login`: once auth succeeds, the shared shell must resolve that route back
- onto the governed dashboard landing path instead of rendering a page-local
+ onto the governed Infrastructure landing path instead of rendering a page-local
not-found state inside the authenticated chrome.
24. Keep relay settings shell copy on the shared presentation owner in
`frontend-modern/src/utils/relayPresentation.ts`. The route metadata in
@@ -1213,9 +1213,9 @@ activity support surface or integrated summary panel must remain factual
activity copy rather than shifting into a second Patrol verdict label while a
run is underway.
`frontend-modern/src/components/shared/TagBadges.tsx` is now also the
-canonical tag-badge primitive. Dashboard workload rows and the unified-resource
-detail drawer must import that shared owner instead of keeping a dashboard-local
-tag badge variant or importing a feature-local path into infrastructure
+canonical tag-badge primitive. Workload rows and the unified-resource detail
+drawer must import that shared owner instead of keeping a workload-local tag
+badge variant or importing a feature-local path into infrastructure
surfaces.
That same owner now also holds the CSP-safe tag-dot rendering contract: tag
color and active-state emphasis must travel through SVG fill/stroke attributes
@@ -1322,33 +1322,21 @@ metadata. The shell may expose `data-active-series-display` and
runtime/model owners may decide whether a hovered or focused series is merely
emphasized or fully isolated; feature shells must not fork their own row-hover
line filtering.
-The dashboard overview trend cards now also have an explicit shared-shell
-obligation: `frontend-modern/src/features/dashboardOverview/TrendCharts.tsx`
-must treat missing infrastructure history as a governed empty state rather than
-as a silent blank sparkline box. Error copy and empty-history copy belong to
-the feature shell, while the data path and chart-shaping logic must stay in the
-owned hook/model layers that feed it.
-That same dashboard overview shell also owns workload discoverability copy on
-the KPI strip. `frontend-modern/src/features/dashboardOverview/KPIStrip.tsx`
-and `frontend-modern/src/utils/dashboardKpiPresentation.ts` must keep the
-`Workloads` card explicit that the unified workloads surface contains VMs,
-containers, and pods, rather than assuming operators will infer that mapping
-from the route label alone.
-That same dashboard boundary now also owns the shared dashboard presentation
-helpers through `frontend-modern/src/utils/dashboardEmptyStatePresentation.ts`,
-`frontend-modern/src/utils/dashboardGuestPresentation.ts`,
-`frontend-modern/src/utils/dashboardKpiPresentation.ts`,
-`frontend-modern/src/utils/dashboardMetricPresentation.ts`, and
-`frontend-modern/src/utils/dashboardTrendPresentation.ts`. Dashboard loading,
-disconnect, and empty states; guest backup/disk fallback copy; KPI card
-framing; status-badge, delta, percent, and action-priority formatting; and
-trend palette/error copy must extend those helpers instead of being redefined
-inline in route shells, guest rows, or overview cards.
-That shell must also stay passive with respect to data ownership: dashboard
-trend cards may render the summary-range controls and operator-facing empty or
-error copy, but they must not reintroduce route-local metrics-history fetch
-loops for CPU and memory sparklines when the canonical infrastructure summary
-surface already owns the chart contract.
+The retired dashboard overview route must not regain feature-local trend,
+KPI, problem-resource, or card shells. Workload-table and guest-row fallback
+copy that lives under `frontend-modern/src/components/Workloads/` must keep
+using `frontend-modern/src/utils/workloadEmptyStatePresentation.ts` and
+`frontend-modern/src/utils/workloadGuestPresentation.ts`. New route-level empty
+states, tone mapping, or compact issue copy must extend the shared
+`emptyStatePresentation`, `semanticTonePresentation`, and
+`problemResourcePresentation` helpers instead of reviving deleted
+dashboard-only KPI, metric, storage, recovery, or trend presentation helpers.
+That shell must also stay passive with respect to data ownership: future
+overview trend cards may render summary-range controls and operator-facing
+empty or error copy only after they have a governed owner, and they must not
+reintroduce route-local metrics-history fetch loops for CPU and memory
+sparklines when the canonical infrastructure summary surface already owns the
+chart contract.
The shared density map now follows that same owner split.
`frontend-modern/src/components/shared/DensityMap.tsx` stays the render shell,
`frontend-modern/src/components/shared/useDensityMapState.ts` owns hover
@@ -1685,7 +1673,7 @@ runtime logic inline. Audit-log filter option labels must come from
label primitive instead of hard-coded title-case strings in the settings shell.
That shared filter-option primitive is also the canonical owner for default
`All ` option wording wherever a product surface exposes filter selects
-or segmented filter choices. Workloads/dashboard filters, storage source
+or segmented filter choices. Workloads filters, storage source
filters, recovery history and platform/type filters, Kubernetes namespace
drawers, resource-change timeline filters, and alert configuration options must
call `frontend-modern/src/components/shared/filterOptionPresentation.ts` through
@@ -1736,49 +1724,15 @@ public demo posture must keep those support entries hidden from the Settings
navigation instead of reviving a standalone operations page.
that are unavailable in demo mode.
-The dashboard overview route now follows that same feature-owner pattern for
-its dashboard-specific summary surfaces. `frontend-modern/src/pages/Dashboard.tsx`
-stays the route shell, while `frontend-modern/src/features/dashboardOverview/`
-owns the dashboard-specific action, KPI, problem-resource, trend, and
-customization surfaces. Lane-owned widgets like recent alerts, storage,
-and recovery must continue to route through their own subsystem owners instead
-of drifting back into a page-local dashboard panel cluster.
-That same dashboard overview boundary owns the first-viewport estate
-orientation contract for the v6 landing page. `EstateSummaryPanel.tsx` and
-`estateSummaryModel.ts` in `frontend-modern/src/features/dashboardOverview/`
-must derive system count, health, source coverage, and freshness from the
-canonical connected-infrastructure projection, fall back only to the compact
-dashboard summary that the route already owns, and keep the explicit
-Infrastructure handoff above detailed problem, storage, recovery, or trend
-rows without restoring platform-special navigation.
-Source coverage is part of that first-viewport proof and must remain readable
-at mobile and tablet shell widths; the estate summary may wrap that provider
-inventory across lines, but it must not truncate the canonical source mix with
-ellipsis in the default dashboard viewport.
-That compact fallback must keep speaking in system terms. When the connected
-projection has not arrived yet, estate orientation copy may say how many
-systems are reporting or syncing, but it must not slide back to generic
-resource-count language that blurs the v6 system model.
-That first-viewport copy must distinguish system-level estate health from
-resource, alert, storage, or recovery issues that remain elsewhere on the
-dashboard, and partial/empty dashboard states must describe synchronization or
-infrastructure-source onboarding in operator terms instead of exposing
-implementation fallback language.
-The estate summary may surface resource and alert issue counts only as
-below-the-summary detail references; it must not claim the whole dashboard has
-no issues when storage or recovery widgets still own independent health
-signals. Those detail references must use governed dashboard section anchors so
-the first viewport can move focus to Problem Resources or Alerts without
-inventing separate dashboard drill-down routes.
-The dashboard may add an optional Pulse Brief below that estate orientation
-only when Assistant and Patrol are actually enabled and configured. That brief
-must stay additive to the factual dashboard source of truth, derive its first
-render from the already-owned estate, overview, action, storage, and recovery
-facts, and hand off to Pulse Assistant through a structured context prompt
-instead of replacing the route's canonical numbers, tables, or lane-owned
-widgets with model prose. `PulseBriefPanel.tsx`, `useDashboardPulseBrief.ts`,
-and `dashboardPulseBriefModel.ts` own that presentation and deterministic
-first-render summary contract under `frontend-modern/src/features/dashboardOverview/`.
+The dashboard overview route and its feature-owned summary surfaces are
+retired. Authenticated root entry now lands on Infrastructure, so first-
+viewport estate orientation belongs to the Infrastructure page and Add
+infrastructure flow rather than a separate dashboard shell. Future overview or
+brief-style surfaces must be governed as new product surfaces before they add
+route-level data orchestration, section anchors, or Assistant prompt handoffs;
+they must not restore `frontend-modern/src/pages/Dashboard.tsx`,
+`frontend-modern/src/features/dashboardOverview/`, or deleted dashboard-only
+presentation helpers as compatibility paths.
The recovery feature shell now also depends on the shared
`frontend-modern/src/components/shared/Subtabs.tsx` primitive for its primary
protected-items versus recovery-events workspace switch. The recovery lane may
@@ -1882,28 +1836,19 @@ status-shaped names such as `storage (offline)` into first-viewport prose or
grouped-row sublabels; when the resource name is only a type plus status, the
surface should summarize the type-level issue in operator language instead of
repeating raw backend-shaped labels.
-That same dashboard overview boundary must consume the governed Patrol finding
-presentation helpers when it surfaces Patrol findings in compact form. In
-`frontend-modern/src/features/dashboardOverview/ActionRequiredPanel.tsx`,
-Patrol-owned runtime findings must use the shared compact badge, title, and
-primary-action/manual-control contracts from
-`frontend-modern/src/utils/aiFindingPresentation.ts` rather than rendering raw
-`Pulse Patrol:` titles or generic snooze/dismiss controls that the Patrol
-runtime lifecycle rejects.
-That same boundary must also consume the shared attention-queue ordering from
-`frontend-modern/src/utils/aiFindingPresentation.ts` through
-`frontend-modern/src/hooks/useDashboardActions.ts`, so Patrol-blinding runtime
-issues sort ahead of same-severity infrastructure findings in the dashboard
-action panel instead of inheriting arbitrary store order.
+The retired dashboard action queue must not be reintroduced as a compact
+Patrol or infrastructure issue panel. Patrol-owned runtime findings remain
+governed by `frontend-modern/src/utils/aiFindingPresentation.ts` and their
+own Patrol route/store surfaces; any future cross-surface issue queue needs a
+new governed owner rather than reviving dashboard action-panel files.
Feature-owned alert shells under `frontend-modern/src/features/alerts/` now
also treat shared action runtime as a first-class feature owner instead of
-rebuilding it per surface. The overview shell and dashboard recent-alerts panel
-must both compose
+rebuilding it per surface. The overview shell must compose
`frontend-modern/src/features/alerts/useAlertAcknowledgementState.ts` for
acknowledge/restore behavior rather than keeping duplicate API and notification
-logic inline in `useAlertOverviewState.ts` or
-`frontend-modern/src/components/Alerts/RecentAlertsPanel.tsx`.
+logic inline in `useAlertOverviewState.ts` or a revived dashboard recent-alert
+panel.
The same feature-owner rule now applies to the alert scheduling surface:
`frontend-modern/src/features/alerts/tabs/ScheduleTab.tsx` must remain the
schedule render shell, while
@@ -2622,7 +2567,7 @@ path inside Infrastructure.
`frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx`,
`frontend-modern/src/components/Settings/settingsHeaderMeta.ts`,
`frontend-modern/src/components/Settings/settingsNavigationModel.ts`,
-`frontend-modern/src/utils/dashboardEmptyStatePresentation.ts`,
+`frontend-modern/src/utils/workloadEmptyStatePresentation.ts`,
`frontend-modern/src/utils/infrastructureEmptyStatePresentation.ts`, and
adjacent setup guidance must use `Add infrastructure` as the operator-facing
first-run label for API-backed onboarding, resolve that label to the shared
@@ -2707,8 +2652,7 @@ That same shared app-shell boundary now also owns assistant bootstrap silence
on non-AI routes. `frontend-modern/src/useAppRuntimeState.ts`,
`frontend-modern/src/App.tsx`,
`frontend-modern/src/stores/aiChat.ts`,
-`frontend-modern/src/components/AI/Chat/index.tsx`, and
-`frontend-modern/src/hooks/useDashboardActions.ts` must treat
+`frontend-modern/src/components/AI/Chat/index.tsx` must treat
`/api/security/status.sessionCapabilities.assistantEnabled` as the only
general-route assistant availability fact, while closed assistant chrome and
non-AI settings panels stay off `/api/settings/ai` and `/api/ai/*` until an
diff --git a/docs/release-control/v6/internal/subsystems/monitoring.md b/docs/release-control/v6/internal/subsystems/monitoring.md
index 1c83426be2..09b21af1b1 100644
--- a/docs/release-control/v6/internal/subsystems/monitoring.md
+++ b/docs/release-control/v6/internal/subsystems/monitoring.md
@@ -322,17 +322,17 @@ sampler generation instead of regenerating or re-downsampling the same seeded
timeline on every endpoint hit. When seeded mock history is rebuilt or a live
mock tick advances, monitoring must invalidate that cache so preview charts
stay current without paying repeated per-request synthesis cost.
-That same sampler-owned cache contract also covers compact dashboard summary
-reads. When live mock ticks advance, monitoring must repopulate the canonical
-24-hour aggregate `/api/charts/storage-summary` cache inside the sampler path
-instead of leaving the first operator request after each tick to rebuild
-per-pool mock storage charts on demand.
+That same sampler-owned cache contract also covers compact summary reads after
+the dashboard overview retirement. When live mock ticks advance, monitoring
+must repopulate the canonical 24-hour aggregate `/api/charts/storage-summary`
+cache inside the sampler path instead of leaving the first operator request
+after each tick to rebuild per-pool mock storage charts on demand.
That same metrics-hot-path ownership also includes metric-type selection for
-compact summary reads. When dashboard infrastructure or storage summary routes
-request only a subset of canonical chart series, `internal/monitoring/monitor_metrics.go`
-must preserve that narrowed metric set through the batch store fallback path
-instead of querying every metric type for each resource and discarding most of
-the payload afterward.
+compact summary reads. When infrastructure or storage summary routes request
+only a subset of canonical chart series,
+`internal/monitoring/monitor_metrics.go` must preserve that narrowed metric
+set through the batch store fallback path instead of querying every metric type
+for each resource and discarding most of the payload afterward.
That same mock-runtime owner now also owns demo-scenario curation.
`internal/mock/fixture_graph.go`, `internal/mock/platform_fixtures.go`, and
`internal/mock/demo_scenarios.go` may project an authored demo estate over
diff --git a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md
index 9d0081d454..f68bc7c627 100644
--- a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md
+++ b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md
@@ -9,7 +9,7 @@
"contract_file": "docs/release-control/v6/internal/subsystems/performance-and-scalability.md",
"status_file": "docs/release-control/v6/internal/status.json",
"registry_file": "docs/release-control/v6/internal/subsystems/registry.json",
- "dependency_subsystem_ids": ["ai-runtime", "api-contracts", "cloud-paid", "frontend-primitives", "storage-recovery", "unified-resources"]
+ "dependency_subsystem_ids": ["api-contracts", "frontend-primitives"]
}
```
@@ -25,63 +25,63 @@ regression protection.
3. `pkg/metrics/store_slo_test.go`
4. `internal/api/slo.go`
5. `internal/api/slo_bench_test.go`
-6. `frontend-modern/src/components/Dashboard/Dashboard.tsx`
-7. `frontend-modern/src/components/Dashboard/DashboardStateCards.tsx`
-8. `frontend-modern/src/components/Dashboard/DashboardStatsStrip.tsx`
-9. `frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx`
-10. `frontend-modern/src/components/Dashboard/WorkloadPanel.tsx`
-11. `frontend-modern/src/components/Dashboard/WorkloadTableHeader.tsx`
-12. `frontend-modern/src/components/Dashboard/useDashboardState.ts`
-13. `frontend-modern/src/components/Dashboard/useDashboardControlsState.ts`
-14. `frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts`
-15. `frontend-modern/src/components/Dashboard/useDashboardGuestMetadataState.ts`
-16. `frontend-modern/src/components/Dashboard/useDashboardSelectionState.ts`
-17. `frontend-modern/src/components/Dashboard/useDashboardWorkloadRouteState.ts`
-18. `frontend-modern/src/components/Dashboard/useDashboardWorkloadUrlSync.ts`
-19. `frontend-modern/src/components/Dashboard/DashboardFilter.tsx`
-20. `frontend-modern/src/components/Dashboard/dashboardFilterModel.ts`
-21. `frontend-modern/src/components/Dashboard/useDashboardFilterState.ts`
-22. `frontend-modern/src/components/Dashboard/ThresholdSlider.tsx`
-23. `frontend-modern/src/components/Dashboard/thresholdSliderModel.ts`
-24. `frontend-modern/src/components/Dashboard/useThresholdSliderState.ts`
-25. `frontend-modern/src/components/Dashboard/StackedDiskBar.tsx`
-26. `frontend-modern/src/components/Dashboard/stackedDiskBarModel.ts`
-27. `frontend-modern/src/components/Dashboard/useStackedDiskBarState.ts`
-28. `frontend-modern/src/components/Dashboard/StackedMemoryBar.tsx`
-29. `frontend-modern/src/components/Dashboard/stackedMemoryBarModel.ts`
-30. `frontend-modern/src/components/Dashboard/useStackedMemoryBarState.ts`
-31. `frontend-modern/src/components/Dashboard/MetricBar.tsx`
-32. `frontend-modern/src/components/Dashboard/metricBarModel.ts`
-33. `frontend-modern/src/components/Dashboard/useMetricBarState.ts`
-34. `frontend-modern/src/components/Dashboard/EnhancedCPUBar.tsx`
-35. `frontend-modern/src/components/Dashboard/enhancedCpuBarModel.ts`
-36. `frontend-modern/src/components/Dashboard/useEnhancedCPUBarState.ts`
-37. `frontend-modern/src/components/Dashboard/DiskList.tsx`
-38. `frontend-modern/src/components/Dashboard/diskListModel.ts`
-39. `frontend-modern/src/components/Dashboard/useDiskListState.ts`
-40. `frontend-modern/src/components/Dashboard/GuestRow.tsx`
-41. `frontend-modern/src/components/Dashboard/GuestRowCells.tsx`
-42. `frontend-modern/src/components/Dashboard/guestRowModel.tsx`
-43. `frontend-modern/src/components/Dashboard/useGuestRowState.ts`
-44. `frontend-modern/src/components/Dashboard/GuestDrawer.tsx`
-45. `frontend-modern/src/components/Dashboard/GuestDrawerOverview.tsx`
-46. `frontend-modern/src/components/Dashboard/guestDrawerModel.ts`
-47. `frontend-modern/src/components/Dashboard/useGuestDrawerState.ts`
-48. `frontend-modern/src/components/Dashboard/useGroupedTableWindowing.ts`
-49. `frontend-modern/src/components/Dashboard/workloadSelectors.ts`
-50. `frontend-modern/src/components/Dashboard/workloadTopology.ts`
-51. `frontend-modern/src/components/Dashboard/dashboardSelectionModel.ts`
-52. `frontend-modern/src/components/Dashboard/dashboardWorkloadRouteModel.ts`
-53. `frontend-modern/src/components/Dashboard/dashboardWorkloadFilterConfigModel.ts`
-54. `frontend-modern/src/components/Dashboard/dashboardWorkloadRouteStateModel.ts`
-55. `frontend-modern/src/components/Dashboard/dashboardWorkloadUrlSyncModel.ts`
-56. `frontend-modern/src/components/Dashboard/useDashboardWorkloadFilterOptions.ts`
-57. `frontend-modern/src/components/Dashboard/__tests__/dashboardSelectionModel.test.ts`
-58. `frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadFilterConfigModel.test.ts`
-59. `frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadRouteModel.test.ts`
-60. `frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadRouteStateModel.test.ts`
-61. `frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadUrlSyncModel.test.ts`
-62. `frontend-modern/src/components/Dashboard/__tests__/workloadTopology.test.ts`
+6. `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`
+7. `frontend-modern/src/components/Workloads/WorkloadsStateCards.tsx`
+8. `frontend-modern/src/components/Workloads/WorkloadsStatsStrip.tsx`
+9. `frontend-modern/src/components/Workloads/WorkloadsTable.tsx`
+10. `frontend-modern/src/components/Workloads/WorkloadPanel.tsx`
+11. `frontend-modern/src/components/Workloads/WorkloadTableHeader.tsx`
+12. `frontend-modern/src/components/Workloads/useWorkloadsState.ts`
+13. `frontend-modern/src/components/Workloads/useWorkloadsControlsState.ts`
+14. `frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts`
+15. `frontend-modern/src/components/Workloads/useWorkloadGuestMetadataState.ts`
+16. `frontend-modern/src/components/Workloads/useWorkloadSelectionState.ts`
+17. `frontend-modern/src/components/Workloads/useWorkloadRouteState.ts`
+18. `frontend-modern/src/components/Workloads/useWorkloadUrlSync.ts`
+19. `frontend-modern/src/components/Workloads/WorkloadsFilter.tsx`
+20. `frontend-modern/src/components/Workloads/workloadsFilterModel.ts`
+21. `frontend-modern/src/components/Workloads/useWorkloadsFilterState.ts`
+22. `frontend-modern/src/components/Workloads/ThresholdSlider.tsx`
+23. `frontend-modern/src/components/Workloads/thresholdSliderModel.ts`
+24. `frontend-modern/src/components/Workloads/useThresholdSliderState.ts`
+25. `frontend-modern/src/components/Workloads/StackedDiskBar.tsx`
+26. `frontend-modern/src/components/Workloads/stackedDiskBarModel.ts`
+27. `frontend-modern/src/components/Workloads/useStackedDiskBarState.ts`
+28. `frontend-modern/src/components/Workloads/StackedMemoryBar.tsx`
+29. `frontend-modern/src/components/Workloads/stackedMemoryBarModel.ts`
+30. `frontend-modern/src/components/Workloads/useStackedMemoryBarState.ts`
+31. `frontend-modern/src/components/Workloads/MetricBar.tsx`
+32. `frontend-modern/src/components/Workloads/metricBarModel.ts`
+33. `frontend-modern/src/components/Workloads/useMetricBarState.ts`
+34. `frontend-modern/src/components/Workloads/EnhancedCPUBar.tsx`
+35. `frontend-modern/src/components/Workloads/enhancedCpuBarModel.ts`
+36. `frontend-modern/src/components/Workloads/useEnhancedCPUBarState.ts`
+37. `frontend-modern/src/components/Workloads/DiskList.tsx`
+38. `frontend-modern/src/components/Workloads/diskListModel.ts`
+39. `frontend-modern/src/components/Workloads/useDiskListState.ts`
+40. `frontend-modern/src/components/Workloads/GuestRow.tsx`
+41. `frontend-modern/src/components/Workloads/GuestRowCells.tsx`
+42. `frontend-modern/src/components/Workloads/guestRowModel.tsx`
+43. `frontend-modern/src/components/Workloads/useGuestRowState.ts`
+44. `frontend-modern/src/components/Workloads/GuestDrawer.tsx`
+45. `frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx`
+46. `frontend-modern/src/components/Workloads/guestDrawerModel.ts`
+47. `frontend-modern/src/components/Workloads/useGuestDrawerState.ts`
+48. `frontend-modern/src/components/Workloads/useGroupedTableWindowing.ts`
+49. `frontend-modern/src/components/Workloads/workloadSelectors.ts`
+50. `frontend-modern/src/components/Workloads/workloadTopology.ts`
+51. `frontend-modern/src/components/Workloads/workloadSelectionModel.ts`
+52. `frontend-modern/src/components/Workloads/workloadRouteModel.ts`
+53. `frontend-modern/src/components/Workloads/workloadFilterConfigModel.ts`
+54. `frontend-modern/src/components/Workloads/workloadRouteStateModel.ts`
+55. `frontend-modern/src/components/Workloads/workloadUrlSyncModel.ts`
+56. `frontend-modern/src/components/Workloads/useWorkloadFilterOptions.ts`
+57. `frontend-modern/src/components/Workloads/__tests__/workloadSelectionModel.test.ts`
+58. `frontend-modern/src/components/Workloads/__tests__/workloadFilterConfigModel.test.ts`
+59. `frontend-modern/src/components/Workloads/__tests__/workloadRouteModel.test.ts`
+60. `frontend-modern/src/components/Workloads/__tests__/workloadRouteStateModel.test.ts`
+61. `frontend-modern/src/components/Workloads/__tests__/workloadUrlSyncModel.test.ts`
+62. `frontend-modern/src/components/Workloads/__tests__/workloadTopology.test.ts`
63. `frontend-modern/src/components/Infrastructure/UnifiedResourceTable.tsx`
64. `frontend-modern/src/components/Infrastructure/unifiedResourceTableStateModel.ts`
65. `frontend-modern/src/components/Infrastructure/useUnifiedResourceTableState.ts`
@@ -95,33 +95,30 @@ regression protection.
73. `frontend-modern/src/components/Infrastructure/unifiedResourceTableModel.ts`
74. `frontend-modern/src/components/Infrastructure/infrastructureSelectors.ts`
75. `frontend-modern/src/components/Infrastructure/resourceDetailMappers.ts`
-76. `frontend-modern/src/components/Dashboard/__tests__/Dashboard.performance.contract.test.tsx`
-77. `frontend-modern/src/components/Dashboard/__tests__/DashboardFilter.test.tsx`
-78. `frontend-modern/src/components/Dashboard/__tests__/useDashboardFilterState.test.ts`
-79. `frontend-modern/src/components/Dashboard/__tests__/useDashboardSelectionState.test.ts`
-80. `frontend-modern/src/components/Dashboard/MetricBar.test.tsx`
-81. `frontend-modern/src/components/Dashboard/__tests__/useMetricBarState.test.tsx`
-82. `frontend-modern/src/components/Dashboard/__tests__/EnhancedCPUBar.test.tsx`
-83. `frontend-modern/src/components/Dashboard/__tests__/useEnhancedCPUBarState.test.tsx`
-84. `frontend-modern/src/components/Dashboard/ThresholdSlider.test.tsx`
-85. `frontend-modern/src/components/Dashboard/__tests__/useThresholdSliderState.test.ts`
-86. `frontend-modern/src/components/Dashboard/__tests__/StackedDiskBar.test.tsx`
-87. `frontend-modern/src/components/Dashboard/__tests__/useStackedDiskBarState.test.tsx`
-88. `frontend-modern/src/components/Dashboard/StackedMemoryBar.test.tsx`
-89. `frontend-modern/src/components/Dashboard/__tests__/useStackedMemoryBarState.test.tsx`
-90. `frontend-modern/src/components/Dashboard/__tests__/DiskList.test.tsx`
-91. `frontend-modern/src/components/Dashboard/__tests__/GuestRow.test.tsx`
-92. `frontend-modern/src/components/Dashboard/GuestDrawer.test.tsx`
-93. `frontend-modern/src/components/Dashboard/__tests__/useGroupedTableWindowing.test.ts`
+76. `frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx`
+77. `frontend-modern/src/components/Workloads/__tests__/WorkloadsFilter.test.tsx`
+78. `frontend-modern/src/components/Workloads/__tests__/useWorkloadsFilterState.test.ts`
+79. `frontend-modern/src/components/Workloads/__tests__/useWorkloadSelectionState.test.ts`
+80. `frontend-modern/src/components/Workloads/MetricBar.test.tsx`
+81. `frontend-modern/src/components/Workloads/__tests__/useMetricBarState.test.tsx`
+82. `frontend-modern/src/components/Workloads/__tests__/EnhancedCPUBar.test.tsx`
+83. `frontend-modern/src/components/Workloads/__tests__/useEnhancedCPUBarState.test.tsx`
+84. `frontend-modern/src/components/Workloads/ThresholdSlider.test.tsx`
+85. `frontend-modern/src/components/Workloads/__tests__/useThresholdSliderState.test.ts`
+86. `frontend-modern/src/components/Workloads/__tests__/StackedDiskBar.test.tsx`
+87. `frontend-modern/src/components/Workloads/__tests__/useStackedDiskBarState.test.tsx`
+88. `frontend-modern/src/components/Workloads/StackedMemoryBar.test.tsx`
+89. `frontend-modern/src/components/Workloads/__tests__/useStackedMemoryBarState.test.tsx`
+90. `frontend-modern/src/components/Workloads/__tests__/DiskList.test.tsx`
+91. `frontend-modern/src/components/Workloads/__tests__/GuestRow.test.tsx`
+92. `frontend-modern/src/components/Workloads/GuestDrawer.test.tsx`
+93. `frontend-modern/src/components/Workloads/__tests__/useGroupedTableWindowing.test.ts`
94. `frontend-modern/src/components/Infrastructure/__tests__/UnifiedResourceTable.performance.contract.test.tsx`
-95. `frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts`
-96. `frontend-modern/src/components/Dashboard/__tests__/useDashboardWorkloadViewportSync.test.tsx`
+95. `frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts`
+96. `frontend-modern/src/components/Workloads/__tests__/useWorkloadViewportSync.test.tsx`
97. `frontend-modern/src/components/Infrastructure/InfrastructureSummary.tsx`
98. `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`
99. `frontend-modern/src/components/Infrastructure/infrastructureSummaryModel.ts`
-100. `frontend-modern/src/hooks/useDashboardTrends.ts`
-101. `frontend-modern/src/hooks/__tests__/useDashboardTrends.test.ts`
-102. `frontend-modern/src/components/Storage/DashboardStoragePanel.tsx`
103. `frontend-modern/src/components/Storage/StorageSummary.tsx`
104. `frontend-modern/src/utils/storageSummaryCache.ts`
105. `frontend-modern/src/pages/Workloads.tsx`
@@ -168,40 +165,36 @@ regression protection.
`/auth/trial-activate` and `POST /api/license/trial/start` from public-path
and CSRF inventories must stay as constant-time route-table absence rather
than replacing the old callback with persistence-backed router probes.
-5. Extend dashboard hot-path filter, sort, grouping, and stats math through `frontend-modern/src/components/Dashboard/workloadSelectors.ts`, and extend workload identity, discovery routing, and node-topology helpers through `frontend-modern/src/components/Dashboard/workloadTopology.ts`, rather than duplicating selector or topology logic in `frontend-modern/src/components/Dashboard/Dashboard.tsx`
- Dashboard landing-page estate orientation is part of that same hot-path
- discipline. First-viewport system count, health, source coverage, and
- freshness must be derived from app-runtime connected-infrastructure state
- and the already-loaded compact dashboard summary fallback; it must not
- introduce a new `useUnifiedResources()` subscription, platform-specific
- fetch, or chart/history request just to make the dashboard feel oriented.
- Dashboard Pulse Brief handoff belongs to that existing route state too:
- `frontend-modern/src/pages/Dashboard.tsx` may open Assistant with the
- already-derived compact prompt and a per-request approval-required override,
- but it must not introduce extra dashboard polling, model/settings fetches,
- or chart/history reads before the Assistant drawer is actually used.
-6. Normalize dashboard workload view-mode aliases through `frontend-modern/src/utils/workloads.ts` instead of keeping local URL/storage parsing in `frontend-modern/src/components/Dashboard/Dashboard.tsx`
-7. Deduplicate dashboard workload rows by canonical workload ID from `frontend-modern/src/utils/workloads.ts` rather than via local pass-through wrappers in `frontend-modern/src/components/Dashboard/Dashboard.tsx`
-8. Render dashboard row identity directly from the shared canonical workload helper so row selection, hover, and fallback metadata lookup stay aligned with the same workload contract
+5. Extend workload hot-path filter, sort, grouping, and stats math through `frontend-modern/src/components/Workloads/workloadSelectors.ts`, and extend workload identity, discovery routing, and node-topology helpers through `frontend-modern/src/components/Workloads/workloadTopology.ts`, rather than duplicating selector or topology logic in `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`
+ The retired dashboard overview route must not return as a hot-path
+ orientation shortcut. First-viewport system count, health, source coverage,
+ and freshness now belong to Infrastructure and Add infrastructure, derived
+ from their existing runtime/resource state rather than a dashboard-specific
+ compact summary fallback. Any future brief-style Assistant handoff needs a
+ newly governed owner and must not add route-global polling, model/settings
+ fetches, or chart/history reads to the authenticated root path.
+6. Normalize workload view-mode aliases through `frontend-modern/src/utils/workloads.ts` instead of keeping local URL/storage parsing in `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`
+7. Deduplicate workload rows by canonical workload ID from `frontend-modern/src/utils/workloads.ts` rather than via local pass-through wrappers in `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`
+8. Render workload row identity directly from the shared canonical workload helper so row selection, hover, and fallback metadata lookup stay aligned with the same workload contract
9. Format infrastructure sensor labels through the shared `frontend-modern/src/utils/textPresentation.ts` presentation helper instead of maintaining a local title-casing implementation in `frontend-modern/src/components/Infrastructure/resourceDetailMappers.ts`
-10. Extend dashboard row contract and per-row hot-path derivations through `frontend-modern/src/components/Dashboard/guestRowModel.tsx` and `frontend-modern/src/components/Dashboard/useGuestRowState.ts`, and extend tooltip-backed row cell presentation through `frontend-modern/src/components/Dashboard/GuestRowCells.tsx`, rather than rebuilding column metadata, row identity, cell tooltips, or anomaly correlation inside `frontend-modern/src/components/Dashboard/GuestRow.tsx`
-11. Extend dashboard drawer derivations and runtime wiring through `frontend-modern/src/components/Dashboard/guestDrawerModel.ts` and `frontend-modern/src/components/Dashboard/useGuestDrawerState.ts`, and extend drawer overview rendering through `frontend-modern/src/components/Dashboard/GuestDrawerOverview.tsx`, rather than rebuilding canonical guest identity, discovery routing, or drawer-local normalization inside `frontend-modern/src/components/Dashboard/GuestDrawer.tsx`
-12. Extend dashboard disk-list derivations and fallback runtime wiring through `frontend-modern/src/components/Dashboard/diskListModel.ts` and `frontend-modern/src/components/Dashboard/useDiskListState.ts` rather than rebuilding usage math, progress-state mapping, or tooltip fallback logic inside `frontend-modern/src/components/Dashboard/DiskList.tsx`
-13. Extend dashboard guest metadata cache persistence, metadata refresh, org-scope switching, and optimistic custom-URL updates through `frontend-modern/src/components/Dashboard/useDashboardGuestMetadataState.ts` rather than rebuilding dashboard-local storage caches, event listeners, or guest metadata API wiring inside `frontend-modern/src/components/Dashboard/useDashboardState.ts`
-14. Extend dashboard deep-link selection and hovered-row continuity semantics through `frontend-modern/src/components/Dashboard/dashboardSelectionModel.ts`, and extend table scroll preservation plus reactive selection state through `frontend-modern/src/components/Dashboard/useDashboardSelectionState.ts`, rather than rebuilding resource-query parsing, selected-row scroll pinning, or hovered-row invalidation inside `frontend-modern/src/components/Dashboard/useDashboardState.ts`; canonical typed workload IDs such as `app-container::` must remain exact route/selection keys and must not be reinterpreted into synthetic node scopes
-15. Extend dashboard workload route ownership, route-driven option catalogs, and toolbar filter config through `frontend-modern/src/components/Dashboard/useDashboardWorkloadRouteState.ts`, `frontend-modern/src/components/Dashboard/useDashboardWorkloadFilterOptions.ts`, `frontend-modern/src/components/Dashboard/dashboardWorkloadRouteModel.ts`, `frontend-modern/src/components/Dashboard/dashboardWorkloadFilterConfigModel.ts`, and `frontend-modern/src/components/Dashboard/dashboardWorkloadRouteStateModel.ts`, and extend query-param synchronization plus managed workload URL semantics through `frontend-modern/src/components/Dashboard/useDashboardWorkloadUrlSync.ts` and `frontend-modern/src/components/Dashboard/dashboardWorkloadUrlSyncModel.ts`, rather than rebuilding route sync, alias parsing, option derivation, toolbar callback/config wiring, reset policy, node-selection compatibility rules, param precedence, or managed workload URLs inside `frontend-modern/src/components/Dashboard/useDashboardState.ts`
- Workloads route host scopes must resolve through `frontend-modern/src/components/Dashboard/workloadTopology.ts`: app-container scopes use the canonical Docker/runtime host id before host labels or node fallbacks, while VM and system-container scopes keep the instance-node key. Route `agent` filters and option catalogs must consume that shared scope so Infrastructure related-workload links cannot drift from Workloads filtering.
-16. Extend grouped dashboard workload derivation, summary fallbacks, and grouped/windowed table presentation through `frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts`, extend viewport-driven grouped table synchronization through `frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts`, and extend node parent mapping through `frontend-modern/src/components/Dashboard/workloadTopology.ts`, rather than rebuilding grouped selectors, summary snapshot math, scroll listeners, or topology lookups inside `frontend-modern/src/components/Dashboard/useDashboardState.ts`
-17. Extend dashboard control defaults, persistent view preferences, keyboard reset behavior, column-visibility ownership, and tag-search flow through `frontend-modern/src/components/Dashboard/useDashboardControlsState.ts` and `frontend-modern/src/components/Dashboard/dashboardFilterModel.ts` rather than rebuilding sort/search/grouping state, reset drift, or column-toggle plumbing inside `frontend-modern/src/components/Dashboard/useDashboardState.ts`
-18. Extend dashboard filter active-count, reset semantics, and mobile toolbar state through `frontend-modern/src/components/Dashboard/dashboardFilterModel.ts` and `frontend-modern/src/components/Dashboard/useDashboardFilterState.ts`, rather than rebuilding filter-local state inside `frontend-modern/src/components/Dashboard/DashboardFilter.tsx`
-19. Extend threshold-slider value-position math, title/label derivation, and drag scroll-lock runtime through `frontend-modern/src/components/Dashboard/thresholdSliderModel.ts` and `frontend-modern/src/components/Dashboard/useThresholdSliderState.ts` rather than rebuilding slider-local state and pointer lifecycle inside `frontend-modern/src/components/Dashboard/ThresholdSlider.tsx`
-20. Extend stacked disk-bar capacity math, segment/tooltip derivation, and resize-observer runtime through `frontend-modern/src/components/Dashboard/stackedDiskBarModel.ts` and `frontend-modern/src/components/Dashboard/useStackedDiskBarState.ts` rather than rebuilding disk-bar-local state, mode branching, and tooltip shaping inside `frontend-modern/src/components/Dashboard/StackedDiskBar.tsx`
-21. Extend stacked memory-bar capacity math, balloon/swap derivation, and resize-observer runtime through `frontend-modern/src/components/Dashboard/stackedMemoryBarModel.ts` and `frontend-modern/src/components/Dashboard/useStackedMemoryBarState.ts` rather than rebuilding memory-bar-local state, tooltip shaping, and label-fit logic inside `frontend-modern/src/components/Dashboard/StackedMemoryBar.tsx`
-22. Extend metric-bar width, label-fit logic, and resize-observer runtime through `frontend-modern/src/components/Dashboard/metricBarModel.ts` and `frontend-modern/src/components/Dashboard/useMetricBarState.ts` rather than rebuilding metric-local state and threshold mapping inside `frontend-modern/src/components/Dashboard/MetricBar.tsx`
-23. Extend enhanced CPU bar usage/anomaly presentation and tooltip runtime through `frontend-modern/src/components/Dashboard/enhancedCpuBarModel.ts` and `frontend-modern/src/components/Dashboard/useEnhancedCPUBarState.ts` rather than rebuilding tooltip-local state and CPU-threshold formatting inside `frontend-modern/src/components/Dashboard/EnhancedCPUBar.tsx`
-23. Extend grouped dashboard row windowing, reveal-index clamping, overscan math, and per-group visible-slice derivation through `frontend-modern/src/components/Dashboard/useGroupedTableWindowing.ts`, and extend viewport event wiring through `frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts` rather than rebuilding scroll handlers, mounted-row budgets, viewport listeners, or group-slice math inside `frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts`
-24. Extend dashboard shell rendering through `frontend-modern/src/components/Dashboard/DashboardStateCards.tsx`, `frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx`, and `frontend-modern/src/components/Dashboard/DashboardStatsStrip.tsx` rather than accreting loading cards, workload table markup, or stats-strip presentation back into `frontend-modern/src/components/Dashboard/Dashboard.tsx`
-25. Extend dashboard workload table shell ownership through `frontend-modern/src/components/Dashboard/WorkloadTableHeader.tsx` and `frontend-modern/src/components/Dashboard/WorkloadPanel.tsx` rather than rebuilding sortable header markup, grouped node rows, row expansion, or guest-drawer rendering inside `frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx`
+10. Extend workload row contract and per-row hot-path derivations through `frontend-modern/src/components/Workloads/guestRowModel.tsx` and `frontend-modern/src/components/Workloads/useGuestRowState.ts`, and extend tooltip-backed row cell presentation through `frontend-modern/src/components/Workloads/GuestRowCells.tsx`, rather than rebuilding column metadata, row identity, cell tooltips, or anomaly correlation inside `frontend-modern/src/components/Workloads/GuestRow.tsx`
+11. Extend workload drawer derivations and runtime wiring through `frontend-modern/src/components/Workloads/guestDrawerModel.ts` and `frontend-modern/src/components/Workloads/useGuestDrawerState.ts`, and extend drawer overview rendering through `frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx`, rather than rebuilding canonical guest identity, discovery routing, or drawer-local normalization inside `frontend-modern/src/components/Workloads/GuestDrawer.tsx`
+12. Extend workload disk-list derivations and fallback runtime wiring through `frontend-modern/src/components/Workloads/diskListModel.ts` and `frontend-modern/src/components/Workloads/useDiskListState.ts` rather than rebuilding usage math, progress-state mapping, or tooltip fallback logic inside `frontend-modern/src/components/Workloads/DiskList.tsx`
+13. Extend workload guest metadata cache persistence, metadata refresh, org-scope switching, and optimistic custom-URL updates through `frontend-modern/src/components/Workloads/useWorkloadGuestMetadataState.ts` rather than rebuilding workload-local storage caches, event listeners, or guest metadata API wiring inside `frontend-modern/src/components/Workloads/useWorkloadsState.ts`
+14. Extend workload deep-link selection and hovered-row continuity semantics through `frontend-modern/src/components/Workloads/workloadSelectionModel.ts`, and extend table scroll preservation plus reactive selection state through `frontend-modern/src/components/Workloads/useWorkloadSelectionState.ts`, rather than rebuilding resource-query parsing, selected-row scroll pinning, or hovered-row invalidation inside `frontend-modern/src/components/Workloads/useWorkloadsState.ts`; canonical typed workload IDs such as `app-container::` must remain exact route/selection keys and must not be reinterpreted into synthetic node scopes
+15. Extend workload route ownership, route-driven option catalogs, and toolbar filter config through `frontend-modern/src/components/Workloads/useWorkloadRouteState.ts`, `frontend-modern/src/components/Workloads/useWorkloadFilterOptions.ts`, `frontend-modern/src/components/Workloads/workloadRouteModel.ts`, `frontend-modern/src/components/Workloads/workloadFilterConfigModel.ts`, and `frontend-modern/src/components/Workloads/workloadRouteStateModel.ts`, and extend query-param synchronization plus managed workload URL semantics through `frontend-modern/src/components/Workloads/useWorkloadUrlSync.ts` and `frontend-modern/src/components/Workloads/workloadUrlSyncModel.ts`, rather than rebuilding route sync, alias parsing, option derivation, toolbar callback/config wiring, reset policy, node-selection compatibility rules, param precedence, or managed workload URLs inside `frontend-modern/src/components/Workloads/useWorkloadsState.ts`
+ Workloads route host scopes must resolve through `frontend-modern/src/components/Workloads/workloadTopology.ts`: app-container scopes use the canonical Docker/runtime host id before host labels or node fallbacks, while VM and system-container scopes keep the instance-node key. Route `agent` filters and option catalogs must consume that shared scope so Infrastructure related-workload links cannot drift from Workloads filtering.
+16. Extend grouped workload derivation, summary fallbacks, and grouped/windowed table presentation through `frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts`, extend viewport-driven grouped table synchronization through `frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts`, and extend node parent mapping through `frontend-modern/src/components/Workloads/workloadTopology.ts`, rather than rebuilding grouped selectors, summary snapshot math, scroll listeners, or topology lookups inside `frontend-modern/src/components/Workloads/useWorkloadsState.ts`
+17. Extend workload control defaults, persistent view preferences, keyboard reset behavior, column-visibility ownership, and tag-search flow through `frontend-modern/src/components/Workloads/useWorkloadsControlsState.ts` and `frontend-modern/src/components/Workloads/workloadsFilterModel.ts` rather than rebuilding sort/search/grouping state, reset drift, or column-toggle plumbing inside `frontend-modern/src/components/Workloads/useWorkloadsState.ts`
+18. Extend workload filter active-count, reset semantics, and mobile toolbar state through `frontend-modern/src/components/Workloads/workloadsFilterModel.ts` and `frontend-modern/src/components/Workloads/useWorkloadsFilterState.ts`, rather than rebuilding filter-local state inside `frontend-modern/src/components/Workloads/WorkloadsFilter.tsx`
+19. Extend threshold-slider value-position math, title/label derivation, and drag scroll-lock runtime through `frontend-modern/src/components/Workloads/thresholdSliderModel.ts` and `frontend-modern/src/components/Workloads/useThresholdSliderState.ts` rather than rebuilding slider-local state and pointer lifecycle inside `frontend-modern/src/components/Workloads/ThresholdSlider.tsx`
+20. Extend stacked disk-bar capacity math, segment/tooltip derivation, and resize-observer runtime through `frontend-modern/src/components/Workloads/stackedDiskBarModel.ts` and `frontend-modern/src/components/Workloads/useStackedDiskBarState.ts` rather than rebuilding disk-bar-local state, mode branching, and tooltip shaping inside `frontend-modern/src/components/Workloads/StackedDiskBar.tsx`
+21. Extend stacked memory-bar capacity math, balloon/swap derivation, and resize-observer runtime through `frontend-modern/src/components/Workloads/stackedMemoryBarModel.ts` and `frontend-modern/src/components/Workloads/useStackedMemoryBarState.ts` rather than rebuilding memory-bar-local state, tooltip shaping, and label-fit logic inside `frontend-modern/src/components/Workloads/StackedMemoryBar.tsx`
+22. Extend metric-bar width, label-fit logic, and resize-observer runtime through `frontend-modern/src/components/Workloads/metricBarModel.ts` and `frontend-modern/src/components/Workloads/useMetricBarState.ts` rather than rebuilding metric-local state and threshold mapping inside `frontend-modern/src/components/Workloads/MetricBar.tsx`
+23. Extend enhanced CPU bar usage/anomaly presentation and tooltip runtime through `frontend-modern/src/components/Workloads/enhancedCpuBarModel.ts` and `frontend-modern/src/components/Workloads/useEnhancedCPUBarState.ts` rather than rebuilding tooltip-local state and CPU-threshold formatting inside `frontend-modern/src/components/Workloads/EnhancedCPUBar.tsx`
+23. Extend grouped workload row windowing, reveal-index clamping, overscan math, and per-group visible-slice derivation through `frontend-modern/src/components/Workloads/useGroupedTableWindowing.ts`, and extend viewport event wiring through `frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts` rather than rebuilding scroll handlers, mounted-row budgets, viewport listeners, or group-slice math inside `frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts`
+24. Extend Workloads shell rendering through `frontend-modern/src/components/Workloads/WorkloadsStateCards.tsx`, `frontend-modern/src/components/Workloads/WorkloadsTable.tsx`, and `frontend-modern/src/components/Workloads/WorkloadsStatsStrip.tsx` rather than accreting loading cards, workload table markup, or stats-strip presentation back into `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`
+25. Extend workload table shell ownership through `frontend-modern/src/components/Workloads/WorkloadTableHeader.tsx` and `frontend-modern/src/components/Workloads/WorkloadPanel.tsx` rather than rebuilding sortable header markup, grouped node rows, row expansion, or guest-drawer rendering inside `frontend-modern/src/components/Workloads/WorkloadsTable.tsx`
Compact icon headers inside `WorkloadTableHeader.tsx` may stay visually
dense for responsive workload tables, but the icon must be decorative and
the column label must remain present through an `sr-only` label so the
@@ -253,14 +246,14 @@ regression protection.
show the host and service tables dropping lower-priority columns without
introducing horizontal overflow.
Dashboard workload table responsive behavior belongs to the same hot-path
- owner. `frontend-modern/src/components/Dashboard/useDashboardControlsState.ts`
+ owner. `frontend-modern/src/components/Workloads/useWorkloadsControlsState.ts`
must derive workload table layout stages from live viewport width, and
- `frontend-modern/src/components/Dashboard/guestRowModel.tsx` must own the
- responsive workload column priority and width model. `DashboardWorkloadTable`,
+ `frontend-modern/src/components/Workloads/guestRowModel.tsx` must own the
+ responsive workload column priority and width model. `WorkloadsTable`,
`WorkloadTableHeader`, and `WorkloadPanel` must consume one shared
layout-visible column set so headers, colgroups, and rows stay aligned during
live resize. View-mode-specific column sets in
- `frontend-modern/src/components/Dashboard/guestRowModel.tsx` must retain
+ `frontend-modern/src/components/Workloads/guestRowModel.tsx` must retain
core monitoring metrics when narrowing scope: app-container mode keeps CPU,
memory, disk, and the responsive Net I/O and Disk I/O columns available,
while the layout priority model decides when detail-heavy I/O columns are
@@ -287,7 +280,14 @@ regression protection.
performance work must not add filesystem reads, GitHub release lookups, or
other per-request version discovery on activation, legacy exchange, or
grant-refresh traffic just to stamp authenticated install metadata.
-30. Keep dashboard summary-chart fetches scope-owned rather than page-churn-owned: `frontend-modern/src/hooks/useDashboardTrends.ts` must hydrate infrastructure and storage summaries once per org/range scope from the canonical summary caches and recompute card presentation locally as the compact dashboard overview changes, rather than refetching the infrastructure-summary transport in `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`, the dashboard storage-summary trend transport in `frontend-modern/src/utils/storageSummaryTrendCache.ts`, or the storage-page summary transport in `frontend-modern/src/utils/storageSummaryCache.ts` for every top-resource or card reshuffle on the same dashboard load. That dashboard infrastructure path must also request only the metrics it renders through the canonical infrastructure-summary route owned by `internal/api/router_routes_monitoring.go` and `internal/api/router.go`; the dashboard may not pay for disk or network summary series when it only renders CPU and memory. App-shell prewarm in `frontend-modern/src/useAppRuntimeState.ts` must not front-run that dashboard-specific route while the operator is already on the root dashboard route owned by `frontend-modern/src/App.tsx`.
+30. Keep retired dashboard summary-chart paths absent rather than replacing
+them with new hot-path fetches. Infrastructure summary cards must continue to
+hydrate through `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`
+and the canonical infrastructure-summary route owned by
+`internal/api/router_routes_monitoring.go` and `internal/api/router.go`; storage
+summary cards must use the storage summary cache owners. The authenticated
+root path in `frontend-modern/src/App.tsx` must not prewarm a deleted
+dashboard-specific overview, trend, or summary transport.
The same hot path must keep mock/demo chart identity on the canonical
unified snapshot too: when mock mode is enabled, `internal/api/router.go`
may not read `/api/charts`, `/api/charts/infrastructure`, or
@@ -320,7 +320,7 @@ regression protection.
hot-path contract: `frontend-modern/src/useAppRuntimeState.ts` may reload
the org list from the shared `organizations_changed` event, but that refresh
must stay event-driven and route-safe rather than expanding into a second
- full app bootstrap, a pre-auth org probe, or a dashboard-route prewarm
+ full app bootstrap, a pre-auth org probe, or a deleted dashboard-route prewarm
that duplicates the canonical summary fetch path.
into another summary-fetch or org-bootstrap hot path.
The same protected hot path also owns Patrol route compatibility: if
@@ -334,7 +334,7 @@ regression protection.
work before the canonical Settings URL takes over.
Authenticated `/login` recovery belongs to that same app-shell boundary:
`frontend-modern/src/App.tsx` must redirect that route back to the
- canonical dashboard landing path instead of leaving the freshly
+ canonical Infrastructure landing path instead of leaving the freshly
authenticated shell on a not-found page that immediately pays another cold
bootstrap.
The same protected hot path now also owns proof harness steadiness.
@@ -343,27 +343,25 @@ regression protection.
must wait for deferred metrics-store startup maintenance to quiesce before
timing steady-state reads, so one-time retention or auto-vacuum cleanup does
not masquerade as summary-route or chart-batch regression latency.
-31. Keep the dashboard overview hot path compact and route-owned. `frontend-modern/src/pages/Dashboard.tsx`, `frontend-modern/src/api/resources.ts`, and `frontend-modern/src/hooks/useDashboardOverview.ts` must hydrate KPI cards, problem-resource rows, and top-infrastructure identities through the compact dashboard-summary API contract owned by the adjacent `api-contracts` and `unified-resources` surfaces, rather than booting the full unfiltered paginated unified-resource list just to derive summary cards.
- Any commercial or relay-owned dashboard affordances composed into that
- route must remain additive shells on top of the same compact summary
- payload instead of reintroducing route-local `all-resources` fetches,
- summary recomputation, or page-level layout churn that displaces the
- protected overview widgets.
- Estate-summary issue copy on that route must use the already-hydrated
- compact overview problem-resource and alert counts; it must not introduce a
- second resource scan, alert fetch, storage read, or recovery read just to
- clarify first-viewport copy. In-page issue anchors must therefore remain
- pure section focus links against already-rendered dashboard sections rather
- than triggering new data hydration.
- Dashboard Pulse Brief composition belongs to that same hot-path rule: the
- first render may issue the existing non-blocking AI runtime settings
- readiness read and consume existing action-state signals, but it must not
- issue an LLM request, mount a second resource scan, or block estate/KPI
- rendering just to produce prose. Its Assistant handoff may add a scoped
- `autonomous_mode:false` flag only when the operator submits the prefilled
- prompt; that request-level safety override must not become a dashboard
- render dependency or a persistent settings write on the hot path.
-32. Keep infrastructure summary consumers on the compact dashboard overview rather than reopening the all-resources hook. `frontend-modern/src/hooks/useDashboardTrends.ts`, `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`, and adjacent dashboard summary consumers may derive chart identity and storage presence from the overview payload they were already given, but they must not call `useResources()` or mount a second unfiltered unified-resource fetch path inside the dashboard hot path. That rule also applies to globally mounted helpers such as `frontend-modern/src/components/AI/Chat/index.tsx`: closed assistant surfaces must read the live websocket snapshot or existing unified-resource cache rather than forcing the dashboard to pay for `all-resources` just because the shell component is mounted. When that assistant shell changes presentation, `frontend-modern/src/utils/aiChatPresentation.ts` must remain the canonical owner for launcher, drawer, session-menu, and empty-state copy so hot-path consumers do not grow one-off inline strings or extra state branches alongside the mounted shell. Blocking shared dialogs must also suppress closed assistant affordances through the shared dialog runtime instead of leaving the mounted shell clickable behind another overlay.
+31. Keep the retired dashboard overview route absent from the protected hot
+path. `frontend-modern/src/pages/Dashboard.tsx`,
+`frontend-modern/src/hooks/useDashboardOverview.ts`, and
+`/api/resources/dashboard-summary` must not be restored as compatibility
+surfaces for KPI cards, problem-resource rows, or top-infrastructure
+identities. New summary cards must live on their owning product route and
+prove their data path there.
+32. Keep infrastructure and assistant consumers off deleted dashboard summary
+state. `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`
+and globally mounted helpers such as `frontend-modern/src/components/AI/Chat/index.tsx`
+must read the live websocket snapshot or existing unified-resource cache
+rather than forcing root navigation to pay for a replacement dashboard
+overview transport. When the assistant shell changes presentation,
+`frontend-modern/src/utils/aiChatPresentation.ts` must remain the canonical
+owner for launcher, drawer, session-menu, and empty-state copy so hot-path
+consumers do not grow one-off inline strings or extra state branches alongside
+the mounted shell. Blocking shared dialogs must also suppress closed assistant
+affordances through the shared dialog runtime instead of leaving the mounted
+shell clickable behind another overlay.
Approval presentation inside that mounted assistant shell must stay
state-local to the existing drawer/session state and backend approval
endpoints. Deny/skip failure handling may preserve the pending approval
@@ -383,21 +381,19 @@ regression protection.
must not hydrate `all-resources` or recovery rollups behind a hidden node
summary; selector-owned data hooks must be explicitly visibility-gated so
`/workloads` only pays for workload-owned transports.
-34. Keep dashboard page-header framing additive on the compact hot path.
- `frontend-modern/src/pages/Dashboard.tsx` may render the shared
- `PageHeader` for route-level shell consistency, but that header must stay
- pure presentation on top of the existing compact overview, trends,
- actions, and recovery/storage widget hydration. It must not introduce a
- second dashboard data load, widen suspense ownership, or force dashboard
- summaries back through full-resource fetch paths just to satisfy page
+34. Keep the retired dashboard page-header path absent from the compact hot
+ path. New page headers must stay pure presentation on their owning route
+ and must not introduce a second data load, widen suspense ownership, or
+ force deleted dashboard summaries back through full-resource fetch paths
+ just to satisfy page
chrome.
-35. Keep the dashboard workloads table CSP-safe on the hot path. The renderers
- in `frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx`,
- `frontend-modern/src/components/Dashboard/WorkloadTableHeader.tsx`,
- `frontend-modern/src/components/Dashboard/GuestRow.tsx`,
- `frontend-modern/src/components/Dashboard/EnhancedCPUBar.tsx`,
- `frontend-modern/src/components/Dashboard/StackedMemoryBar.tsx`, and
- `frontend-modern/src/components/Dashboard/StackedDiskBar.tsx` may still
+35. Keep the Workloads table CSP-safe on the hot path. The renderers
+ in `frontend-modern/src/components/Workloads/WorkloadsTable.tsx`,
+ `frontend-modern/src/components/Workloads/WorkloadTableHeader.tsx`,
+ `frontend-modern/src/components/Workloads/GuestRow.tsx`,
+ `frontend-modern/src/components/Workloads/EnhancedCPUBar.tsx`,
+ `frontend-modern/src/components/Workloads/StackedMemoryBar.tsx`, and
+ `frontend-modern/src/components/Workloads/StackedDiskBar.tsx` may still
use shared models plus SVG or HTML attributes for widths, offsets, and
colors, but they must not fall back to inline `style=` attributes on the
public shell just to express virtualization spacers, alert accents, or
@@ -444,7 +440,7 @@ health-state counts (offline, degraded, alerting) instead of raw online/offline
splits. `InfrastructureSummary.tsx` and `infrastructureSummaryModel.ts` add
`degraded` and `alerting` resource counts; `StorageSummary.tsx` and
`useStoragePageSummary.ts` add `poolsDegraded` and `disksFailing` indicators;
-`WorkloadsSummary.tsx` and `useDashboardWorkloadDerivedState.ts` add an
+`WorkloadsSummary.tsx` and `useWorkloadsDerivedState.ts` add an
alerting count derived from `activeAlerts`. These additions must remain
read-only projections from existing websocket state β they must not introduce
new polling loops or widen fetch scope on the hot-path boundary.
@@ -474,10 +470,10 @@ snapshot-owned sources; the hot path must fail closed until the monitor has
both observed an initial baseline for every active connection and rebuilt the
canonical store at or after the latest provider watermark.
-The dashboard workload selector path and the dashboard runtime that consumes it
+The Workloads selector path and the Workloads runtime that consumes it
are now part of the protected performance surface rather than proof-only
context. Future hot-path filter/group/sort/windowing changes must route through
-the explicit dashboard performance proof policy in the subsystem registry.
+the explicit Workloads performance proof policy in the subsystem registry.
Route-backed workload `resource` focus on that hot path is contextual state
only, not inferred filter state: opening or closing an inline drawer must not
invent, retain, or clear `agent` or node-scope filters unless those filters
@@ -502,15 +498,15 @@ That same hot path now also owns dashboard freshness discipline. Supported
unified-resource dashboard reads may hydrate from REST for first paint, but
once websocket `state.resources` is available they must consume that canonical
live snapshot directly instead of turning each websocket update into a second
-REST fetch. Dashboard trend loading must also key off stable target identity
+REST fetch. Route-owned trend loading must also key off stable target identity
and selected range only; reconciled resource snapshots that do not change the
-effective target set must not trigger duplicate infrastructure or storage
-chart requests.
+effective target set must not trigger duplicate infrastructure or storage chart
+requests.
That same protected metrics-store boundary now also owns selected-series batch
-queries. Compact dashboard routes that request only CPU/memory or only
-storage `used`/`avail` capacity must keep that metric-type filter all the way
-through `pkg/metrics/store.go` instead of fetching every series for every
-resource and discarding the extra payload in higher layers.
+queries. Compact route consumers that request only CPU/memory or only storage
+`used`/`avail` capacity must keep that metric-type filter all the way through
+`pkg/metrics/store.go` instead of fetching every series for every resource and
+discarding the extra payload in higher layers.
That same protected workload-chart hot path now also owns rendered-metric
budgeting. `internal/api/router.go` may parallelize VM, container, pod, and
docker-container workload batch reads, but `/api/charts/workloads` and
@@ -566,7 +562,7 @@ rows and infrastructure resource rows must expose summary-linked activity
through the shared `data-summary-row-active` marker and let the shared frontend
primitive render the emphasis, instead of layering lane-local row-fill classes
that diverge across pages or wash out inline metric bars.
-`frontend-modern/src/components/Dashboard/useDashboardSelectionState.ts` must
+`frontend-modern/src/components/Workloads/useWorkloadSelectionState.ts` must
write workload selection back into the workloads route through the shared
same-path route-state scheduler, but the actual shell-position handoff for
query-only row focus must go through `frontend-modern/src/utils/appShellScrollRestoration.ts`
@@ -619,23 +615,22 @@ must include API-backed systems such as top-level TrueNAS appliances through
the shared `isAgentFacetInfrastructureResource(...)` helper instead of a local
`resource.type` branch, so the summary poll/cache path stays on one canonical
infrastructure selector contract.
-That same protected dashboard hot path now includes storage trend loading too.
-`frontend-modern/src/hooks/useDashboardTrends.ts` and
-`internal/api/router.go` must keep dashboard storage trends on one compact
-`/api/charts/storage-summary` request backed by
-`GetStorageMetricsForChartBatch(...)`, so the dashboard does not pull the full
-storage-page `/api/storage-charts` payload or reopen an N+1 per-pool
-`/api/metrics-store/history` fan-out just to compute the shared 24-hour
-storage capacity delta.
-That same dashboard shell boundary also owns empty-state action routing in
-`frontend-modern/src/components/Dashboard/DashboardStateCards.tsx`. When the
-dashboard has no connected infrastructure, the CTA must hand operators
+That same protected hot path keeps storage trend loading route-owned after the
+dashboard overview retirement. `internal/api/router.go` must continue serving
+the compact `/api/charts/storage-summary` request backed by
+`GetStorageMetricsForChartBatch(...)` for the surfaces that still own storage
+summary presentation, but no deleted dashboard trend hook may reopen the full
+storage-page `/api/storage-charts` payload or an N+1 per-pool
+`/api/metrics-store/history` fan-out.
+That same Workloads shell boundary also owns empty-state action routing in
+`frontend-modern/src/components/Workloads/WorkloadsStateCards.tsx`. When the
+Workloads route has no connected infrastructure, the CTA must hand operators
directly to the canonical infrastructure install route via
`buildInfrastructureWorkspacePath('install')` instead of bouncing through a
generic settings landing page.
That workload route now also treats readiness as a route-owned contract instead
-of a raw websocket proxy signal: `frontend-modern/src/components/Dashboard/Dashboard.tsx`
-and `frontend-modern/src/components/Dashboard/useDashboardState.ts` must keep
+of a raw websocket proxy signal: `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`
+and `frontend-modern/src/components/Workloads/useWorkloadsState.ts` must keep
filters, stats, and table visibility driven by the workload route's own
REST-backed health so websocket churn does not hide already-fetched workloads
or swap the protected hot path into a false disconnected shell. The first
@@ -657,47 +652,48 @@ served stale mixed-cadence chart shapes after the backend timeline model has
already been corrected.
stay on one ordered index scan plus Go-side bucket aggregation rather than
forcing SQLite to `GROUP BY` computed buckets through a temp B-tree on the
-fleet-scale dashboard path.
+fleet-scale workload path.
That runtime is now intentionally split by concern:
-`frontend-modern/src/components/Dashboard/useDashboardState.ts` owns
-top-level dashboard orchestration, workload loading, and composition across
-the canonical dashboard owners, while
-`frontend-modern/src/components/Dashboard/useDashboardControlsState.ts`
+`frontend-modern/src/components/Workloads/useWorkloadsState.ts` owns
+top-level Workloads orchestration, workload loading, and composition across
+the canonical Workloads owners, while
+`frontend-modern/src/components/Workloads/useWorkloadsControlsState.ts`
owns persistent control defaults, keyboard-reset semantics, sort/search/tag
behavior, column visibility, and summary display preferences, while
-`frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts`
+`frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts`
owns grouped workload derivation, summary fallbacks, parent-node mapping,
and grouped/windowed table math, while
-`frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts`
+`frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts`
owns grouped workload viewport synchronization and the scroll/resize listener
lifecycle, while
-`frontend-modern/src/components/Dashboard/useDashboardGuestMetadataState.ts`
+`frontend-modern/src/components/Workloads/useWorkloadGuestMetadataState.ts`
owns guest metadata cache persistence, optimistic custom-URL updates,
org-scope switching, and metadata refresh, and
-`frontend-modern/src/components/Dashboard/useDashboardWorkloadRouteState.ts`
+`frontend-modern/src/components/Workloads/useWorkloadRouteState.ts`
owns workload-route synchronization, deep-link normalization, and route-scoped
-filter contracts. Future dashboard hot-path changes must extend through those
-owners instead of accreting back into `frontend-modern/src/components/Dashboard/Dashboard.tsx`.
+filter contracts. Future workload hot-path changes must extend through those
+owners within the Workloads surface, and new overview-route work must not
+accrete back into `frontend-modern/src/components/Workloads/WorkloadsSurface.tsx`.
That same route-owned filter contract now also includes canonical workload
-`platform` scoping for API-backed runtimes. Dashboard URL-sync, filter-option
+`platform` scoping for API-backed runtimes. Workloads URL-sync, filter-option
assembly, and workload drill-down routes must preserve
`platform=` for surfaces such as TrueNAS app-containers,
while treating host or cluster identity as secondary scope instead of
collapsing those routes back to generic agent-only semantics. The derived
workload hot path must also tolerate transient async route/data gaps by
treating missing filtered-workload collections as empty until the route and
-resource snapshots converge, rather than crashing the dashboard between sync
+resource snapshots converge, rather than crashing Workloads between sync
phases.
That same workload hot path also owns the split between canonical
app-container routing and Docker-only actions. `frontend-modern/src/hooks/useWorkloads.ts`,
-`frontend-modern/src/components/Dashboard/workloadTopology.ts`, and
-`frontend-modern/src/components/Dashboard/useGuestRowState.ts` must preserve a
+`frontend-modern/src/components/Workloads/workloadTopology.ts`, and
+`frontend-modern/src/components/Workloads/useGuestRowState.ts` must preserve a
canonical app-container navigation path while keeping Docker runtime action
-identifiers explicit. Discovery affordances on the dashboard drawer must follow
+identifiers explicit. Discovery affordances on the Workloads drawer must follow
the canonical `discoveryTarget` contract, not generic app-container host
fallbacks. TrueNAS app-containers may reuse runtime metadata such as image and
runtime strings, but they must not inherit Docker-only update affordances or
-agent-only Discovery tabs on the dashboard row path unless the unified
+agent-only Discovery tabs on the Workloads row path unless the unified
resource contract explicitly supplies discovery ownership.
That same row-and-selection boundary also requires canonical app-container
identity to stay intact on the workload surface. `/workloads` rows, deep links,
@@ -729,50 +725,50 @@ When a row is only known through an agent or container runtime, the table must
prefer reported OS/appliance identity before falling back to Docker/runtime
capability labels.
That derived workload owner now also routes grouped row windowing through
-`frontend-modern/src/components/Dashboard/useGroupedTableWindowing.ts`, which
+`frontend-modern/src/components/Workloads/useGroupedTableWindowing.ts`, which
owns row-window thresholds, overscan behavior, reveal-index clamping, and
-per-group visible-slice derivation. Future dashboard table windowing changes
+per-group visible-slice derivation. Future Workloads table windowing changes
must extend through that hook instead of rebuilding scroll math or mounted-row
-budgets inline inside `frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts`.
+budgets inline inside `frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts`.
Viewport-driven grouped table synchronization now also routes through
-`frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts`,
-which owns the dashboard table body measurement and the scroll/resize listener
+`frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts`,
+which owns the Workloads table body measurement and the scroll/resize listener
lifecycle. Future viewport sync changes must extend through that hook rather
than rebuilding browser-event wiring or table-body geometry reads inside
-`frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts`.
-The dashboard guest-row path now follows the same pattern: the render shell
-stays in `frontend-modern/src/components/Dashboard/GuestRow.tsx`, tooltip-backed
-cell presentation lives in `frontend-modern/src/components/Dashboard/GuestRowCells.tsx`,
+`frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts`.
+The workload guest-row path now follows the same pattern: the render shell
+stays in `frontend-modern/src/components/Workloads/GuestRow.tsx`, tooltip-backed
+cell presentation lives in `frontend-modern/src/components/Workloads/GuestRowCells.tsx`,
and the canonical row contract and per-row hot-path derivations live in
-`frontend-modern/src/components/Dashboard/guestRowModel.tsx` and
-`frontend-modern/src/components/Dashboard/useGuestRowState.ts`. Future row
+`frontend-modern/src/components/Workloads/guestRowModel.tsx` and
+`frontend-modern/src/components/Workloads/useGuestRowState.ts`. Future row
identity, column, cell-tooltip, anomaly-correlation, and link-state changes
must extend through those owners instead of rebuilding row-local state inside
the shell.
That per-row link state now also consumes the shared
`frontend-modern/src/routing/resourceLinks.ts` workload-to-infrastructure
-helper instead of a dashboard-local routing shim. Future infrastructure-link
-changes for dashboard rows must extend through the shared routing owner rather
+helper instead of a workload-local routing shim. Future infrastructure-link
+changes for workload rows must extend through the shared routing owner rather
than recreating feature-local path builders.
That shell now also routes tag-dot rendering through the shared
`frontend-modern/src/components/shared/TagBadges.tsx` primitive instead of
-keeping a dashboard-local badge helper. Future guest-row tag presentation
+keeping a workload-local badge helper. Future guest-row tag presentation
changes must extend through that shared owner rather than reintroducing a
-dashboard-only tag-badge variant.
-The dashboard guest drawer now follows that same ownership rule: the shell
-stays in `frontend-modern/src/components/Dashboard/GuestDrawer.tsx`, the
+workload-only tag-badge variant.
+The Workloads guest drawer now follows that same ownership rule: the shell
+stays in `frontend-modern/src/components/Workloads/GuestDrawer.tsx`, the
overview card surface lives in
-`frontend-modern/src/components/Dashboard/GuestDrawerOverview.tsx`, and
+`frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx`, and
drawer-local normalization, backup/tag formatting, discovery identity wiring,
and workload-derived navigation state live in
-`frontend-modern/src/components/Dashboard/guestDrawerModel.ts` and
-`frontend-modern/src/components/Dashboard/useGuestDrawerState.ts`. Future
+`frontend-modern/src/components/Workloads/guestDrawerModel.ts` and
+`frontend-modern/src/components/Workloads/useGuestDrawerState.ts`. Future
drawer runtime and overview-surface changes must extend through those owners
instead of adding more mixed state and helper drift back into the shell.
That drawer state now also consumes the same shared
`frontend-modern/src/routing/resourceLinks.ts` workload-to-infrastructure
helper, so row and drawer navigation stay aligned without a second
-dashboard-local link-mapping file.
+workload-local link-mapping file.
The shared infrastructure mapper hot path now stays intentionally narrow:
`frontend-modern/src/components/Infrastructure/resourceDetailMappers.ts`
continues to own sensor-label presentation and hot-path host/agent projection,
@@ -790,86 +786,86 @@ service-model helpers, while
stays a thin render shell. Future running-task visibility changes must extend
through the shared model and accepted performance proof file instead of adding
per-row PBS status parsing or inline job scans in the table render path.
-The dashboard disk list now follows the same pattern: the shell stays in
-`frontend-modern/src/components/Dashboard/DiskList.tsx`, while disk-row
+The Workloads disk list now follows the same pattern: the shell stays in
+`frontend-modern/src/components/Workloads/DiskList.tsx`, while disk-row
presentation derivations and fallback tooltip/runtime wiring live in
-`frontend-modern/src/components/Dashboard/diskListModel.ts` and
-`frontend-modern/src/components/Dashboard/useDiskListState.ts`. Future disk
+`frontend-modern/src/components/Workloads/diskListModel.ts` and
+`frontend-modern/src/components/Workloads/useDiskListState.ts`. Future disk
usage math, threshold-color routing, and fallback handling must extend
through those owners instead of accreting back into the shell.
-The dashboard filter now follows that same ownership rule: the shell
-stays in `frontend-modern/src/components/Dashboard/DashboardFilter.tsx`, while
+The Workloads filter now follows that same ownership rule: the shell
+stays in `frontend-modern/src/components/Workloads/WorkloadsFilter.tsx`, while
toolbar defaults, active-filter counting, and reset semantics live in
-`frontend-modern/src/components/Dashboard/dashboardFilterModel.ts` and
-`frontend-modern/src/components/Dashboard/useDashboardFilterState.ts`.
-Dashboard table-mode controls must also keep their accessible group name aligned
+`frontend-modern/src/components/Workloads/workloadsFilterModel.ts` and
+`frontend-modern/src/components/Workloads/useWorkloadsFilterState.ts`.
+Workloads table-mode controls must also keep their accessible group name aligned
with the shared table presentation contract by using `Group by` for the
grouped/list selector instead of reintroducing local `Group By` casing or
platform-specific cluster wording. Dense workload toolbar variants must keep
that same row wrap-capable so optional runtime, chart, column, and reset
controls remain reachable on desktop instead of forcing a single no-wrap row
that clips trailing actions.
-The dashboard-owned filter-config assembly now lives in
-`frontend-modern/src/components/Dashboard/useDashboardState.ts`, so future
+The Workloads-owned filter-config assembly now lives in
+`frontend-modern/src/components/Workloads/useWorkloadsState.ts`, so future
filter runtime changes must extend through those owners instead of
-reintroducing dashboard-local state, reset drift, or inline config assembly
+reintroducing workload-local state, reset drift, or inline config assembly
into the shell.
Workload type option labels are part of that filter-config model ownership:
-`DashboardFilter.tsx` must render the exported workload type option catalog
+`WorkloadsFilter.tsx` must render the exported workload type option catalog
instead of embedding its own `System containers` / `App containers` wording in
the shell.
The dashboard threshold slider now follows that same pattern: the shell stays
-in `frontend-modern/src/components/Dashboard/ThresholdSlider.tsx`, while
+in `frontend-modern/src/components/Workloads/ThresholdSlider.tsx`, while
metric-type text and fill presentation live in
`frontend-modern/src/utils/thresholdSliderPresentation.ts`, while
slider bounds math, thumb-position transforms, and title/label derivations
-live in `frontend-modern/src/components/Dashboard/thresholdSliderModel.ts`
+live in `frontend-modern/src/components/Workloads/thresholdSliderModel.ts`
and drag scroll-lock lifecycle lives in
-`frontend-modern/src/components/Dashboard/useThresholdSliderState.ts`.
+`frontend-modern/src/components/Workloads/useThresholdSliderState.ts`.
Future slider runtime changes must extend through those owners instead of
reintroducing mixed drag state, type-color formatting, and presentation logic
into the shell.
The dashboard stacked disk bar now follows that same pattern: the shell stays
-in `frontend-modern/src/components/Dashboard/StackedDiskBar.tsx`, while
+in `frontend-modern/src/components/Workloads/StackedDiskBar.tsx`, while
disk-capacity math, segment and tooltip derivation, max-disk labeling, and
mode-specific presentation live in
-`frontend-modern/src/components/Dashboard/stackedDiskBarModel.ts` and
+`frontend-modern/src/components/Workloads/stackedDiskBarModel.ts` and
resize-observer plus tooltip lifecycle live in
-`frontend-modern/src/components/Dashboard/useStackedDiskBarState.ts`.
+`frontend-modern/src/components/Workloads/useStackedDiskBarState.ts`.
Future disk-bar runtime changes must extend through those owners instead of
reintroducing mixed resize state and presentation branching into the shell.
The dashboard stacked memory bar now follows that same pattern: the shell
-stays in `frontend-modern/src/components/Dashboard/StackedMemoryBar.tsx`,
+stays in `frontend-modern/src/components/Workloads/StackedMemoryBar.tsx`,
while memory-capacity math, balloon/swap tooltip derivation, anomaly label
presentation, and sublabel-fit logic live in
-`frontend-modern/src/components/Dashboard/stackedMemoryBarModel.ts` and
+`frontend-modern/src/components/Workloads/stackedMemoryBarModel.ts` and
resize-observer plus tooltip lifecycle live in
-`frontend-modern/src/components/Dashboard/useStackedMemoryBarState.ts`.
+`frontend-modern/src/components/Workloads/useStackedMemoryBarState.ts`.
Future memory-bar runtime changes must extend through those owners instead of
reintroducing mixed resize state, balloon branching, and tooltip shaping into
the shell.
The dashboard metric bar now follows that same pattern: the shell stays in
-`frontend-modern/src/components/Dashboard/MetricBar.tsx`, while width,
+`frontend-modern/src/components/Workloads/MetricBar.tsx`, while width,
show-label, sublabel-fit, and threshold-color derivation live in
-`frontend-modern/src/components/Dashboard/metricBarModel.ts` and
+`frontend-modern/src/components/Workloads/metricBarModel.ts` and
resize-observer lifecycle lives in
-`frontend-modern/src/components/Dashboard/useMetricBarState.ts`. Future
+`frontend-modern/src/components/Workloads/useMetricBarState.ts`. Future
metric-bar runtime changes must extend through those owners instead of
reintroducing mixed resize state and label-fit logic into the shell.
The dashboard enhanced CPU bar now follows that same pattern: the shell stays
-in `frontend-modern/src/components/Dashboard/EnhancedCPUBar.tsx`, while usage
+in `frontend-modern/src/components/Workloads/EnhancedCPUBar.tsx`, while usage
formatting, anomaly presentation, tooltip load-average formatting, and
threshold-driven label state live in
-`frontend-modern/src/components/Dashboard/enhancedCpuBarModel.ts` and
+`frontend-modern/src/components/Workloads/enhancedCpuBarModel.ts` and
tooltip lifecycle lives in
-`frontend-modern/src/components/Dashboard/useEnhancedCPUBarState.ts`. Future
+`frontend-modern/src/components/Workloads/useEnhancedCPUBarState.ts`. Future
CPU-bar runtime changes must extend through those owners instead of
reintroducing mixed tooltip state and formatting logic into the shell.
The unified resource table hot path is now also governed as explicit
performance-owned runtime, with shared ownership against the unified-resource
consumer boundary. The remaining performance work is no longer top-level
-ownership ambiguity on the main dashboard or infrastructure tables.
+ownership ambiguity on the main Infrastructure or Workloads tables.
The table's reactive runtime, grouping, and row-windowing owner now lives in
`frontend-modern/src/components/Infrastructure/useUnifiedResourceTableState.ts`,
while pure table-state derivation, service sorting, sort-cycle policy, and
@@ -975,7 +971,7 @@ The shared workloads-link helper used by the resource drawer and table now
also routes its Kubernetes-cluster fallback through the same preferred
resource display contract, so navigation context does not leak raw
`displayName` values for governed clusters.
-That same workloads-link path and the dashboard workload projection now also
+That same workloads-link path and the workload projection now also
share the canonical cluster-name helpers in the shared agent-resource layer,
so route labels, pod grouping, and cluster-name fetch keys keep using the
same source of truth instead of rebuilding the `clusterName`/`context`/
@@ -1084,7 +1080,7 @@ doing range selection and fallback. Feature-local polling loops or browser-side
disk ring buffers are forbidden because they duplicate live sampling work and
drift out of sync with the governed history timeline.
That same hot-path ownership now also requires lazy-load-safe websocket
-consumption. `frontend-modern/src/components/Dashboard/useDashboardState.ts`
+consumption. `frontend-modern/src/components/Workloads/useWorkloadsState.ts`
may read connection and alert state only through
`frontend-modern/src/contexts/appRuntime.ts`; it must not import `@/App` or
create a reverse dependency into the root shell just to read websocket state.
@@ -1093,15 +1089,15 @@ Shared shells may consume the small `/api/license/runtime-capabilities`
contract for feature truth, but commercial demo routes stay hidden and the
browser must not keep retrying `/api/license/commercial-posture`,
`/api/license/entitlements`, `/auth/license-purchase-start`, or other hidden
-commercial endpoints from performance-sensitive settings or dashboard shells.
-Dashboard and infrastructure summary consumers now also keep null-tolerant read
+commercial endpoints from performance-sensitive settings or route shells.
+Workloads and infrastructure summary consumers now also keep null-tolerant read
models on the shared hot path. Guest rows, stacked bars, anomaly summaries, and
resource detail mappers may accept partial platform metadata or undefined
ratios, but they must normalize those values once in the shared model layer
instead of scattering non-null assertions or per-component count coercion
-through the dashboard runtime.
+through the Workloads runtime.
That same workload-table hot path now also owns a single width contract.
-`frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx`,
+`frontend-modern/src/components/Workloads/WorkloadsTable.tsx`,
`WorkloadTableHeader.tsx`, `GuestRow.tsx`, and `guestRowModel.tsx` must remain
the canonical owners for desktop and mobile workload column sizing. Global CSS
must not reintroduce competing `.workload-table [data-workload-col=β¦]` width
diff --git a/docs/release-control/v6/internal/subsystems/registry.json b/docs/release-control/v6/internal/subsystems/registry.json
index 44dc240df8..79ca212144 100644
--- a/docs/release-control/v6/internal/subsystems/registry.json
+++ b/docs/release-control/v6/internal/subsystems/registry.json
@@ -1320,7 +1320,6 @@
"exact_files": [
"frontend-modern/src/components/Alerts/__tests__/BulkEditDialog.test.tsx",
"frontend-modern/src/components/Alerts/__tests__/InvestigateAlertButton.test.tsx",
- "frontend-modern/src/components/Alerts/__tests__/RecentAlertsPanel.test.tsx",
"frontend-modern/src/components/Alerts/__tests__/ThresholdsTable.test.tsx",
"frontend-modern/src/components/Alerts/EmailProviderSelect.test.tsx",
"frontend-modern/src/components/Alerts/ResourceTable.test.tsx",
@@ -2990,27 +2989,11 @@
"frontend-modern/src/components/SetupWizard/SetupCompletionPreview.tsx",
"frontend-modern/src/components/SetupWizard/SetupWizard.tsx",
"frontend-modern/src/components/Toast/Toast.tsx",
- "frontend-modern/src/features/dashboardOverview/ActionRequiredPanel.tsx",
- "frontend-modern/src/features/dashboardOverview/DashboardCustomizer.tsx",
- "frontend-modern/src/features/dashboardOverview/dashboardPulseBriefModel.ts",
- "frontend-modern/src/features/dashboardOverview/estateSummaryModel.ts",
- "frontend-modern/src/features/dashboardOverview/EstateSummaryPanel.tsx",
- "frontend-modern/src/features/dashboardOverview/index.ts",
- "frontend-modern/src/features/dashboardOverview/KPIStrip.tsx",
- "frontend-modern/src/features/dashboardOverview/ProblemResourcesTable.tsx",
- "frontend-modern/src/features/dashboardOverview/PulseBriefPanel.tsx",
- "frontend-modern/src/features/dashboardOverview/TrendCharts.tsx",
- "frontend-modern/src/features/dashboardOverview/useDashboardPulseBrief.ts",
"frontend-modern/src/hooks/createNonSuspendingQuery.ts",
"frontend-modern/src/index.css",
"frontend-modern/src/pages/Operations.tsx",
"frontend-modern/src/stores/aiChat.ts",
"frontend-modern/src/utils/aiSettingsPresentation.ts",
- "frontend-modern/src/utils/dashboardEmptyStatePresentation.ts",
- "frontend-modern/src/utils/dashboardGuestPresentation.ts",
- "frontend-modern/src/utils/dashboardKpiPresentation.ts",
- "frontend-modern/src/utils/dashboardMetricPresentation.ts",
- "frontend-modern/src/utils/dashboardTrendPresentation.ts",
"frontend-modern/src/utils/diagnosticsPresentation.ts",
"frontend-modern/src/utils/discoveryPresentation.ts",
"frontend-modern/src/utils/emptyStatePresentation.ts",
@@ -3032,7 +3015,9 @@
"frontend-modern/src/utils/toast.ts",
"frontend-modern/src/utils/typeColumnPresentation.ts",
"frontend-modern/src/utils/updatesPresentation.ts",
- "frontend-modern/src/utils/upgradeNavigation.ts"
+ "frontend-modern/src/utils/upgradeNavigation.ts",
+ "frontend-modern/src/utils/workloadEmptyStatePresentation.ts",
+ "frontend-modern/src/utils/workloadGuestPresentation.ts"
],
"verification": {
"allow_same_subsystem_tests": false,
@@ -3214,24 +3199,18 @@
]
},
{
- "id": "dashboard-presentation-helpers",
- "label": "dashboard presentation helper proof",
+ "id": "workload-presentation-helpers",
+ "label": "workload presentation helper proof",
"match_prefixes": [],
"match_files": [
- "frontend-modern/src/utils/dashboardEmptyStatePresentation.ts",
- "frontend-modern/src/utils/dashboardGuestPresentation.ts",
- "frontend-modern/src/utils/dashboardKpiPresentation.ts",
- "frontend-modern/src/utils/dashboardMetricPresentation.ts",
- "frontend-modern/src/utils/dashboardTrendPresentation.ts"
+ "frontend-modern/src/utils/workloadEmptyStatePresentation.ts",
+ "frontend-modern/src/utils/workloadGuestPresentation.ts"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
- "frontend-modern/src/utils/__tests__/dashboardEmptyStatePresentation.test.ts",
- "frontend-modern/src/utils/__tests__/dashboardGuestPresentation.test.ts",
- "frontend-modern/src/utils/__tests__/dashboardKpiPresentation.test.ts",
- "frontend-modern/src/utils/__tests__/dashboardMetricPresentation.test.ts",
- "frontend-modern/src/utils/__tests__/dashboardTrendPresentation.test.ts"
+ "frontend-modern/src/utils/__tests__/workloadEmptyStatePresentation.test.ts",
+ "frontend-modern/src/utils/__tests__/workloadGuestPresentation.test.ts"
]
},
{
@@ -3256,6 +3235,7 @@
"match_files": [
"frontend-modern/src/components/Toast/Toast.tsx",
"frontend-modern/src/utils/emptyStatePresentation.ts",
+ "frontend-modern/src/utils/problemResourcePresentation.ts",
"frontend-modern/src/utils/semanticTonePresentation.ts",
"frontend-modern/src/utils/toast.ts",
"frontend-modern/src/utils/typeColumnPresentation.ts"
@@ -3266,6 +3246,7 @@
"frontend-modern/src/components/shared/TypeColumn.guardrails.test.ts",
"frontend-modern/src/components/Toast/__tests__/Toast.test.tsx",
"frontend-modern/src/utils/__tests__/emptyStatePresentation.test.ts",
+ "frontend-modern/src/utils/__tests__/problemResourcePresentation.test.ts",
"frontend-modern/src/utils/__tests__/semanticTonePresentation.test.ts",
"frontend-modern/src/utils/__tests__/typeColumnPresentation.test.ts"
]
@@ -3393,37 +3374,6 @@
"frontend-modern/src/components/Infrastructure/__tests__/ResourceDetailDrawer.history.test.tsx"
]
},
- {
- "id": "dashboard-overview-feature-surface",
- "label": "dashboard overview feature proof",
- "match_prefixes": [],
- "match_files": [
- "frontend-modern/src/features/dashboardOverview/ActionRequiredPanel.tsx",
- "frontend-modern/src/features/dashboardOverview/DashboardCustomizer.tsx",
- "frontend-modern/src/features/dashboardOverview/dashboardPulseBriefModel.ts",
- "frontend-modern/src/features/dashboardOverview/estateSummaryModel.ts",
- "frontend-modern/src/features/dashboardOverview/EstateSummaryPanel.tsx",
- "frontend-modern/src/features/dashboardOverview/index.ts",
- "frontend-modern/src/features/dashboardOverview/KPIStrip.tsx",
- "frontend-modern/src/features/dashboardOverview/ProblemResourcesTable.tsx",
- "frontend-modern/src/features/dashboardOverview/PulseBriefPanel.tsx",
- "frontend-modern/src/features/dashboardOverview/TrendCharts.tsx",
- "frontend-modern/src/features/dashboardOverview/useDashboardPulseBrief.ts",
- "frontend-modern/src/utils/problemResourcePresentation.ts"
- ],
- "allow_same_subsystem_tests": false,
- "test_prefixes": [],
- "exact_files": [
- "frontend-modern/src/features/dashboardOverview/__tests__/dashboardPulseBriefModel.test.ts",
- "frontend-modern/src/features/dashboardOverview/__tests__/KPIStrip.test.tsx",
- "frontend-modern/src/features/dashboardOverview/__tests__/ProblemResourcesTable.test.tsx",
- "frontend-modern/src/features/dashboardOverview/__tests__/TrendCharts.test.tsx",
- "frontend-modern/src/pages/__tests__/DashboardPage.test.tsx",
- "frontend-modern/src/utils/__tests__/frontendResourceTypeBoundaries.test.ts",
- "frontend-modern/src/utils/__tests__/problemResourcePresentation.test.ts",
- "frontend-modern/src/utils/__tests__/typeColumnPresentation.test.ts"
- ]
- },
{
"id": "first-session-runtime-and-preview",
"label": "first-session runtime and preview proof",
@@ -4155,58 +4105,6 @@
"pkg/metrics/"
],
"owned_files": [
- "frontend-modern/src/components/Dashboard/Dashboard.tsx",
- "frontend-modern/src/components/Dashboard/DashboardFilter.tsx",
- "frontend-modern/src/components/Dashboard/dashboardFilterModel.ts",
- "frontend-modern/src/components/Dashboard/dashboardSelectionModel.ts",
- "frontend-modern/src/components/Dashboard/DashboardStateCards.tsx",
- "frontend-modern/src/components/Dashboard/DashboardStatsStrip.tsx",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadFilterConfigModel.ts",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadRouteModel.ts",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadRouteStateModel.ts",
- "frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadUrlSyncModel.ts",
- "frontend-modern/src/components/Dashboard/DiskList.tsx",
- "frontend-modern/src/components/Dashboard/diskListModel.ts",
- "frontend-modern/src/components/Dashboard/EnhancedCPUBar.tsx",
- "frontend-modern/src/components/Dashboard/enhancedCpuBarModel.ts",
- "frontend-modern/src/components/Dashboard/GuestDrawer.tsx",
- "frontend-modern/src/components/Dashboard/guestDrawerModel.ts",
- "frontend-modern/src/components/Dashboard/GuestDrawerOverview.tsx",
- "frontend-modern/src/components/Dashboard/GuestRow.tsx",
- "frontend-modern/src/components/Dashboard/GuestRowCells.tsx",
- "frontend-modern/src/components/Dashboard/guestRowModel.tsx",
- "frontend-modern/src/components/Dashboard/MetricBar.tsx",
- "frontend-modern/src/components/Dashboard/metricBarModel.ts",
- "frontend-modern/src/components/Dashboard/StackedDiskBar.tsx",
- "frontend-modern/src/components/Dashboard/stackedDiskBarModel.ts",
- "frontend-modern/src/components/Dashboard/StackedMemoryBar.tsx",
- "frontend-modern/src/components/Dashboard/stackedMemoryBarModel.ts",
- "frontend-modern/src/components/Dashboard/ThresholdSlider.tsx",
- "frontend-modern/src/components/Dashboard/thresholdSliderModel.ts",
- "frontend-modern/src/components/Dashboard/useDashboardControlsState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardFilterState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardGuestMetadataState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardSelectionState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadFilterOptions.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadRouteState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadUrlSync.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts",
- "frontend-modern/src/components/Dashboard/useDiskListState.ts",
- "frontend-modern/src/components/Dashboard/useEnhancedCPUBarState.ts",
- "frontend-modern/src/components/Dashboard/useGroupedTableWindowing.ts",
- "frontend-modern/src/components/Dashboard/useGuestDrawerState.ts",
- "frontend-modern/src/components/Dashboard/useGuestRowState.ts",
- "frontend-modern/src/components/Dashboard/useMetricBarState.ts",
- "frontend-modern/src/components/Dashboard/useStackedDiskBarState.ts",
- "frontend-modern/src/components/Dashboard/useStackedMemoryBarState.ts",
- "frontend-modern/src/components/Dashboard/useThresholdSliderState.ts",
- "frontend-modern/src/components/Dashboard/WorkloadPanel.tsx",
- "frontend-modern/src/components/Dashboard/workloadSelectors.ts",
- "frontend-modern/src/components/Dashboard/WorkloadTableHeader.tsx",
- "frontend-modern/src/components/Dashboard/workloadTopology.ts",
"frontend-modern/src/components/Infrastructure/infrastructureSelectors.ts",
"frontend-modern/src/components/Infrastructure/InfrastructureSummary.tsx",
"frontend-modern/src/components/Infrastructure/infrastructureSummaryModel.ts",
@@ -4221,7 +4119,59 @@
"frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts",
"frontend-modern/src/components/Infrastructure/useUnifiedResourceTableState.ts",
"frontend-modern/src/components/Infrastructure/useUnifiedResourceTableViewportSync.ts",
+ "frontend-modern/src/components/Workloads/DiskList.tsx",
+ "frontend-modern/src/components/Workloads/diskListModel.ts",
+ "frontend-modern/src/components/Workloads/EnhancedCPUBar.tsx",
+ "frontend-modern/src/components/Workloads/enhancedCpuBarModel.ts",
+ "frontend-modern/src/components/Workloads/GuestDrawer.tsx",
+ "frontend-modern/src/components/Workloads/guestDrawerModel.ts",
+ "frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx",
+ "frontend-modern/src/components/Workloads/GuestRow.tsx",
+ "frontend-modern/src/components/Workloads/GuestRowCells.tsx",
+ "frontend-modern/src/components/Workloads/guestRowModel.tsx",
+ "frontend-modern/src/components/Workloads/MetricBar.tsx",
+ "frontend-modern/src/components/Workloads/metricBarModel.ts",
+ "frontend-modern/src/components/Workloads/StackedDiskBar.tsx",
+ "frontend-modern/src/components/Workloads/stackedDiskBarModel.ts",
+ "frontend-modern/src/components/Workloads/StackedMemoryBar.tsx",
+ "frontend-modern/src/components/Workloads/stackedMemoryBarModel.ts",
+ "frontend-modern/src/components/Workloads/ThresholdSlider.tsx",
+ "frontend-modern/src/components/Workloads/thresholdSliderModel.ts",
+ "frontend-modern/src/components/Workloads/useDiskListState.ts",
+ "frontend-modern/src/components/Workloads/useEnhancedCPUBarState.ts",
+ "frontend-modern/src/components/Workloads/useGroupedTableWindowing.ts",
+ "frontend-modern/src/components/Workloads/useGuestDrawerState.ts",
+ "frontend-modern/src/components/Workloads/useGuestRowState.ts",
+ "frontend-modern/src/components/Workloads/useMetricBarState.ts",
+ "frontend-modern/src/components/Workloads/useStackedDiskBarState.ts",
+ "frontend-modern/src/components/Workloads/useStackedMemoryBarState.ts",
+ "frontend-modern/src/components/Workloads/useThresholdSliderState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadFilterOptions.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadGuestMetadataState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadRouteState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsControlsState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadSelectionState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsFilterState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadUrlSync.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts",
+ "frontend-modern/src/components/Workloads/workloadFilterConfigModel.ts",
+ "frontend-modern/src/components/Workloads/WorkloadPanel.tsx",
+ "frontend-modern/src/components/Workloads/workloadRouteModel.ts",
+ "frontend-modern/src/components/Workloads/workloadRouteStateModel.ts",
+ "frontend-modern/src/components/Workloads/workloadSelectionModel.ts",
+ "frontend-modern/src/components/Workloads/workloadSelectors.ts",
+ "frontend-modern/src/components/Workloads/WorkloadsFilter.tsx",
+ "frontend-modern/src/components/Workloads/workloadsFilterModel.ts",
+ "frontend-modern/src/components/Workloads/WorkloadsStateCards.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadsStatsStrip.tsx",
"frontend-modern/src/components/Workloads/WorkloadsSummary.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadsSurface.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadsTable.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadTableHeader.tsx",
+ "frontend-modern/src/components/Workloads/workloadTopology.ts",
+ "frontend-modern/src/components/Workloads/workloadUrlSyncModel.ts",
"frontend-modern/src/pages/Workloads.tsx",
"frontend-modern/src/utils/thresholdSliderPresentation.ts",
"frontend-modern/src/utils/throughputPresentation.ts",
@@ -4233,28 +4183,28 @@
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
- "frontend-modern/src/components/Dashboard/__tests__/Dashboard.performance.contract.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/DashboardFilter.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardSelectionModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadFilterConfigModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadRouteModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadRouteStateModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadUrlSyncModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/DiskList.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/EnhancedCPUBar.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/StackedDiskBar.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useDashboardFilterState.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/useDashboardSelectionState.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/useDashboardWorkloadViewportSync.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useEnhancedCPUBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useGroupedTableWindowing.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/useMetricBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useStackedDiskBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useStackedMemoryBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useThresholdSliderState.test.ts",
- "frontend-modern/src/components/Dashboard/MetricBar.test.tsx",
- "frontend-modern/src/components/Dashboard/StackedMemoryBar.test.tsx",
- "frontend-modern/src/components/Dashboard/ThresholdSlider.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/DiskList.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/EnhancedCPUBar.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/StackedDiskBar.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useEnhancedCPUBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useGroupedTableWindowing.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useMetricBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useStackedDiskBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useStackedMemoryBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useThresholdSliderState.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useWorkloadSelectionState.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useWorkloadsFilterState.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useWorkloadViewportSync.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/workloadFilterConfigModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadRouteModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadRouteStateModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadSelectionModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/WorkloadsFilter.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/workloadUrlSyncModel.test.ts",
+ "frontend-modern/src/components/Workloads/MetricBar.test.tsx",
+ "frontend-modern/src/components/Workloads/StackedMemoryBar.test.tsx",
+ "frontend-modern/src/components/Workloads/ThresholdSlider.test.tsx",
"internal/api/router_bench_test.go",
"internal/api/slo_bench_test.go",
"pkg/metrics/store_bench_test.go",
@@ -4280,62 +4230,10 @@
]
},
{
- "id": "dashboard-workload-hot-path",
- "label": "dashboard workload selector proof",
+ "id": "workloads-hot-path",
+ "label": "Workloads hot-path proof",
"match_prefixes": [],
"match_files": [
- "frontend-modern/src/components/Dashboard/Dashboard.tsx",
- "frontend-modern/src/components/Dashboard/DashboardFilter.tsx",
- "frontend-modern/src/components/Dashboard/dashboardFilterModel.ts",
- "frontend-modern/src/components/Dashboard/dashboardSelectionModel.ts",
- "frontend-modern/src/components/Dashboard/DashboardStateCards.tsx",
- "frontend-modern/src/components/Dashboard/DashboardStatsStrip.tsx",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadFilterConfigModel.ts",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadRouteModel.ts",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadRouteStateModel.ts",
- "frontend-modern/src/components/Dashboard/DashboardWorkloadTable.tsx",
- "frontend-modern/src/components/Dashboard/dashboardWorkloadUrlSyncModel.ts",
- "frontend-modern/src/components/Dashboard/DiskList.tsx",
- "frontend-modern/src/components/Dashboard/diskListModel.ts",
- "frontend-modern/src/components/Dashboard/EnhancedCPUBar.tsx",
- "frontend-modern/src/components/Dashboard/enhancedCpuBarModel.ts",
- "frontend-modern/src/components/Dashboard/GuestDrawer.tsx",
- "frontend-modern/src/components/Dashboard/guestDrawerModel.ts",
- "frontend-modern/src/components/Dashboard/GuestDrawerOverview.tsx",
- "frontend-modern/src/components/Dashboard/GuestRow.tsx",
- "frontend-modern/src/components/Dashboard/GuestRowCells.tsx",
- "frontend-modern/src/components/Dashboard/guestRowModel.tsx",
- "frontend-modern/src/components/Dashboard/MetricBar.tsx",
- "frontend-modern/src/components/Dashboard/metricBarModel.ts",
- "frontend-modern/src/components/Dashboard/StackedDiskBar.tsx",
- "frontend-modern/src/components/Dashboard/stackedDiskBarModel.ts",
- "frontend-modern/src/components/Dashboard/StackedMemoryBar.tsx",
- "frontend-modern/src/components/Dashboard/stackedMemoryBarModel.ts",
- "frontend-modern/src/components/Dashboard/ThresholdSlider.tsx",
- "frontend-modern/src/components/Dashboard/thresholdSliderModel.ts",
- "frontend-modern/src/components/Dashboard/useDashboardControlsState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardFilterState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardGuestMetadataState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardSelectionState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadDerivedState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadFilterOptions.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadRouteState.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadUrlSync.ts",
- "frontend-modern/src/components/Dashboard/useDashboardWorkloadViewportSync.ts",
- "frontend-modern/src/components/Dashboard/useDiskListState.ts",
- "frontend-modern/src/components/Dashboard/useEnhancedCPUBarState.ts",
- "frontend-modern/src/components/Dashboard/useGroupedTableWindowing.ts",
- "frontend-modern/src/components/Dashboard/useGuestDrawerState.ts",
- "frontend-modern/src/components/Dashboard/useGuestRowState.ts",
- "frontend-modern/src/components/Dashboard/useMetricBarState.ts",
- "frontend-modern/src/components/Dashboard/useStackedDiskBarState.ts",
- "frontend-modern/src/components/Dashboard/useStackedMemoryBarState.ts",
- "frontend-modern/src/components/Dashboard/useThresholdSliderState.ts",
- "frontend-modern/src/components/Dashboard/WorkloadPanel.tsx",
- "frontend-modern/src/components/Dashboard/workloadSelectors.ts",
- "frontend-modern/src/components/Dashboard/WorkloadTableHeader.tsx",
- "frontend-modern/src/components/Dashboard/workloadTopology.ts",
"frontend-modern/src/components/Infrastructure/infrastructureSelectors.ts",
"frontend-modern/src/components/Infrastructure/InfrastructureSummary.tsx",
"frontend-modern/src/components/Infrastructure/infrastructureSummaryModel.ts",
@@ -4350,42 +4248,94 @@
"frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts",
"frontend-modern/src/components/Infrastructure/useUnifiedResourceTableState.ts",
"frontend-modern/src/components/Infrastructure/useUnifiedResourceTableViewportSync.ts",
+ "frontend-modern/src/components/Workloads/DiskList.tsx",
+ "frontend-modern/src/components/Workloads/diskListModel.ts",
+ "frontend-modern/src/components/Workloads/EnhancedCPUBar.tsx",
+ "frontend-modern/src/components/Workloads/enhancedCpuBarModel.ts",
+ "frontend-modern/src/components/Workloads/GuestDrawer.tsx",
+ "frontend-modern/src/components/Workloads/guestDrawerModel.ts",
+ "frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx",
+ "frontend-modern/src/components/Workloads/GuestRow.tsx",
+ "frontend-modern/src/components/Workloads/GuestRowCells.tsx",
+ "frontend-modern/src/components/Workloads/guestRowModel.tsx",
+ "frontend-modern/src/components/Workloads/MetricBar.tsx",
+ "frontend-modern/src/components/Workloads/metricBarModel.ts",
+ "frontend-modern/src/components/Workloads/StackedDiskBar.tsx",
+ "frontend-modern/src/components/Workloads/stackedDiskBarModel.ts",
+ "frontend-modern/src/components/Workloads/StackedMemoryBar.tsx",
+ "frontend-modern/src/components/Workloads/stackedMemoryBarModel.ts",
+ "frontend-modern/src/components/Workloads/ThresholdSlider.tsx",
+ "frontend-modern/src/components/Workloads/thresholdSliderModel.ts",
+ "frontend-modern/src/components/Workloads/useDiskListState.ts",
+ "frontend-modern/src/components/Workloads/useEnhancedCPUBarState.ts",
+ "frontend-modern/src/components/Workloads/useGroupedTableWindowing.ts",
+ "frontend-modern/src/components/Workloads/useGuestDrawerState.ts",
+ "frontend-modern/src/components/Workloads/useGuestRowState.ts",
+ "frontend-modern/src/components/Workloads/useMetricBarState.ts",
+ "frontend-modern/src/components/Workloads/useStackedDiskBarState.ts",
+ "frontend-modern/src/components/Workloads/useStackedMemoryBarState.ts",
+ "frontend-modern/src/components/Workloads/useThresholdSliderState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadFilterOptions.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadGuestMetadataState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadRouteState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsControlsState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsDerivedState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadSelectionState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsFilterState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadsState.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadUrlSync.ts",
+ "frontend-modern/src/components/Workloads/useWorkloadViewportSync.ts",
+ "frontend-modern/src/components/Workloads/workloadFilterConfigModel.ts",
+ "frontend-modern/src/components/Workloads/WorkloadPanel.tsx",
+ "frontend-modern/src/components/Workloads/workloadRouteModel.ts",
+ "frontend-modern/src/components/Workloads/workloadRouteStateModel.ts",
+ "frontend-modern/src/components/Workloads/workloadSelectionModel.ts",
+ "frontend-modern/src/components/Workloads/workloadSelectors.ts",
+ "frontend-modern/src/components/Workloads/WorkloadsFilter.tsx",
+ "frontend-modern/src/components/Workloads/workloadsFilterModel.ts",
+ "frontend-modern/src/components/Workloads/WorkloadsStateCards.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadsStatsStrip.tsx",
"frontend-modern/src/components/Workloads/WorkloadsSummary.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadsSurface.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadsTable.tsx",
+ "frontend-modern/src/components/Workloads/WorkloadTableHeader.tsx",
+ "frontend-modern/src/components/Workloads/workloadTopology.ts",
+ "frontend-modern/src/components/Workloads/workloadUrlSyncModel.ts",
"frontend-modern/src/pages/Workloads.tsx",
"frontend-modern/src/utils/thresholdSliderPresentation.ts"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
- "frontend-modern/src/components/Dashboard/__tests__/Dashboard.performance.contract.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/DashboardFilter.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardSelectionModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadFilterConfigModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadRouteModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadRouteStateModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/dashboardWorkloadUrlSyncModel.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/DiskList.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/EnhancedCPUBar.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/GuestRow.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/StackedDiskBar.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useDashboardFilterState.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/useDashboardSelectionState.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/useDashboardWorkloadViewportSync.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useEnhancedCPUBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useGroupedTableWindowing.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/useMetricBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useStackedDiskBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useStackedMemoryBarState.test.tsx",
- "frontend-modern/src/components/Dashboard/__tests__/useThresholdSliderState.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/workloadSelectors.test.ts",
- "frontend-modern/src/components/Dashboard/__tests__/workloadTopology.test.ts",
- "frontend-modern/src/components/Dashboard/GuestDrawer.test.tsx",
- "frontend-modern/src/components/Dashboard/MetricBar.test.tsx",
- "frontend-modern/src/components/Dashboard/StackedMemoryBar.test.tsx",
- "frontend-modern/src/components/Dashboard/ThresholdSlider.test.tsx",
"frontend-modern/src/components/Infrastructure/__tests__/infrastructureSummaryModel.test.ts",
"frontend-modern/src/components/Infrastructure/__tests__/UnifiedResourceTable.performance.contract.test.tsx",
"frontend-modern/src/components/Infrastructure/__tests__/unifiedResourceTableStateModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/DiskList.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/EnhancedCPUBar.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/GuestRow.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/StackedDiskBar.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useEnhancedCPUBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useGroupedTableWindowing.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useMetricBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useStackedDiskBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useStackedMemoryBarState.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/useThresholdSliderState.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useWorkloadSelectionState.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useWorkloadsFilterState.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/useWorkloadViewportSync.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/workloadFilterConfigModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadRouteModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadRouteStateModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadSelectionModel.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadSelectors.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/WorkloadsFilter.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx",
+ "frontend-modern/src/components/Workloads/__tests__/workloadTopology.test.ts",
+ "frontend-modern/src/components/Workloads/__tests__/workloadUrlSyncModel.test.ts",
+ "frontend-modern/src/components/Workloads/GuestDrawer.test.tsx",
+ "frontend-modern/src/components/Workloads/MetricBar.test.tsx",
+ "frontend-modern/src/components/Workloads/StackedMemoryBar.test.tsx",
+ "frontend-modern/src/components/Workloads/ThresholdSlider.test.tsx",
"frontend-modern/src/components/Workloads/WorkloadsSummary.test.tsx",
"frontend-modern/src/pages/__tests__/Workloads.helpers.test.ts",
"frontend-modern/src/utils/__tests__/thresholdSliderPresentation.test.ts"
@@ -4731,21 +4681,14 @@
"internal/recovery/"
],
"owned_files": [
- "frontend-modern/src/components/Recovery/DashboardRecoveryStatusPanel.tsx",
- "frontend-modern/src/components/Storage/DashboardStoragePanel.tsx",
- "frontend-modern/src/features/dashboardOverview/dashboardWidgets.ts",
"frontend-modern/src/features/recovery/useRecoverySurfaceState.ts",
- "frontend-modern/src/hooks/useDashboardRecovery.ts",
"frontend-modern/src/hooks/useRecoveryPoints.ts",
"frontend-modern/src/hooks/useRecoveryPointsFacets.ts",
"frontend-modern/src/hooks/useRecoveryPointsSeries.ts",
"frontend-modern/src/hooks/useRecoveryRollups.ts",
- "frontend-modern/src/pages/Dashboard.tsx",
"frontend-modern/src/pages/Recovery.tsx",
"frontend-modern/src/pages/Storage.tsx",
"frontend-modern/src/types/recovery.ts",
- "frontend-modern/src/utils/dashboardRecoveryPresentation.ts",
- "frontend-modern/src/utils/dashboardStoragePresentation.ts",
"frontend-modern/src/utils/recoveryActionPresentation.ts",
"frontend-modern/src/utils/recoveryArtifactModePresentation.ts",
"frontend-modern/src/utils/recoveryDatePresentation.ts",
@@ -4769,7 +4712,6 @@
"frontend-modern/src/components/Recovery/RecoverySummary.test.tsx",
"frontend-modern/src/components/Storage/code_standards.test.ts",
"frontend-modern/src/pages/__tests__/Recovery.test.tsx",
- "frontend-modern/src/utils/__tests__/dashboardRecoveryPresentation.test.ts",
"internal/recovery/recovery_test.go"
],
"require_explicit_path_policy_coverage": true,
@@ -4793,20 +4735,6 @@
"internal/recovery/store/store_test.go"
]
},
- {
- "id": "dashboard-storage-recovery-surface",
- "label": "dashboard storage and recovery surface proof",
- "match_prefixes": [],
- "match_files": [
- "frontend-modern/src/features/dashboardOverview/dashboardWidgets.ts",
- "frontend-modern/src/pages/Dashboard.tsx"
- ],
- "allow_same_subsystem_tests": false,
- "test_prefixes": [],
- "exact_files": [
- "frontend-modern/src/pages/__tests__/DashboardPage.test.tsx"
- ]
- },
{
"id": "recovery-product-surface",
"label": "recovery product surface proof",
@@ -4814,16 +4742,13 @@
"frontend-modern/src/components/Recovery/"
],
"match_files": [
- "frontend-modern/src/components/Recovery/DashboardRecoveryStatusPanel.tsx",
"frontend-modern/src/features/recovery/useRecoverySurfaceState.ts",
- "frontend-modern/src/hooks/useDashboardRecovery.ts",
"frontend-modern/src/hooks/useRecoveryPoints.ts",
"frontend-modern/src/hooks/useRecoveryPointsFacets.ts",
"frontend-modern/src/hooks/useRecoveryPointsSeries.ts",
"frontend-modern/src/hooks/useRecoveryRollups.ts",
"frontend-modern/src/pages/Recovery.tsx",
"frontend-modern/src/types/recovery.ts",
- "frontend-modern/src/utils/dashboardRecoveryPresentation.ts",
"frontend-modern/src/utils/recoveryActionPresentation.ts",
"frontend-modern/src/utils/recoveryArtifactModePresentation.ts",
"frontend-modern/src/utils/recoveryDatePresentation.ts",
@@ -4845,7 +4770,6 @@
"frontend-modern/src/components/Recovery/__tests__/Recovery.test.tsx",
"frontend-modern/src/components/Recovery/RecoverySummary.test.tsx",
"frontend-modern/src/pages/__tests__/Recovery.test.tsx",
- "frontend-modern/src/utils/__tests__/dashboardRecoveryPresentation.test.ts",
"frontend-modern/src/utils/__tests__/frontendResourceTypeBoundaries.test.ts",
"tests/integration/tests/17-recovery-layout.spec.ts"
]
@@ -4858,14 +4782,11 @@
"frontend-modern/src/features/storageBackups/"
],
"match_files": [
- "frontend-modern/src/components/Storage/DashboardStoragePanel.tsx",
- "frontend-modern/src/pages/Storage.tsx",
- "frontend-modern/src/utils/dashboardStoragePresentation.ts"
+ "frontend-modern/src/pages/Storage.tsx"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
- "frontend-modern/src/components/Storage/__tests__/DashboardStoragePanel.test.tsx",
"frontend-modern/src/components/Storage/__tests__/DiskList.test.tsx",
"frontend-modern/src/components/Storage/__tests__/Storage.test.tsx",
"frontend-modern/src/components/Storage/__tests__/StorageControls.test.tsx",
@@ -4881,7 +4802,6 @@
"frontend-modern/src/features/storageBackups/__tests__/storagePagePresentation.test.ts",
"frontend-modern/src/features/storageBackups/__tests__/storagePoolsTablePresentation.test.ts",
"frontend-modern/src/pages/__tests__/Storage.helpers.test.ts",
- "frontend-modern/src/utils/__tests__/dashboardStoragePresentation.test.ts",
"frontend-modern/src/utils/__tests__/frontendResourceTypeBoundaries.test.ts"
]
}
@@ -4935,7 +4855,6 @@
"frontend-modern/src/features/infrastructure/InfrastructurePageSurface.tsx",
"frontend-modern/src/features/infrastructure/useInfrastructurePageRouteState.ts",
"frontend-modern/src/features/infrastructure/useInfrastructurePageState.ts",
- "frontend-modern/src/hooks/useDashboardTrends.ts",
"frontend-modern/src/hooks/useUnifiedResources.ts",
"frontend-modern/src/pages/Infrastructure.tsx",
"frontend-modern/src/routing/resourceLinks.ts",
@@ -5054,7 +4973,6 @@
"frontend-modern/src/features/infrastructure/InfrastructurePageSurface.tsx",
"frontend-modern/src/features/infrastructure/useInfrastructurePageRouteState.ts",
"frontend-modern/src/features/infrastructure/useInfrastructurePageState.ts",
- "frontend-modern/src/hooks/useDashboardTrends.ts",
"frontend-modern/src/hooks/useUnifiedResources.ts",
"frontend-modern/src/pages/Infrastructure.tsx",
"frontend-modern/src/routing/resourceLinks.ts",
@@ -5080,7 +4998,6 @@
"frontend-modern/src/components/Infrastructure/__tests__/unifiedResourceTableStateModel.test.ts",
"frontend-modern/src/features/infrastructure/__tests__/infrastructurePageModel.test.ts",
"frontend-modern/src/features/infrastructure/__tests__/InfrastructurePageSurface.guardrails.test.ts",
- "frontend-modern/src/hooks/__tests__/useDashboardTrends.test.ts",
"frontend-modern/src/hooks/__tests__/useUnifiedResources.test.ts",
"frontend-modern/src/pages/__tests__/Infrastructure.empty-state.test.tsx",
"frontend-modern/src/pages/__tests__/Infrastructure.pbs-pmg.test.tsx",
diff --git a/docs/release-control/v6/internal/subsystems/security-privacy.md b/docs/release-control/v6/internal/subsystems/security-privacy.md
index 5fdeba29f2..0e0a89f095 100644
--- a/docs/release-control/v6/internal/subsystems/security-privacy.md
+++ b/docs/release-control/v6/internal/subsystems/security-privacy.md
@@ -155,6 +155,11 @@ Security-facing settings remain intentionally shared with `frontend-primitives`
because shell framing and presentation consistency still belong there, but the
meaning of those surfaces now lives here so auth posture, token controls, and
privacy toggles stop borrowing their governance only from adjacent lanes.
+That settings presentation boundary also owns trust-sensitive vocabulary around
+operator access. `frontend-modern/src/components/Settings/GeneralSettingsPanel.tsx`
+and `frontend-modern/src/components/Settings/apiTokenManagerModel.ts` must use
+monitoring/workspace wording for tours and read-only token presets instead of
+reviving Dashboard-specific labels after the Dashboard route has been retired.
The Data Handling settings surface extends that trust boundary to resource
policy posture. It may expose the canonical sensitivity, handling-boundary,
and redaction counts that Pulse already applies to resources, but it must stay
diff --git a/docs/release-control/v6/internal/subsystems/storage-recovery.md b/docs/release-control/v6/internal/subsystems/storage-recovery.md
index 3cca199385..ebbd7e07fd 100644
--- a/docs/release-control/v6/internal/subsystems/storage-recovery.md
+++ b/docs/release-control/v6/internal/subsystems/storage-recovery.md
@@ -47,11 +47,7 @@ querying, and the operator-facing storage health presentation layer.
20. `frontend-modern/src/hooks/useRecoveryPointsSeries.ts`
21. `frontend-modern/src/pages/Recovery.tsx`
22. `frontend-modern/src/routing/resourceLinks.ts`
-23. `frontend-modern/src/pages/Dashboard.tsx`
-24. `frontend-modern/src/features/dashboardOverview/dashboardWidgets.ts`
-25. `frontend-modern/src/components/Recovery/DashboardRecoveryStatusPanel.tsx`
-26. `frontend-modern/src/components/Storage/DashboardStoragePanel.tsx`
-27. `frontend-modern/src/types/recovery.ts`
+23. `frontend-modern/src/types/recovery.ts`
28. `frontend-modern/src/utils/recoverySummaryPresentation.ts`
29. `frontend-modern/src/utils/recoveryTablePresentation.ts`
30. `frontend-modern/src/utils/recoveryItemTypePresentation.ts`
@@ -84,17 +80,11 @@ querying, and the operator-facing storage health presentation layer.
protected-inventory-only state so hidden filters cannot make valid history
look empty.
3. Add or change storage page UX through `frontend-modern/src/pages/Storage.tsx`, `frontend-modern/src/components/Storage/`, `frontend-modern/src/features/storageBackups/`, and the shared storage-source contract in `frontend-modern/src/utils/storageSources.ts`
- Dashboard route composition may place storage and recovery widgets beside
- the estate summary, but estate-summary copy must not present storage or
- recovery health as resolved. Storage and recovery readiness claims remain
- owned by `DashboardStoragePanel` and `DashboardRecoveryStatusPanel`; estate
- summary anchors may focus the dashboard alerts or problem-resource sections
- but must not redirect into storage or recovery ownership. Optional dashboard
- Pulse Brief copy may summarize storage and recovery facts that are already on
- the route, but it must not become the owner of storage capacity, storage
- health, protected-item, or recovery-outcome readiness claims. The Assistant
- handoff safety mode for that brief remains an AI runtime/API contract concern
- and must not move storage or recovery readiness truth into model prose.
+ The retired dashboard route must not reintroduce storage or recovery
+ widgets as compatibility panels. Storage capacity, storage health,
+ protected-item, and recovery-outcome readiness claims belong on the Storage
+ and Recovery surfaces or their shared summary components, not in a restored
+ dashboard panel cluster or Assistant brief.
4. Route transport changes for storage and recovery endpoints through `internal/api/` and the owning `api-contracts` proof routes
That same adjacent API/security boundary owns CSRF replacement-token
concurrency for browser mutations. Storage and recovery forms may benefit
@@ -348,24 +338,13 @@ querying, and the operator-facing storage health presentation layer.
In mock mode, that same compact route must stay aggregate-only and
sampler-prewarmed; storage and recovery must not trigger per-pool chart
reconstruction on the first dashboard request after each mock refresh.
-34. Keep storage and recovery websocket reads on the neutral app-runtime boundary. `frontend-modern/src/components/Recovery/RecoveryPointDetails.tsx`, `frontend-modern/src/components/Storage/useStoragePageResources.ts`, and storage/recovery-adjacent dashboard composition may consume live websocket state only through `frontend-modern/src/contexts/appRuntime.ts`, not by importing `frontend-modern/src/App.tsx` or rebuilding shell-local providers.
- That same dashboard composition boundary also owns compact summary reads.
- When `frontend-modern/src/pages/Dashboard.tsx` renders storage and
- recovery-adjacent cards from `/api/resources/dashboard-summary` and
- `/api/charts/storage-summary`, those cards may reuse the compact payloads
- they were already given, but they must not reopen paginated
- `useUnifiedResources()` transport or reintroduce per-pool
- `/api/metrics-store/history` fan-out under the dashboard hot path.
- Any route-owned dashboard additions composed above those cards must remain
- adjacent composition only: they must not replace the recovery/storage
- dashboard panels, suppress the governed no-resources handoff, or move
- storage/recovery summary ownership out of the compact dashboard route.
- Dashboard estate-orientation additions follow that same rule: they may
- compose above the storage/recovery cards to prove Pulse sees the connected
- estate, but they must consume `appRuntime` connected-infrastructure state
- and the existing compact dashboard summary fallback rather than adding new
- storage/recovery fetches or reclassifying storage/recovery widgets as
- dashboard-owned summary panels.
+34. Keep storage and recovery websocket reads on the neutral app-runtime boundary. `frontend-modern/src/components/Recovery/RecoveryPointDetails.tsx`, `frontend-modern/src/components/Storage/useStoragePageResources.ts`, and adjacent summary/detail composition may consume live websocket state only through `frontend-modern/src/contexts/appRuntime.ts`, not by importing `frontend-modern/src/App.tsx` or rebuilding shell-local providers.
+ That same dashboard composition boundary is now a retired negative space.
+ Storage and recovery-adjacent summaries may reuse
+ `/api/charts/storage-summary` through their owning summary components, but
+ they must not restore `/api/resources/dashboard-summary`, paginated
+ `useUnifiedResources()` transport, or per-pool `/api/metrics-store/history`
+ fan-out under a dashboard hot path.
35. Keep shared `frontend-modern/src/App.tsx` public-route ownership explicit by
surface. Storage/recovery preview entrypoints such as
`/preview/setup-complete` may remain public app-shell routes, but unrelated
@@ -387,7 +366,7 @@ querying, and the operator-facing storage health presentation layer.
plane boundary.
Authenticated `/login` must follow that same shared app-shell contract:
once login succeeds, `frontend-modern/src/App.tsx` must hand the browser
- back to the governed dashboard landing route instead of leaving
+ back to the governed Infrastructure landing route instead of leaving
storage/recovery-adjacent authenticated shells on a page-local not-found
route.
Authenticated-shell demo organization suppression on `frontend-modern/src/App.tsx`
@@ -453,18 +432,17 @@ querying, and the operator-facing storage health presentation layer.
runtime as populated mock inventory, but they must not expose
`demo_fixtures`, billing identity, or alternate entitlement semantics as
recovery-local transport or operator-facing storage metadata.
-37. Keep dashboard storage summary fetches scope-owned on the shared summary
- caches. `frontend-modern/src/components/Storage/StorageSummary.tsx`,
+37. Keep storage summary fetches scope-owned on the shared summary caches.
+ `frontend-modern/src/components/Storage/StorageSummary.tsx`,
`frontend-modern/src/utils/storageSummaryCache.ts`,
- `frontend-modern/src/utils/storageSummaryTrendCache.ts`, and
- `frontend-modern/src/pages/Dashboard.tsx` may reuse cached org/range
- storage summaries for first paint, but they must not refetch the full
- `/api/storage-charts` payload once per additional dashboard resource page
- or invent a dashboard-only storage summary transport path outside the
+ and `frontend-modern/src/utils/storageSummaryTrendCache.ts` may reuse
+ cached org/range storage summaries for first paint, but they must not
+ refetch the full `/api/storage-charts` payload once per adjacent summary
+ card or invent a dashboard-only storage summary transport path outside the
canonical cache owners.
38. Keep storage and recovery route framing additive and owner-neutral.
`frontend-modern/src/components/Storage/Storage.tsx` and storage/recovery-
- adjacent dashboard composition may use the shared `PageHeader` shell for
+ adjacent route composition may use the shared `PageHeader` shell for
top-level route framing, but that header must stay additive on top of the
canonical storage page model, recovery presenters, and shared summary
caches. Header chrome must not become a second owner for storage filters,
@@ -528,19 +506,14 @@ querying, and the operator-facing storage health presentation layer.
widening it into a broad short-name collapse across distinct FQDNs.
5. Keep recovery history table width budgeting derived from the canonical column specs in `frontend-modern/src/utils/recoveryTablePresentation.ts`, not from raw visible-column counts, so normalized subject labels and optional column sets cannot drift the right-edge badges and controls off-screen
6. Keep at least one browser-level desktop recovery proof in the governed `recovery-product-surface` policy so right-edge column visibility and wrapper-fit regressions are caught at rendered layout time instead of only through unit-level width math
-7. Keep the dashboard route's no-resources state on an explicit first-session
- handoff. `frontend-modern/src/pages/Dashboard.tsx` may stay storage/recovery-
- owned for dashboard composition, but when no resources have reported yet it
- must route operators to `/settings/infrastructure/install` instead of
- leaving the dashboard as a passive dead end.
-8. Keep dashboard storage/recovery composition on the shared all-resources
- snapshot. `frontend-modern/src/pages/Dashboard.tsx` may stay
- storage/recovery-owned for dashboard widget composition, but it must reuse
- the canonical `all-resources` cache key from
- `frontend-modern/src/hooks/useUnifiedResources.ts` so storage/recovery
- widgets do not fork a dashboard-only resource snapshot and force adjacent
- infrastructure handoffs back through transient loading shells once the
- broader dashboard data is already warm.
+7. Keep the retired dashboard route from becoming a passive no-resources
+ compatibility shell. First-session handoff now belongs to Infrastructure
+ and Add infrastructure, and storage/recovery must not restore dashboard
+ composition just to route operators to setup.
+8. Keep storage/recovery summaries on their owning snapshots after dashboard
+ retirement. They may reuse the canonical `all-resources` cache key from
+ `frontend-modern/src/hooks/useUnifiedResources.ts` only through their owned
+ page or shared drawer surfaces, not as a dashboard-only resource snapshot.
9. Keep shared OIDC/SAML callback redirects on the canonical local-target
helper contract when storage- or recovery-adjacent routes inherit shared
auth browser handoff through `internal/api/`, so adjacent surfaces do not
@@ -1520,42 +1493,13 @@ boundary: raw compatibility fields such as `provider` / `providers` may be
accepted from older `/api/recovery/*` payloads, but the runtime values they
return to the rest of the recovery UI must be canonical `platform` /
`platforms` models.
-That same rule applies to the dashboard recovery entry points too:
-`frontend-modern/src/hooks/useDashboardRecovery.ts`,
-`frontend-modern/src/pages/Dashboard.tsx`,
-`frontend-modern/src/features/dashboardOverview/dashboardWidgets.ts`,
-`frontend-modern/src/components/Recovery/DashboardRecoveryStatusPanel.tsx`, and
-`frontend-modern/src/utils/dashboardRecoveryPresentation.ts` must stay on
-explicit direct dashboard/recovery proof routing instead of inheriting
-coverage only through the full recovery route or broader dashboard shells.
-The storage dashboard entry point must be treated the same way on the storage
-side: `frontend-modern/src/pages/Dashboard.tsx`,
-`frontend-modern/src/features/dashboardOverview/dashboardWidgets.ts`, and
-`frontend-modern/src/components/Storage/DashboardStoragePanel.tsx` and
-`frontend-modern/src/utils/dashboardStoragePresentation.ts` must stay on
-explicit direct dashboard/storage proof routing instead of borrowing release-
-control coverage only from the broader storage page, component, and model
-surfaces.
-That same dashboard storage surface must also render its capacity meter through
-the shared `frontend-modern/src/components/shared/ProgressBar.tsx` primitive
-and attribute-driven fill geometry instead of owner-local inline width styles,
-so the live dashboard remains CSP-safe while still reporting the canonical
-storage summary.
-That route shell now also composes the recent-alerts widget directly from the
-alert-owned `frontend-modern/src/components/Alerts/RecentAlertsPanel.tsx`
-surface instead of via a dashboard-panels-local alert implementation, so the
-dashboard route stays storage/recovery-owned while alert widget runtime remains
-owned by the alerts subsystem. That route handoff must stay thin: the dashboard
-page should pass the live alert list into `RecentAlertsPanel` and let the
-alert-owned surface derive its own summary and acknowledgement state instead of
-rebuilding alert summary counts or alert-action runtime inside the
-storage/recovery-governed dashboard route.
-That same route shell also owns the top-of-dashboard scan order. When
-`frontend-modern/src/pages/Dashboard.tsx` renders both the KPI strip and the
-problem-resources table, the route must keep the operator snapshot above the
-detail table so the page reads as action queue, summary, then problem detail
-rather than dropping operators straight into a long exception list before the
-dashboard baseline is visible.
+The retired dashboard recovery and storage entry points must stay removed:
+`useDashboardRecovery`, `DashboardRecoveryStatusPanel`,
+`DashboardStoragePanel`, dashboard storage/recovery presentation helpers, and
+dashboard widget orchestration must not return as direct proof surfaces. New
+storage or recovery summary proof must attach to the owning Storage,
+Recovery, Infrastructure drawer, or shared summary component instead of
+borrowing coverage through a broader dashboard shell.
The shared recovery type contract must be pinned the same way:
`frontend-modern/src/types/recovery.ts` must stay on the explicit
`recovery-product-surface` proof path instead of riding indirectly on route or
@@ -2624,13 +2568,12 @@ collector, agent-id/device fallback stream, or separate "real-time" history
store once monitoring and `/api/metrics-store/history` already own the disk
timeline.
The same shell/runtime split now applies to websocket consumers:
-`frontend-modern/src/components/Recovery/RecoveryPointDetails.tsx`,
-`frontend-modern/src/components/Storage/useStoragePageResources.ts`, and
-`frontend-modern/src/pages/Dashboard.tsx` may consume websocket state only
-through `frontend-modern/src/contexts/appRuntime.ts`. They must not import
-`@/App` or create storage/recovery-local shell coupling, because provider
-placement remains app-shell-owned and storage/recovery surfaces must stay
-lazy-load safe.
+`frontend-modern/src/components/Recovery/RecoveryPointDetails.tsx` and
+`frontend-modern/src/components/Storage/useStoragePageResources.ts` may consume
+websocket state only through `frontend-modern/src/contexts/appRuntime.ts`.
+They must not import `@/App` or create storage/recovery-local shell coupling,
+because provider placement remains app-shell-owned and storage/recovery
+surfaces must stay lazy-load safe.
That same adjacent `internal/api/` boundary now also governs public-demo
commercial redaction for storage and recovery viewers. Shared storage/recovery
surfaces may run beside a demo runtime that has real internal entitlements,
diff --git a/docs/release-control/v6/internal/subsystems/unified-resources.md b/docs/release-control/v6/internal/subsystems/unified-resources.md
index 52a8eb7ff8..3cd708adcd 100644
--- a/docs/release-control/v6/internal/subsystems/unified-resources.md
+++ b/docs/release-control/v6/internal/subsystems/unified-resources.md
@@ -100,8 +100,7 @@ cross-source deduplication.
74. `frontend-modern/src/components/PMG/ServiceHealthBadge.tsx`
75. `frontend-modern/src/utils/resourceIdentity.ts`
76. `frontend-modern/src/components/Infrastructure/resourceDetailDrawerIdentityModel.ts`
-77. `frontend-modern/src/hooks/useDashboardTrends.ts`
-78. `frontend-modern/src/hooks/useUnifiedResources.ts`
+77. `frontend-modern/src/hooks/useUnifiedResources.ts`
79. `frontend-modern/src/types/resource.ts`
80. `frontend-modern/src/utils/sourcePlatforms.ts`
81. `frontend-modern/src/utils/platformSupportManifest.generated.ts`
@@ -228,7 +227,7 @@ AI-only summary payloads, or page-local heuristics.
canonicalization boundary: REST may hydrate the initial snapshot and
unsupported filtered queries, but supported snapshot freshness must come
from websocket `state.resources` instead of layering confirmatory
- dashboard/infrastructure REST refetch loops over already-owned resource
+ route-local REST refetch loops over already-owned resource
updates.
That shared store/adapter/hook path must also preserve canonical row shape
across transport boundaries: thinner realtime `state.resources` payloads
@@ -243,20 +242,19 @@ AI-only summary payloads, or page-local heuristics.
explicit cluster identity such as Kubernetes context or platform cluster
labels; standalone resource names must never be repurposed as synthetic
`clusterId` values.
-10. Keep the dashboard overview shell on the compact governed summary route
- rather than the unfiltered list transport. `frontend-modern/src/pages/Dashboard.tsx`
- and `frontend-modern/src/hooks/useDashboardOverview.ts` may consume the
- canonical `/api/resources/dashboard-summary` payload for KPI cards,
- problem-resource rows, and top-resource identity, but they must not
- recreate those summaries by mounting `useUnifiedResources()` just to count
- or rank resources on the dashboard shell.
+10. Keep the retired dashboard overview shell absent from unified-resource
+ consumers. `frontend-modern/src/pages/Dashboard.tsx`,
+ `frontend-modern/src/hooks/useDashboardOverview.ts`, and
+ `/api/resources/dashboard-summary` must not be restored as compatibility
+ readers for KPI cards, problem-resource rows, or top-resource identity.
+ Infrastructure and Workloads must consume their owning unified-resource
+ projections directly.
11. Keep summary consumers on the payload they were already given.
- `frontend-modern/src/hooks/useDashboardTrends.ts` and
`frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`
may derive chart identity, storage presence, and infrastructure rollups
- from the compact dashboard overview or resource snapshot they already own,
- but they must not reopen `useResources()` or start a second unfiltered
- unified-resource fetch path under the dashboard summary surface.
+ from the resource snapshot it already owns, but it must not reopen
+ `useResources()` or start a second unfiltered unified-resource fetch path
+ as a replacement dashboard summary surface.
12. Keep shared selector hydration visibility-bound. Reusable shells such as
`frontend-modern/src/components/shared/useInfrastructureSelectorState.ts`
may consume `frontend-modern/src/hooks/useUnifiedResources.ts`, but hidden
@@ -420,13 +418,13 @@ AI-only summary payloads, or page-local heuristics.
through the canonical frontend-to-`ResourceType` resolver before slicing
the snapshot, so compatibility values such as `disk` / `physical_disk`
stay on one cache truth instead of falling back to ad hoc filter aliases.
-18. Keep dashboard storage trend target selection on canonical unified-resource
- truth. `frontend-modern/src/hooks/useDashboardTrends.ts` may detect
- storage presence from canonical `isStorage(...)` resources and their
- shared metrics-target IDs, but once storage exists it must reuse the owned
- compact `/api/charts/storage-summary` contract instead of rebuilding
- page-local per-resource storage history fetches, storage-type aliases, or
- full storage-page `/api/storage-charts` fetches.
+18. Keep storage summary target selection on canonical unified-resource truth.
+ Storage-summary consumers may detect storage presence from canonical
+ `isStorage(...)` resources and their shared metrics-target IDs, but once
+ storage exists they must reuse the owned compact
+ `/api/charts/storage-summary` contract instead of rebuilding page-local
+ per-resource storage history fetches, storage-type aliases, or full
+ storage-page `/api/storage-charts` fetches.
19. Keep infrastructure page-header framing presentation-only on the page
shell. `frontend-modern/src/features/infrastructure/InfrastructurePageSurface.tsx`
may render the shared `PageHeader`, but canonical source/status/search
@@ -584,8 +582,8 @@ Seeded unified-resource snapshots are part of that same registry ownership.
`internal/unifiedresources/registry.go` must rebuild the canonical `bySource`
index from source-owned facets already present on seeded unified resources
before manual links, overlays, or metrics-target resolution run, so
-`/api/resources/dashboard-summary`, `/api/resources`, dashboard trend joins,
-and other chart consumers keep resolving history through canonical source
+`/api/resources`, infrastructure summary joins, storage summary joins, and
+other chart consumers keep resolving history through canonical source
coordinates instead of silently falling back to hashed unified resource IDs.
That same registry/view boundary now also applies to provider-backed storage.
`internal/unifiedresources/registry.go` must attach the resolved
@@ -836,20 +834,14 @@ shape: `InfrastructureSummary.tsx` is the render shell,
org-scope lifecycle, and focused-summary state, and
`infrastructureSummaryModel.ts` owns chart matching, focused-summary display
selection, empty-state wording, and summary-series/metric derivation.
-The dashboard overview trend hook now follows that same canonical consumer
-contract for infrastructure sparklines: `frontend-modern/src/hooks/useDashboardTrends.ts`
-must consume the infrastructure summary chart cache and shared unified-resource
-series matching logic instead of issuing bespoke per-resource
-`/api/metrics-store/history` fetches for top-CPU and top-memory cards. That
-keeps dashboard summary sparklines aligned with canonical resource identity
-matching, agent-facet fallback behavior, and first-sample empty-state semantics
-already owned by the infrastructure summary surface.
-The same contract now also treats dashboard top-card sparkline hydration as a
-summary projection concern, not a per-resource history concern: top-CPU and
-top-memory selections may still come from dashboard overview ranking, but the
-series attached to those selections must be resolved through the same
-resource-to-chart matching path used by infrastructure summary cards so agent
-fallback and canonical identity aliases do not drift between the two surfaces.
+The retired dashboard overview trend hook must not return as a second
+infrastructure sparkline consumer. Infrastructure summary surfaces must consume
+the infrastructure summary chart cache and shared unified-resource series
+matching logic instead of issuing bespoke per-resource
+`/api/metrics-store/history` fetches for overview cards. That keeps summary
+sparklines aligned with canonical resource identity matching, agent-facet
+fallback behavior, and first-sample empty-state semantics already owned by the
+infrastructure summary surface.
The backend AI and Patrol context renderers now derive their canonical change
kind, source type, source adapter, actor, reason, and related-resource
fragments from `internal/unifiedresources/change_presentation.go`, so the
@@ -943,7 +935,7 @@ card, so canonical timeline wording and ordering stay governed by one
frontend feed instead of separate page-local loops.
The unified-resource detail drawer now also routes resource-tag presentation
through the shared `frontend-modern/src/components/shared/TagBadges.tsx`
-primitive instead of importing a dashboard-local badge helper into the
+primitive instead of importing a workload-local badge helper into the
resource surface. Future drawer tag presentation changes must extend through
that shared primitive boundary rather than recreating tag-dot logic inside the
drawer or pulling feature-local badge components across subsystem lines.
@@ -1033,9 +1025,9 @@ drawer, which keeps the presentation surface aligned with the governed API
contract instead of rebuilding the relationship and timeline inline.
The canonical routing owner now also lives in
`frontend-modern/src/routing/resourceLinks.ts`, including the
-workload-to-infrastructure href builder used by dashboard row and drawer
+workload-to-infrastructure href builder used by Workloads row and drawer
consumers. Future workload-to-resource navigation changes must extend through
-that shared routing contract instead of reintroducing dashboard-local path
+that shared routing contract instead of reintroducing workload-local path
builders.
That same shared routing boundary now also owns the canonical Patrol
destination used by cross-surface findings and drill-down links. Shared
@@ -1418,15 +1410,15 @@ mock-history paths, so cluster, node, pod, and deployment charts all bind to
one runtime key family instead of each layer rebuilding Kubernetes IDs from
cluster name, namespace, or surface-local aliases.
The drawer's discovery mapper also reuses that helper for pod fallback agent
-IDs, so the resource-detail path and the dashboard path stay aligned on the
+IDs, so the resource-detail path and the Workloads path stay aligned on the
same cluster-name source of truth.
-The dashboard workload projection and workloads-link route helpers also share
+The workload projection and workloads-link route helpers also share
the same Kubernetes context prefix helper in the shared agent-resource
layer, so pod grouping and cluster navigation keep the same cluster-context
prefix before any surface-specific display fallback is applied.
The unified-resource projection also reuses that same prefix helper for
projected Kubernetes `clusterId`, so the shared resource store stays aligned
-with the dashboard and detail surfaces on the same canonical cluster-context
+with the Workloads and detail surfaces on the same canonical cluster-context
source of truth.
That same contract also owns the canonical resource display-name fallback, so
name-or-ID presentation stays consistent between the unified AI adapter, the
@@ -1796,8 +1788,8 @@ Docker-routed control target.
That same contract applies to the frontend workload state boundary:
`frontend-modern/src/hooks/useWorkloads.ts`,
`frontend-modern/src/utils/workloads.ts`,
-`frontend-modern/src/components/Dashboard/workloadTopology.ts`, and
-`frontend-modern/src/components/Dashboard/useGuestRowState.ts` may reuse
+`frontend-modern/src/components/Workloads/workloadTopology.ts`, and
+`frontend-modern/src/components/Workloads/useGuestRowState.ts` may reuse
shared `DockerData` for runtime metadata, but they must keep Docker-only
action identifiers and update affordances scoped to Docker-managed
app-containers. TrueNAS-backed `app-container` workloads must still navigate
diff --git a/frontend-modern/scripts/canonical-platform-audit.mjs b/frontend-modern/scripts/canonical-platform-audit.mjs
index 2b2a83f7c6..4306765ce1 100644
--- a/frontend-modern/scripts/canonical-platform-audit.mjs
+++ b/frontend-modern/scripts/canonical-platform-audit.mjs
@@ -61,10 +61,8 @@ const ALLOWLIST = new Set([
'src/utils/agentCapabilityPresentation.ts',
'src/utils/unifiedAgentInventoryPresentation.ts',
'src/utils/unifiedAgentStatusPresentation.ts',
- 'src/utils/dashboardAlertPresentation.ts',
- 'src/utils/dashboardEmptyStatePresentation.ts',
- 'src/utils/dashboardStoragePresentation.ts',
- 'src/utils/dashboardRecoveryPresentation.ts',
+ 'src/utils/alertOverviewPresentation.ts',
+ 'src/utils/workloadEmptyStatePresentation.ts',
'src/utils/temperature.ts',
'src/utils/licensePresentation.ts',
'src/utils/k8sStatusPresentation.ts',
@@ -142,10 +140,7 @@ const ALLOWLIST = new Set([
'src/utils/k8sDeploymentPresentation.ts',
'src/utils/k8sNamespacePresentation.ts',
'src/components/shared/EnvironmentLockBadge.tsx',
- 'src/utils/dashboardCompositionPresentation.ts',
- 'src/utils/dashboardGuestPresentation.ts',
- 'src/utils/dashboardMetricPresentation.ts',
- 'src/utils/dashboardTrendPresentation.ts',
+ 'src/utils/workloadGuestPresentation.ts',
'src/utils/deployFlowPresentation.ts',
'src/utils/infrastructureEmptyStatePresentation.ts',
]);
@@ -335,11 +330,11 @@ const HELPER_RULES = [
'Do not define local infrastructure empty-state copy in page code. Use @/utils/infrastructureEmptyStatePresentation instead.',
},
{
- rule: 'canonical-dashboard/no-local-dashboard-empty-state-copy',
+ rule: 'canonical-workloads/no-local-workload-empty-state-copy',
regex:
/No infrastructure hosts connected|No guests found|Install the Pulse agent to connect a host and unlock v6 infrastructure data, or add a Proxmox connection in Settings β Infrastructure β Proxmox\.|No guests match your current filters|No guests match your search |Loading dashboard data\.\.\.|Connecting to monitoring service|Reconnecting to monitoring serviceβ¦|Real-time data is currently unavailable\. Showing last-known state\.|Real-time data is reconnecting\. Showing last-known state\.|Dashboard unavailable|Real-time dashboard data is currently unavailable\. Reconnect to try again\.|No resources yet|Once connected platforms report resources, your dashboard overview will appear here\./g,
message:
- 'Do not define local dashboard empty-state copy in component code. Use @/utils/dashboardEmptyStatePresentation instead.',
+ 'Do not define local Workloads empty-state copy in component code. Use @/utils/workloadEmptyStatePresentation instead.',
},
{
rule: 'canonical-shared/no-local-empty-state-tone-maps',
@@ -530,16 +525,16 @@ const HELPER_RULES = [
'Do not define local recovery chart range selected-button classes in page code. Use the shared segmented button contract instead.',
},
{
- rule: 'canonical-dashboard/no-local-trend-range-selected-classes',
+ rule: 'canonical-overview/no-local-trend-range-selected-classes',
regex: /\bselectedRange\(\)\s*===\s*range\b[\s\S]{0,260}bg-blue-600\s+text-white/g,
message:
- 'Do not define local dashboard trend range selected-button classes in page code. Use the shared segmented button contract instead.',
+ 'Do not define local overview trend range selected-button classes in page code. Use the shared segmented button contract instead.',
},
{
- rule: 'canonical-dashboard/no-local-trend-error-copy',
+ rule: 'canonical-overview/no-local-trend-error-copy',
regex: /Unable to load trends/g,
message:
- 'Do not define local dashboard trend error copy in panel code. Use @/utils/dashboardTrendPresentation instead.',
+ 'Do not define local overview trend error copy in panel code. Use the governed route presentation helper instead.',
},
{
rule: 'canonical-ai/no-local-findings-filter-selected-classes',
@@ -644,30 +639,30 @@ const HELPER_RULES = [
'Do not define local unified-agent lookup status helpers in component code. Use @/utils/unifiedAgentStatusPresentation instead.',
},
{
- rule: 'canonical-dashboard/no-local-problem-status-variant',
+ rule: 'canonical-overview/no-local-problem-status-variant',
regex: /\b(?:const|function)\s+statusVariant\s*\(\s*pr\s*:\s*ProblemResource\s*\)/g,
message:
- 'Do not define local dashboard problem-resource status helpers in page code. Use @/utils/problemResourcePresentation instead.',
+ 'Do not define local problem-resource status helpers in page code. Use @/utils/problemResourcePresentation instead.',
},
{
- rule: 'canonical-dashboard/no-local-alerts-tone',
+ rule: 'canonical-alerts/no-local-alerts-tone',
regex: /\b(?:const|function)\s+alertsTone\b/g,
message:
- 'Do not define local dashboard alert summary tone helpers in page code. Use @/utils/dashboardAlertPresentation instead.',
+ 'Do not define local alert summary tone helpers in page code. Use @/utils/alertOverviewPresentation instead.',
},
{
- rule: 'canonical-dashboard/no-local-storage-recovery-or-alert-copy',
+ rule: 'canonical-overview/no-local-storage-recovery-or-alert-copy',
regex:
/No active alerts|No storage resources|No recovery data available|Last recovery point over 24 hours ago/g,
message:
- 'Do not define local dashboard storage, recovery, or alert empty-state/staleness copy in page code. Use the shared dashboard presentation utilities instead.',
+ 'Do not define local storage, recovery, or alert empty-state/staleness copy in page code. Use the owning shared presentation utilities instead.',
},
{
- rule: 'canonical-dashboard/no-local-composition-or-ai-empty-state-copy',
+ rule: 'canonical-overview/no-local-composition-or-ai-empty-state-copy',
regex:
/No resources detected|Loading usageβ¦|No usage data yet\.|No daily USD trend yet\.|No daily token trend yet\.|No issues found/g,
message:
- 'Do not define local dashboard or AI empty-state copy in component code. Use the shared presentation utilities instead.',
+ 'Do not define local overview or AI empty-state copy in component code. Use the shared presentation utilities instead.',
},
{
rule: 'canonical-ai/no-local-chat-empty-state-copy',
@@ -789,7 +784,7 @@ const HELPER_RULES = [
'Do not define local ResourcePicker filter labels or hardcoded filter lists in component code. Use @/utils/reportableResourceTypes instead.',
},
{
- rule: 'canonical-dashboard/no-local-threshold-slider-color-map',
+ rule: 'canonical-shared/no-local-threshold-slider-color-map',
regex:
/\bconst\s+colorMap\s*:\s*Record\s*=\s*\{[\s\S]{0,220}cpu:[\s\S]{0,220}memory:[\s\S]{0,220}disk:[\s\S]{0,220}temperature:/g,
message:
@@ -1027,24 +1022,24 @@ const HELPER_RULES = [
'Do not define local recovery timeline chart presentation in component code. Use @/utils/recoveryTimelineChartPresentation instead.',
},
{
- rule: 'canonical-dashboard/no-local-dashboard-helper-implementations',
+ rule: 'canonical-overview/no-local-helper-implementations',
regex:
/\bexport function statusBadgeClass\b|\bexport function priorityBadgeClass\b|\bexport function deltaColorClass\b/g,
message:
- 'Do not define dashboard metric presentation functions in page-local helpers. Use @/utils/dashboardMetricPresentation instead.',
+ 'Do not define metric presentation functions in page-local helpers. Use the governed route presentation helper instead.',
},
{
- rule: 'canonical-dashboard/no-local-composition-icon-map',
+ rule: 'canonical-overview/no-local-composition-icon-map',
regex: /\bconst\s+TYPE_ICONS\s*:\s*Record\s*=/g,
message:
- 'Do not define local dashboard composition icon maps in page code. Use @/utils/dashboardCompositionPresentation instead.',
+ 'Do not define local composition icon maps in page code. Use the governed route presentation helper instead.',
},
{
- rule: 'canonical-dashboard/no-local-guest-backup-status-map',
+ rule: 'canonical-workloads/no-local-guest-backup-status-map',
regex:
/\bconst\s+BACKUP_STATUS_CONFIG\s*:\s*Record<|No backup found|No IP assigned|No filesystems found\. VM may be booting or using a Live ISO\./g,
message:
- 'Do not define local dashboard guest fallback copy or backup status maps in component code. Use @/utils/dashboardGuestPresentation instead.',
+ 'Do not define local Workloads guest fallback copy or backup status maps in component code. Use @/utils/workloadGuestPresentation instead.',
},
{
rule: 'canonical-infrastructure/no-local-deploy-flow-copy',
diff --git a/frontend-modern/src/App.tsx b/frontend-modern/src/App.tsx
index 341afab0c5..58c28f8d96 100644
--- a/frontend-modern/src/App.tsx
+++ b/frontend-modern/src/App.tsx
@@ -23,7 +23,6 @@ import { aiChatStore } from './stores/aiChat';
import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts';
import { useKioskMode } from '@/hooks/useKioskMode';
import {
- DASHBOARD_PATH,
PATROL_PATH,
buildRecoveryPath,
buildInfrastructurePath,
@@ -54,7 +53,6 @@ const AlertsPage = lazy(() =>
);
const SettingsPage = lazy(() => import('./components/Settings/Settings'));
const InfrastructurePage = lazy(() => import('./pages/Infrastructure'));
-const DashboardPage = lazy(() => import('./pages/Dashboard'));
const WorkloadsPage = lazy(() => import('./pages/Workloads'));
const AIIntelligencePage = lazy(() =>
import('./pages/AIIntelligence').then((module) => ({ default: module.AIIntelligence })),
@@ -67,7 +65,6 @@ const SetupCompletionPreviewPage = lazy(() =>
default: module.SetupCompletionPreview,
})),
);
-const ROOT_DASHBOARD_PATH = DASHBOARD_PATH;
const INFRASTRUCTURE_ROUTE_PATH = buildInfrastructurePath();
const ROOT_WORKLOADS_PATH = buildWorkloadsPath();
const STORAGE_PATH = buildStoragePath();
@@ -455,7 +452,6 @@ function App() {
-
diff --git a/frontend-modern/src/AppLayout.tsx b/frontend-modern/src/AppLayout.tsx
index 474fb82641..82b4b7194f 100644
--- a/frontend-modern/src/AppLayout.tsx
+++ b/frontend-modern/src/AppLayout.tsx
@@ -2,7 +2,6 @@ import { For, Show, Suspense, createEffect, createMemo, createSignal, onCleanup
import type { JSX } from 'solid-js';
import { useLocation, useNavigate } from '@solidjs/router';
import BoxesIcon from 'lucide-solid/icons/boxes';
-import LayoutDashboardIcon from 'lucide-solid/icons/layout-dashboard';
import ServerIcon from 'lucide-solid/icons/server';
import HardDriveIcon from 'lucide-solid/icons/hard-drive';
import ArchiveIcon from 'lucide-solid/icons/archive';
@@ -31,7 +30,6 @@ import { preloadRouteModule } from '@/routing/routePreload';
import {
buildInfrastructurePath,
buildWorkloadsPath,
- DASHBOARD_PATH,
} from '@/routing/resourceLinks';
import { buildStorageRecoveryTabSpecs } from '@/routing/platformTabs';
import { getKioskModePreference, setKioskMode } from '@/utils/url';
@@ -229,8 +227,8 @@ export function AppLayout(props: AppLayoutProps) {
!normalizedPath.startsWith('/alerts/overview/') &&
!normalizedPath.startsWith('/alerts/history/');
- if ((isBlocked || isAlertConfigTab) && normalizedPath !== DASHBOARD_PATH) {
- navigate(DASHBOARD_PATH, { replace: true });
+ if ((isBlocked || isAlertConfigTab) && normalizedPath !== ROOT_INFRASTRUCTURE_PATH) {
+ navigate(ROOT_INFRASTRUCTURE_PATH, { replace: true });
}
});
@@ -268,17 +266,6 @@ export function AppLayout(props: AppLayoutProps) {
const platformTabs = createMemo(() => {
const allPlatforms: PlatformTab[] = [
- {
- id: 'dashboard',
- label: 'Dashboard',
- route: DASHBOARD_PATH,
- settingsRoute: '/settings',
- tooltip: 'Environment overview and command center',
- enabled: true,
- live: true,
- icon: LayoutDashboardIcon,
- alwaysShow: true,
- },
{
id: 'infrastructure',
label: 'Infrastructure',
diff --git a/frontend-modern/src/__tests__/App.architecture.test.ts b/frontend-modern/src/__tests__/App.architecture.test.ts
index 45675fd0cc..a8706a6114 100644
--- a/frontend-modern/src/__tests__/App.architecture.test.ts
+++ b/frontend-modern/src/__tests__/App.architecture.test.ts
@@ -11,7 +11,6 @@ const appStylesSource = readFileSync(join(process.cwd(), 'src/index.css'), 'utf8
describe('App architecture', () => {
it('keeps App as the entry shell that delegates runtime and chrome ownership', () => {
- expect(appSource).toContain('DASHBOARD_PATH,');
expect(appSource).toContain("import { AppLayout } from '@/AppLayout';");
expect(appSource).toContain("import { aiChatStore } from './stores/aiChat';");
expect(appSource).toContain(
@@ -28,7 +27,7 @@ describe('App architecture', () => {
expect(appSource).toContain('setAppScrollShellRef');
expect(appSource).toContain('readPendingAppShellRestoreTop');
expect(appSource).toContain('clearPendingAppShellRestoreTop');
- expect(appSource).toContain('const ROOT_DASHBOARD_PATH = DASHBOARD_PATH;');
+ expect(appSource).toContain('const INFRASTRUCTURE_ROUTE_PATH = buildInfrastructurePath();');
expect(appSource).toContain('const ROOT_PATROL_PATH = PATROL_PATH;');
expect(appSource).toContain("import { preloadRouteModule } from '@/routing/routePreload';");
expect(appSource).toContain('const APP_SHELL_ROUTE_PRELOAD_PATHS = [');
@@ -37,7 +36,10 @@ describe('App architecture', () => {
expect(appSource).toContain('await preloadRouteModule(route);');
expect(appSource).toContain('const timeoutId = window.setTimeout(() => {');
expect(appSource).toContain('void preloadAppShellRoutes();');
- expect(appSource).toContain('');
+ expect(appSource).toContain(
+ '',
+ );
+ expect(appSource).not.toContain('DashboardPage');
expect(appSource).toContain("import RuntimeHomePage from '@/pages/RuntimeHome';");
expect(appSource).toContain('');
expect(appSource).toContain('');
@@ -67,7 +69,7 @@ describe('App architecture', () => {
"const StorageComponent = lazy(() => import('./components/Storage/Storage'));",
);
expect(appSource).not.toContain(
- "const WorkloadsView = lazy(() => import('./components/Dashboard/Dashboard'));",
+ "const WorkloadsView = lazy(() => import('./components/Workloads/WorkloadsSurface'));",
);
expect(appSource).not.toContain(
"const RecoveryRoute = lazy(() => import('./pages/RecoveryRoute'));",
@@ -244,8 +246,10 @@ describe('App architecture', () => {
expect(appRuntimeStateSource).toContain(
"eventBus.on('websocket_reconnected', handleWebSocketReconnected);",
);
- expect(appRuntimeStateSource).toContain("const ROOT_DASHBOARD_PATH = '/dashboard';");
- expect(appRuntimeStateSource).toContain('if (pathname === ROOT_DASHBOARD_PATH) return false;');
+ expect(appRuntimeStateSource).toContain(
+ 'const ROOT_INFRASTRUCTURE_PATH = buildInfrastructurePath();',
+ );
+ expect(appRuntimeStateSource).not.toContain("const ROOT_DASHBOARD_PATH = '/dashboard';");
expect(appRuntimeStateSource).not.toContain(
"import { startMetricsCollector } from '@/stores/metricsCollector';",
);
@@ -257,9 +261,10 @@ describe('App architecture', () => {
expect(routePreloadSource).toContain(
'const routePreloadCache = new Map>();',
);
+ expect(routePreloadSource).toContain("import('@/pages/Infrastructure')");
expect(routePreloadSource).toContain("import('@/pages/Workloads')");
expect(routePreloadSource).toContain("import('@/pages/Recovery')");
- expect(routePreloadSource).not.toContain("import('@/components/Dashboard/Dashboard')");
+ expect(routePreloadSource).not.toContain("import('@/components/Workloads/WorkloadsSurface')");
expect(routePreloadSource).not.toContain("import('@/pages/RecoveryRoute')");
expect(appRuntimeContextSource).toContain(
"import { createContext, useContext } from 'solid-js';",
diff --git a/frontend-modern/src/__tests__/AppLayout.test.tsx b/frontend-modern/src/__tests__/AppLayout.test.tsx
index f35417b6a7..0a0544240e 100644
--- a/frontend-modern/src/__tests__/AppLayout.test.tsx
+++ b/frontend-modern/src/__tests__/AppLayout.test.tsx
@@ -9,7 +9,7 @@ HTMLElement.prototype.scrollIntoView = vi.fn();
describe('AppLayout navigation icons', () => {
beforeEach(() => {
- window.history.replaceState({}, '', '/dashboard');
+ window.history.replaceState({}, '', '/infrastructure');
aiChatStore.close();
aiChatStore.setEnabled(true);
});
@@ -24,7 +24,7 @@ describe('AppLayout navigation icons', () => {
render(() => (
(
({
@@ -58,7 +58,7 @@ describe('AppLayout navigation icons', () => {
showOrgSwitcher={() => false}
onSwitchOrg={() => {}}
>
-
- Replay the five-stop walkthrough of Dashboard, Infrastructure, Workloads, Storage,
- and Recovery.
+ Replay the four-stop walkthrough of Infrastructure, Workloads, Storage, and
+ Recovery.
diff --git a/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx b/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx
index 3ad5988288..d6a39f7527 100644
--- a/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx
+++ b/frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx
@@ -613,8 +613,8 @@ export const InfrastructureInstallerSection: Component = () => {
>
{isConnected()
? state.lookupWasAutoDetected()
- ? `${agent().displayName || agent().hostname} started reporting and Pulse detected it automatically. Open the dashboard to verify your first overview, or open Inventory to inspect this host and add more infrastructure.`
- : `${agent().displayName || agent().hostname} is reporting live telemetry to Pulse. Open the dashboard to verify your first overview, or open Inventory to inspect this host and add more infrastructure.`
+ ? `${agent().displayName || agent().hostname} started reporting and Pulse detected it automatically. Open Infrastructure to inspect this host and add more infrastructure.`
+ : `${agent().displayName || agent().hostname} is reporting live telemetry to Pulse. Open Infrastructure to inspect this host and add more infrastructure.`
: `${agent().displayName || agent().hostname} has been found, but Pulse is not receiving a live check-in yet. Keep the installer running on that machine and check again.`}
@@ -650,10 +650,10 @@ export const InfrastructureInstallerSection: Component = () => {
The URL included in email alerts to link back to Pulse. Required for Docker deployments
with custom ports.
@@ -148,7 +148,7 @@ export const NetworkBoundarySettingsSection: Component
- Allow Pulse to be embedded in iframes (e.g., Homepage dashboard)
+ Allow Pulse to be embedded in iframes (e.g., Homepage)
- Example: If Pulse is at pulse.my.domain and your dashboard is at{' '}
+ Example: If Pulse is at pulse.my.domain and your homepage is at{' '}
my.domain, add https://my.domain here.
diff --git a/frontend-modern/src/components/Settings/NodeModalBasicInfoSection.tsx b/frontend-modern/src/components/Settings/NodeModalBasicInfoSection.tsx
index 78f11105cc..530b146e26 100644
--- a/frontend-modern/src/components/Settings/NodeModalBasicInfoSection.tsx
+++ b/frontend-modern/src/components/Settings/NodeModalBasicInfoSection.tsx
@@ -34,7 +34,7 @@ export const NodeModalBasicInfoSection: Component state.updateField('name', event.currentTarget.value)}
- placeholder="Pulse uses this label across dashboards"
+ placeholder="Pulse uses this label across monitoring views"
required
class={controlClass()}
/>
diff --git a/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx b/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx
index 1a4d721a07..597d448c18 100644
--- a/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx
+++ b/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx
@@ -75,7 +75,7 @@ export const NodeModalMonitoringSection: Component
Control which Proxmox VE resources Pulse ingests. Disable individual collectors to
- reduce API load or trim dashboard noise.
+ reduce API load or trim workload noise.