{ "version": 1, "rules": [ { "id": "runtime-web-interface-name-link", "category": "resource-launch", "summary": "Runtime resource rows must launch saved or inferred web-interface URLs through the shared name-link template, not a page-local link or separate web column.", "canonical": { "path": "src/components/shared/WebInterfaceNameLink.tsx", "export": "WebInterfaceNameLink" }, "requiredConsumers": [ { "path": "src/components/shared/NodeGroupHeader.tsx" }, { "path": "src/components/Workloads/GuestRow.tsx" }, { "path": "src/features/standalone/AgentsMachinesTable.tsx" }, { "path": "src/features/proxmox/ProxmoxNodesTable.tsx" } ], "forbiddenPatterns": [ { "path": "src/components/Workloads/GuestRow.tsx", "patterns": ["target=\"_blank\"", "rel=\"noopener noreferrer\""] }, { "path": "src/components/shared/NodeGroupHeader.tsx", "patterns": ["target=\"_blank\"", "rel=\"noopener noreferrer\""] }, { "path": "src/features/standalone/AgentsMachinesTable.tsx", "patterns": [ "target=\"_blank\"", "rel=\"noopener noreferrer\"", "AgentMachineWebLinkCell", "data-agent-machine-web-link" ] }, { "path": "src/features/standalone/agentMachineTableModel.ts", "patterns": ["id: 'web'", "label: 'Web'"] }, { "path": "src/features/proxmox/ProxmoxNodesTable.tsx", "patterns": [ "target=\"_blank\"", "rel=\"noopener noreferrer\"", "data-proxmox-host-web-link" ] }, { "path": "src/features/proxmox/proxmoxHostTableModel.ts", "patterns": ["id: 'web'", "label: 'Web'"] } ], "proof": [ "src/components/shared/SharedPrimitives.guardrails.test.ts", "src/components/shared/__tests__/NodeGroupHeader.test.tsx", "src/features/standalone/__tests__/AgentsMachinesTable.test.tsx", "src/components/Workloads/__tests__/GuestRow.test.tsx", "src/features/proxmox/__tests__/ProxmoxNodesTable.test.tsx", "src/features/proxmox/__tests__/proxmoxHostTableModel.test.ts" ] }, { "id": "inline-detail-table-row-shell", "category": "row-detail", "summary": "Platform, workload, and infrastructure inline detail rows must compose the shared row/cell/content shell instead of recreating page-local surface-alt drawer rows.", "canonical": { "path": "src/components/shared/InlineDetailTableRow.tsx", "export": "InlineDetailTableRow" }, "requiredConsumers": [ { "path": "src/components/Infrastructure/UnifiedResourceHostTableCard.tsx" }, { "path": "src/components/Infrastructure/UnifiedResourcePBSTableSection.tsx" }, { "path": "src/components/Infrastructure/UnifiedResourcePMGTableSection.tsx" }, { "path": "src/components/Workloads/WorkloadPanel.tsx" }, { "path": "src/features/docker/DockerAlertsTable.tsx" }, { "path": "src/features/docker/DockerHostsTable.tsx" }, { "path": "src/features/docker/DockerNetworksTable.tsx" }, { "path": "src/features/kubernetes/KubernetesAlertsTable.tsx" }, { "path": "src/features/platformPage/PlatformResourceDetailTableRow.tsx" }, { "path": "src/features/proxmox/ProxmoxCephTable.tsx" }, { "path": "src/features/proxmox/ProxmoxCoverageTable.tsx" }, { "path": "src/features/proxmox/ProxmoxMailGatewayTable.tsx" }, { "path": "src/features/proxmox/ProxmoxNodesTable.tsx" }, { "path": "src/features/truenas/TrueNASAlertsTable.tsx" }, { "path": "src/features/truenas/TrueNASProtectionTable.tsx" }, { "path": "src/features/truenas/TrueNASServicesTable.tsx" }, { "path": "src/features/vmware/VsphereActivityTable.tsx" }, { "path": "src/features/vmware/VsphereAlertsTable.tsx" } ], "forbiddenPatterns": [ { "path": "src/components/Workloads/WorkloadPanel.tsx", "patterns": [ "p-0 border-b border-border bg-surface-alt", "border-b border-border bg-surface-alt p-0" ] }, { "path": "src/features/platformPage/PlatformResourceDetailTableRow.tsx", "patterns": ["border-b border-border bg-surface-alt p-0"] } ], "proof": [ "src/components/shared/SharedPrimitives.guardrails.test.ts", "src/components/shared/__tests__/InlineDetailTableRow.test.tsx", "scripts/shared-template-audit.mjs" ] }, { "id": "table-card-frame-shell", "category": "table-card", "summary": "Product table surfaces must compose TableCard for the shared card frame instead of recreating local overflow-hidden bordered table wrappers.", "canonical": { "path": "src/components/shared/TableCard.tsx", "export": "TableCard" }, "requiredConsumers": [ { "path": "src/components/Infrastructure/UnifiedResourceHostTableCard.tsx" }, { "path": "src/components/Infrastructure/UnifiedResourceServiceInfrastructureCard.tsx" }, { "path": "src/components/Storage/StorageContentCard.tsx" }, { "path": "src/components/Workloads/WorkloadsSurface.tsx" }, { "path": "src/components/Workloads/WorkloadsTable.tsx" }, { "path": "src/features/alerts/AlertHistoryTableSection.tsx" }, { "path": "src/features/platformPage/sharedPlatformPage.tsx" } ], "proof": [ "src/components/shared/SharedPrimitives.guardrails.test.ts", "scripts/shared-template-audit.mjs" ] }, { "id": "table-card-header-shell", "category": "table-card", "summary": "Table-card headers must compose TableCardHeader for title/action/clear chrome instead of recreating local summary-table header aliases.", "canonical": { "path": "src/components/shared/TableCardHeader.tsx", "export": "TableCardHeader" }, "requiredConsumers": [ { "path": "src/components/Infrastructure/UnifiedResourceHostTableCard.tsx" }, { "path": "src/components/Infrastructure/UnifiedResourceServiceInfrastructureCard.tsx" }, { "path": "src/components/Storage/StorageContentCard.tsx" }, { "path": "src/features/platformPage/sharedPlatformPage.tsx" } ], "proof": [ "src/components/shared/SharedPrimitives.guardrails.test.ts", "scripts/shared-template-audit.mjs" ] }, { "id": "platform-table-loading-state", "category": "platform-table-loading-state", "summary": "Platform page and table loading states must compose PlatformTableLoadingState instead of recreating local TableCard status rows.", "canonical": { "path": "src/features/platformPage/sharedPlatformPage.tsx", "export": "PlatformTableLoadingState" }, "requiredConsumers": [ { "path": "src/features/docker/DockerPageSurface.tsx" }, { "path": "src/features/kubernetes/KubernetesPageSurface.tsx" }, { "path": "src/features/proxmox/ProxmoxBackupsTable.tsx" }, { "path": "src/features/proxmox/ProxmoxPageSurface.tsx" }, { "path": "src/features/proxmox/ProxmoxReplicationTable.tsx" }, { "path": "src/features/standalone/StandalonePageSurface.tsx" }, { "path": "src/features/truenas/TrueNASPageSurface.tsx" }, { "path": "src/features/truenas/TrueNASProtectionTable.tsx" }, { "path": "src/features/vmware/VmwarePageSurface.tsx" } ], "proof": [ "src/components/shared/SharedPrimitives.guardrails.test.ts", "src/features/platformPage/__tests__/platformOverviewLayout.guardrails.test.ts", "scripts/shared-template-audit.mjs" ] }, { "id": "platform-error-state", "category": "platform-error-state", "summary": "Platform page and table load failures must compose PlatformErrorState instead of recreating a local EmptyState plus Refresh action.", "canonical": { "path": "src/features/platformPage/sharedPlatformPage.tsx", "export": "PlatformErrorState" }, "requiredConsumers": [ { "path": "src/features/docker/DockerPageSurface.tsx" }, { "path": "src/features/kubernetes/KubernetesPageSurface.tsx" }, { "path": "src/features/proxmox/ProxmoxBackupsTable.tsx" }, { "path": "src/features/proxmox/ProxmoxPageSurface.tsx" }, { "path": "src/features/proxmox/ProxmoxReplicationTable.tsx" }, { "path": "src/features/standalone/StandalonePageSurface.tsx" }, { "path": "src/features/truenas/TrueNASPageSurface.tsx" }, { "path": "src/features/truenas/TrueNASProtectionTable.tsx" }, { "path": "src/features/vmware/VmwarePageSurface.tsx" } ], "proof": [ "src/components/shared/SharedPrimitives.guardrails.test.ts", "src/features/platformPage/__tests__/platformOverviewLayout.guardrails.test.ts", "scripts/shared-template-audit.mjs" ] }, { "id": "platform-section-tabs", "category": "platform-section-tabs", "summary": "Platform page workflow tabs must compose PlatformSectionTabs instead of recreating page-local nav tab bars.", "canonical": { "path": "src/features/platformPage/sharedPlatformPage.tsx", "export": "PlatformSectionTabs" }, "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__/platformOverviewLayout.guardrails.test.ts", "scripts/shared-template-audit.mjs" ] }, { "id": "filter-bar-catalog-shell", "category": "filter-bar", "summary": "Resource-list filter surfaces must compose the shared FilterBar catalog shell instead of recreating page-local filter rows or legacy PageControls decks.", "canonical": { "path": "src/components/shared/FilterBar/FilterBar.tsx", "export": "FilterBar" }, "requiredConsumers": [ { "path": "src/components/Alerts/ThresholdsTable.tsx" }, { "path": "src/components/Settings/AuditLogPanel.tsx" }, { "path": "src/components/Storage/StoragePageControls.tsx" }, { "path": "src/components/Workloads/WorkloadsFilter.tsx" }, { "path": "src/features/alerts/AlertHistoryFiltersCard.tsx" }, { "path": "src/features/platformPage/sharedPlatformPage.tsx" }, { "path": "src/features/proxmox/ProxmoxBackupsTable.tsx" } ], "forbiddenPatterns": [ { "path": "src/components/Storage/StoragePageControls.tsx", "patterns": [ "from '@/components/shared/PageControls'", "