diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md
index 8c2151273..618200dd8 100644
--- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md
+++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md
@@ -217,6 +217,8 @@ puts the same machine on two surfaces that do not share an identity.
131a. `frontend-modern/src/features/platformPage/PlatformResourceDetailTableRow.tsx`
131b. `frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.tsx`
131c. `frontend-modern/src/features/platformPage/PlatformOutdatedSensorSetupNotice.tsx`
+ 131d. `frontend-modern/src/features/platformPage/PlatformEstateOverview.tsx`
+ 131e. `frontend-modern/src/features/platformPage/platformEstateOverviewModel.ts`
132. `frontend-modern/src/utils/platformSupportManifest.generated.ts`
133. `frontend-modern/src/utils/platformSupportManifest.ts`
134. `frontend-modern/src/utils/sourcePlatformOptions.ts`
@@ -2056,6 +2058,21 @@ default` instead of fusing provider and badge text such as
grouped-by-host containers view) sort within groups while grouping itself
stays orthogonal to sort state.
+18. Keep estate orientation on one canonical platform primitive. Proxmox,
+ Docker / Podman, Kubernetes, TrueNAS, VMware vSphere, and Standalone
+ Machines overview surfaces must compose
+ `PlatformEstateOverview.tsx` and pass their already-loaded, platform-scoped
+ canonical resource set into `platformEstateOverviewModel.ts`. The model
+ owns metric definitions, actionable-status classification, spotlight
+ priority, bounded spotlight count, and platform workflow destinations; a
+ platform page may not recreate those rules or retain a provider-only
+ summary. The renderer owns the compact responsive metric frame and
+ spotlight presentation. Its single `platformEstateOverviewVisible`
+ preference is global and browser-persisted, so an operator's Hide or Show
+ choice follows them between platform pages and reloads without initiating
+ another resource fetch. Table-local filters and counts remain separate
+ consumer concerns and must not be promoted into a competing overview.
+
## Forbidden Paths
1. Reinventing table/filter/toggle primitives when a shared version exists
@@ -2080,6 +2097,9 @@ default` instead of fusing provider and badge text such as
`/settings/infrastructure/*` paths back into current settings panels.
Retired aliases must fail route eligibility instead of being kept as
compatibility redirects.
+8. Platform pages implementing local estate metric cards, operational
+ spotlight classifiers, or separate visibility preferences instead of
+ composing the canonical platform estate overview.
## Completion Obligations
diff --git a/docs/release-control/v6/internal/subsystems/registry.json b/docs/release-control/v6/internal/subsystems/registry.json
index 87ef3cc22..d00cd53c5 100644
--- a/docs/release-control/v6/internal/subsystems/registry.json
+++ b/docs/release-control/v6/internal/subsystems/registry.json
@@ -4727,6 +4727,8 @@
"frontend-modern/src/components/Toast/Toast.tsx",
"frontend-modern/src/components/Workloads/nodeDrawerModel.ts",
"frontend-modern/src/features/docker/dockerHostDrawerModel.ts",
+ "frontend-modern/src/features/platformPage/PlatformEstateOverview.tsx",
+ "frontend-modern/src/features/platformPage/platformEstateOverviewModel.ts",
"frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.tsx",
"frontend-modern/src/features/platformPage/PlatformOutdatedSensorSetupNotice.tsx",
"frontend-modern/src/features/platformPage/PlatformResourceDetailTableRow.tsx",
@@ -5240,6 +5242,8 @@
"match_files": [
"frontend-modern/scripts/shared-template-audit.mjs",
"frontend-modern/scripts/shared-template-registry.json",
+ "frontend-modern/src/features/platformPage/PlatformEstateOverview.tsx",
+ "frontend-modern/src/features/platformPage/platformEstateOverviewModel.ts",
"frontend-modern/src/features/platformPage/PlatformOutdatedAgentNotice.tsx",
"frontend-modern/src/features/platformPage/PlatformOutdatedSensorSetupNotice.tsx",
"frontend-modern/src/features/platformPage/PlatformResourceDetailTableRow.tsx",
@@ -5248,7 +5252,10 @@
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
- "frontend-modern/src/components/shared/SharedPrimitives.guardrails.test.ts"
+ "frontend-modern/src/components/shared/SharedPrimitives.guardrails.test.ts",
+ "frontend-modern/src/features/platformPage/__tests__/PlatformEstateOverview.test.tsx",
+ "frontend-modern/src/features/platformPage/__tests__/platformEstateOverviewModel.test.ts",
+ "frontend-modern/src/features/platformPage/__tests__/platformOverviewLayout.guardrails.test.ts"
]
},
{
@@ -7340,11 +7347,13 @@
"frontend-modern/src/features/truenas/TrueNASAlertsTable.tsx",
"frontend-modern/src/features/truenas/TrueNASAppsTable.tsx",
"frontend-modern/src/features/truenas/TrueNASNetworkSharesTable.tsx",
+ "frontend-modern/src/features/truenas/TrueNASPageSurface.tsx",
"frontend-modern/src/features/truenas/TrueNASProtectionTable.tsx",
"frontend-modern/src/features/truenas/TrueNASServicesTable.tsx",
"frontend-modern/src/features/truenas/TrueNASStorageTopologyTable.tsx",
"frontend-modern/src/features/truenas/TrueNASSystemsTable.tsx",
"frontend-modern/src/features/truenas/TrueNASVirtualMachinesTable.tsx",
+ "frontend-modern/src/features/vmware/VmwarePageSurface.tsx",
"frontend-modern/src/features/vmware/VsphereActivityTable.tsx",
"frontend-modern/src/features/vmware/VsphereAlertsTable.tsx",
"frontend-modern/src/features/vmware/VsphereDatastoresTable.tsx",
@@ -7533,11 +7542,13 @@
"frontend-modern/src/features/truenas/TrueNASAlertsTable.tsx",
"frontend-modern/src/features/truenas/TrueNASAppsTable.tsx",
"frontend-modern/src/features/truenas/TrueNASNetworkSharesTable.tsx",
+ "frontend-modern/src/features/truenas/TrueNASPageSurface.tsx",
"frontend-modern/src/features/truenas/TrueNASProtectionTable.tsx",
"frontend-modern/src/features/truenas/TrueNASServicesTable.tsx",
"frontend-modern/src/features/truenas/TrueNASStorageTopologyTable.tsx",
"frontend-modern/src/features/truenas/TrueNASSystemsTable.tsx",
"frontend-modern/src/features/truenas/TrueNASVirtualMachinesTable.tsx",
+ "frontend-modern/src/features/vmware/VmwarePageSurface.tsx",
"frontend-modern/src/features/vmware/VsphereActivityTable.tsx",
"frontend-modern/src/features/vmware/VsphereAlertsTable.tsx",
"frontend-modern/src/features/vmware/VsphereDatastoresTable.tsx",
diff --git a/docs/release-control/v6/internal/subsystems/storage-recovery.md b/docs/release-control/v6/internal/subsystems/storage-recovery.md
index 69a45f83e..1bdf5220e 100644
--- a/docs/release-control/v6/internal/subsystems/storage-recovery.md
+++ b/docs/release-control/v6/internal/subsystems/storage-recovery.md
@@ -403,6 +403,14 @@ Patrol coverage, schedule, finding, and approval state belongs on Patrol-owned
surfaces or explicit Patrol affordances; Proxmox overview must not treat it as
backup coverage, restore readiness, PBS verification/protection proof, or a
replacement for the Proxmox Backups tab and workload Backup column.
+The Proxmox estate-at-a-glance metrics and operational spotlights are likewise
+an adjacent frontend-primitives and unified-resource projection, not backup or
+recovery evidence. `ProxmoxPageSurface` must compose the canonical shared
+platform estate overview with its already-loaded Proxmox resource set rather
+than deriving a Proxmox-only summary. A spotlight may route into the owned
+Storage, Backups, Ceph, or Mail workflows, but it must not imply protection,
+verification, or restore readiness beyond the evidence held by those
+workflow-owned surfaces.
Proxmox backup inventory loading and load-failure chrome is likewise a
frontend-primitives dependency. `ProxmoxBackupsTable` owns the backup API
queries, recovery model, filters, coverage split, and backup-specific error
diff --git a/docs/release-control/v6/internal/subsystems/unified-resources.md b/docs/release-control/v6/internal/subsystems/unified-resources.md
index 1db98929f..7aae64d08 100644
--- a/docs/release-control/v6/internal/subsystems/unified-resources.md
+++ b/docs/release-control/v6/internal/subsystems/unified-resources.md
@@ -274,9 +274,22 @@ about the same disk cannot diverge.
132. `frontend-modern/src/features/vmware/VsphereAlertsTable.tsx`
133. `frontend-modern/src/features/vmware/VsphereDatastoresTable.tsx`
134. `frontend-modern/src/features/vmware/VsphereNetworksTable.tsx`
+135. `frontend-modern/src/features/truenas/TrueNASPageSurface.tsx`
+136. `frontend-modern/src/features/vmware/VmwarePageSurface.tsx`
## Shared Boundaries
+Platform estate orientation consumes the same canonical resource projection as
+the platform's tables. Docker / Podman, Kubernetes, TrueNAS, VMware vSphere,
+Standalone Machines, and the storage/recovery-owned Proxmox surface pass their
+already-loaded scoped resource set into the frontend-primitives-owned
+`platformEstateOverviewModel.ts`; pages must not issue a summary fetch, infer
+membership from a second platform heuristic, or locally reinterpret resource
+status, incidents, alerts, or storage pressure. Unified resources owns the
+identity, type, platform membership, status, and evidence fields supplied to
+that shared model. Frontend primitives owns how those fields become the four
+orientation metrics and bounded operational spotlights.
+
Kubernetes workload presentation is API-native, not generic inventory. Pods,
Deployments, controllers, and autoscalers render under the `/kubernetes/workloads`
workflow tab; legacy object routes such as `/kubernetes/pods`,
@@ -1367,6 +1380,8 @@ served clones. Proof: `TestClonedResourcesPreservePlatformAdmission` and
1. New ad hoc resource-type aliases outside unified resource normalization
2. New duplicate ID normalization logic outside unified resources
3. Reintroducing legacy runtime resource contracts as live truth
+4. Platform page-local resource membership or attention rules for estate
+ overview metrics and spotlights
## Completion Obligations
diff --git a/frontend-modern/browser-verification.json b/frontend-modern/browser-verification.json
index 542716d94..2584a2179 100644
--- a/frontend-modern/browser-verification.json
+++ b/frontend-modern/browser-verification.json
@@ -1,21 +1,37 @@
{
"version": 1,
- "base_sha": "57e08985c37e33dc48e90345afe98c1d7a8f1a31",
- "verified_at": "2026-08-19T15:24:06Z",
+ "base_sha": "2da68787550ca774b0e202591ab542d8e35a688e",
+ "verified_at": "2026-08-19T16:23:24Z",
"result": "passed",
"changed_paths": [
- "frontend-modern/src/features/proxmox/ProxmoxCoverageTable.tsx",
- "frontend-modern/src/features/proxmox/ProxmoxRecoverableTable.tsx",
- "frontend-modern/src/features/proxmox/useProxmoxBackupTableWindowing.ts"
+ "frontend-modern/src/features/docker/DockerPageSurface.tsx",
+ "frontend-modern/src/features/kubernetes/KubernetesPageSurface.tsx",
+ "frontend-modern/src/features/platformPage/PlatformAttentionSummary.tsx",
+ "frontend-modern/src/features/platformPage/PlatformEstateOverview.tsx",
+ "frontend-modern/src/features/platformPage/platformEstateOverviewModel.ts",
+ "frontend-modern/src/features/proxmox/ProxmoxPageSurface.tsx",
+ "frontend-modern/src/features/standalone/StandalonePageSurface.tsx",
+ "frontend-modern/src/features/truenas/TrueNASPageSurface.tsx",
+ "frontend-modern/src/features/vmware/VmwarePageSurface.tsx"
],
"content_sha256": {
- "frontend-modern/src/features/proxmox/ProxmoxCoverageTable.tsx": "82e2164c3190b49a6540531576b598862ce829b353236cc8df6946e4b3fd917d",
- "frontend-modern/src/features/proxmox/ProxmoxRecoverableTable.tsx": "ebf464760597dbb92c172e9b51284578f156ddcae574da87c097a9dd7b6381f3",
- "frontend-modern/src/features/proxmox/useProxmoxBackupTableWindowing.ts": "6e9ba89417d2d664c3a40f0e29922414bbc103e738e9698ea584049c67790fd0"
+ "frontend-modern/src/features/docker/DockerPageSurface.tsx": "5c8eb2147a5442ead798e9e1a3caeaad17413ef8d95f6742276c174deeeaa62d",
+ "frontend-modern/src/features/kubernetes/KubernetesPageSurface.tsx": "3a66c9d684ec6265dda01232228521d77ddc2ff8e35b6958629486c8c99728a9",
+ "frontend-modern/src/features/platformPage/PlatformAttentionSummary.tsx": "deleted",
+ "frontend-modern/src/features/platformPage/PlatformEstateOverview.tsx": "ecf80c58f89b646bc3bde4328634c0718bd5a8a47bf9cd8069d69f6c62ce2ded",
+ "frontend-modern/src/features/platformPage/platformEstateOverviewModel.ts": "eb11afc71a9a1a593c5c7f69890b0893f230b824fa3380f2d51b58338327606a",
+ "frontend-modern/src/features/proxmox/ProxmoxPageSurface.tsx": "c18e370e5c4067cefe7fc46e0ed15d8660b79f04c2dd6b9ecc552d2714007263",
+ "frontend-modern/src/features/standalone/StandalonePageSurface.tsx": "38f2a514a7c8641156acff7fba1cf366c893922532e82a23105648748d44ab3d",
+ "frontend-modern/src/features/truenas/TrueNASPageSurface.tsx": "c842d9c12e4cc6eaffc79b777cae9d0ffae5d68ac50b77985fbeba77e69d3e2d",
+ "frontend-modern/src/features/vmware/VmwarePageSurface.tsx": "d46924006f3b394b89edab2437248402c62ccebaa22266de03358dd69dac6d4a"
},
"routes": [
"/proxmox/overview",
- "/proxmox/backups"
+ "/docker/overview",
+ "/kubernetes/overview",
+ "/truenas/overview",
+ "/vmware/overview",
+ "/standalone/machines"
],
"viewports": [
{
@@ -28,17 +44,17 @@
}
],
"states": [
- "Large Proxmox overview showing 578 workloads across five named six-node clusters and two standalone nodes with no legacy mock aliases",
- "Overview workload table capped at 140 mounted rows while preserving the complete fleet totals and exact filtered results",
- "Backup Coverage showing 581 targets, 1874 restore points, 225 PBS snapshots, and at most 140 mounted rows",
- "Backup By date view preserving day headings and restore artifacts within the same 140-row mounted window",
- "Coverage and By date tables at desktop and 390px narrow widths with continuous table geometry and responsive columns"
+ "Large Proxmox estate overview showing 32 nodes, 578 workloads, five clusters plus two standalone nodes, 104 attention resources, and three bounded operational spotlights",
+ "Canonical visible estate overview on Docker, Kubernetes, TrueNAS, VMware vSphere, and Standalone Machines with exactly four platform-specific metrics on each surface",
+ "Globally hidden estate overview on Docker after choosing Hide on Proxmox and again after a full reload",
+ "Restored visible overview after choosing Show, followed by navigation across every platform surface",
+ "Proxmox overview at 390 by 844 with four metrics, three stacked spotlights, and document scroll width equal to viewport width"
],
"interactions": [
- "Searched the overview for checkout-web-01 and confirmed the exact deep-estate workload appeared in approximately 176ms",
- "Scrolled through the large overview and backup tables to verify continuous window advancement without pagination or load-more controls",
- "Switched between Coverage and By date backup views and confirmed each mounted at most 140 rows",
- "Searched backups for checkout-web-01 and confirmed the exact deep-estate result appeared in approximately 82ms",
- "Reloaded and inspected overview, backup coverage, and backup date states at 1280x720 and 390x844"
+ "Chose Hide on Proxmox, navigated to Docker, and confirmed the shared Show estate overview control replaced the summary",
+ "Reloaded Docker and confirmed the hidden preference persisted before first paint",
+ "Chose Show on Docker and navigated through Docker, Kubernetes, TrueNAS, VMware vSphere, Standalone Machines, and Proxmox to confirm the same canonical component marker",
+ "Inspected the rendered desktop Proxmox estate summary above the existing workload filters and dense inventory table",
+ "Applied a 390 by 844 viewport, verified no horizontal page overflow, captured the stacked responsive state, and reset the viewport"
]
}
diff --git a/frontend-modern/scripts/shared-template-registry.json b/frontend-modern/scripts/shared-template-registry.json
index a6df4ce44..6bbfe025b 100644
--- a/frontend-modern/scripts/shared-template-registry.json
+++ b/frontend-modern/scripts/shared-template-registry.json
@@ -3193,6 +3193,30 @@
"src/components/shared/SharedPrimitives.guardrails.test.ts",
"scripts/shared-template-audit.mjs"
]
+ },
+ {
+ "id": "platform-estate-overview",
+ "category": "platform-overview",
+ "summary": "Every primary platform overview composes one shared estate metric and operational spotlight surface with one global persisted visibility preference.",
+ "canonical": {
+ "path": "src/features/platformPage/PlatformEstateOverview.tsx",
+ "export": "PlatformEstateOverview"
+ },
+ "requiredConsumers": [
+ { "path": "src/features/docker/DockerPageSurface.tsx" },
+ { "path": "src/features/kubernetes/KubernetesPageSurface.tsx" },
+ { "path": "src/features/proxmox/ProxmoxPageSurface.tsx" },
+ { "path": "src/features/standalone/StandalonePageSurface.tsx" },
+ { "path": "src/features/truenas/TrueNASPageSurface.tsx" },
+ { "path": "src/features/vmware/VmwarePageSurface.tsx" }
+ ],
+ "proof": [
+ "src/components/shared/SharedPrimitives.guardrails.test.ts",
+ "src/features/platformPage/__tests__/PlatformEstateOverview.test.tsx",
+ "src/features/platformPage/__tests__/platformEstateOverviewModel.test.ts",
+ "src/features/platformPage/__tests__/platformOverviewLayout.guardrails.test.ts",
+ "scripts/shared-template-audit.mjs"
+ ]
}
],
"patternGuards": [
diff --git a/frontend-modern/src/features/docker/DockerPageSurface.tsx b/frontend-modern/src/features/docker/DockerPageSurface.tsx
index 6390ef0a2..481b800e8 100644
--- a/frontend-modern/src/features/docker/DockerPageSurface.tsx
+++ b/frontend-modern/src/features/docker/DockerPageSurface.tsx
@@ -3,6 +3,7 @@ import { Show, createMemo, createSignal } from 'solid-js';
import BoxIcon from 'lucide-solid/icons/box';
import { ButtonLink } from '@/components/shared/Button';
import { getPlatformIcon } from '@/features/platformPage/platformIcon';
+import { PlatformEstateOverview } from '@/features/platformPage/PlatformEstateOverview';
import { useUnifiedResources } from '@/hooks/useUnifiedResources';
import {
PLATFORM_HEALTH_FILTER_OPTIONS,
@@ -156,14 +157,17 @@ export function DockerPageSurface() {
actionLabel="Open agent upgrade commands"
/>
-
+