diff --git a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md index bb23d53cf..c424e92d3 100644 --- a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md +++ b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md @@ -30,8 +30,9 @@ management, and fleet control surfaces. 8. `scripts/install.ps1` 9. `frontend-modern/src/api/agentProfiles.ts` 10. `frontend-modern/src/components/Settings/AgentProfilesPanel.tsx` -11. `frontend-modern/src/components/Settings/useAgentProfilesPanelState.ts` -12. `frontend-modern/src/components/Settings/infrastructureOperationsModel.tsx` +11. `frontend-modern/src/components/Settings/agentProfileSettings.ts` +12. `frontend-modern/src/components/Settings/useAgentProfilesPanelState.ts` +13. `frontend-modern/src/components/Settings/infrastructureOperationsModel.tsx` 13. `frontend-modern/src/components/Settings/ConnectionsTable.tsx` 14. `frontend-modern/src/components/Settings/connectionsTableModel.ts` 15. `frontend-modern/src/components/Settings/useConnectionsLedger.ts` @@ -284,7 +285,7 @@ profile and assignment columns, but embedded table framing must route through Approval-gated command execution must expose stable rejection reasons for invalid approval grants so fleet operators can distinguish missing, expired, mismatched, and signature-invalid grants through agent metrics. -9. Add or change profile management, the extracted agent profiles runtime owner, the infrastructure source-manager landing, the pure unified-agent inventory/install model, the connections-ledger workspace shell, the unified ConnectionEditor and its per-type credential slots, route model, shared install section owner, the shared direct-node/discovery infrastructure settings owners plus their model, shared frontend install-command assembly, Proxmox setup/install API transport, TrueNAS platform-connection management, VMware platform-connection management, the shared monitored-system admission preview shell for those platform connections, setup-completion install handoff transport, deploy-fallback manual install transport, and fleet-control presentation through `frontend-modern/src/api/agentProfiles.ts`, `frontend-modern/src/api/nodes.ts`, `frontend-modern/src/components/Settings/AgentProfilesPanel.tsx`, `frontend-modern/src/components/Settings/useAgentProfilesPanelState.ts`, `frontend-modern/src/components/Settings/ConnectionsTable.tsx`, `frontend-modern/src/components/Settings/connectionsTableModel.ts`, `frontend-modern/src/components/Settings/useConnectionsLedger.ts`, `frontend-modern/src/components/Settings/useConnectionRowActions.ts`, `frontend-modern/src/components/Settings/ConnectionEditor/ConnectionEditor.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/AddressProbeStep.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/useConnectionEditor.ts`, `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/NodeCredentialSlot.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/TrueNASCredentialSlot.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/VMwareCredentialSlot.tsx`, `frontend-modern/src/components/Settings/infrastructureOperationsModel.tsx`, `frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx`, `frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx`, `frontend-modern/src/components/Settings/InfrastructureSourceManager.tsx`, `frontend-modern/src/components/Settings/infrastructureWorkspaceModel.ts`, `frontend-modern/src/components/Settings/MonitoredSystemAdmissionPreview.tsx`, `frontend-modern/src/components/Settings/platformConnectionsModel.ts`, `frontend-modern/src/components/Settings/useTrueNASSettingsPanelState.ts`, `frontend-modern/src/components/Settings/useVMwareSettingsPanelState.ts`, `frontend-modern/src/components/Settings/proxmoxSettingsModel.ts`, `frontend-modern/src/components/Settings/ConfiguredNodeTables.tsx`, `frontend-modern/src/components/Settings/SettingsSectionNav.tsx`, `frontend-modern/src/components/Settings/infrastructureSettingsModel.ts`, `frontend-modern/src/components/Settings/useInfrastructureConfiguredNodesState.ts`, `frontend-modern/src/components/Settings/useInfrastructureDiscoveryRuntimeState.ts`, `frontend-modern/src/components/Settings/useInfrastructureInstallState.tsx`, `frontend-modern/src/components/Settings/useInfrastructureOperationsState.tsx`, `frontend-modern/src/components/Settings/useInfrastructureSettingsState.ts`, `frontend-modern/src/components/Settings/nodeModalModel.ts`, `frontend-modern/src/components/Settings/useNodeModalState.ts`, `frontend-modern/src/components/SetupWizard/SetupCompletionPanel.tsx`, and `frontend-modern/src/utils/agentInstallCommand.ts`. Phase 9 retired the legacy reporting/inventory surface (InfrastructureOperationsController, InfrastructureInventorySection, InfrastructureActiveRowDetails, InfrastructureIgnoredRowDetails, InfrastructureStopMonitoringDialog, useInfrastructureReportingState) and the per-type shells (PlatformConnectionsWorkspace, ProxmoxSettingsPanel, ProxmoxDirectWorkspace, ProxmoxConfiguredNodesTable, ProxmoxDirectConnectionsCard, ProxmoxDiscoveryResultsCard, ProxmoxDeleteNodeDialog, ProxmoxNodeModalStack, NodeModal shell, TrueNASSettingsPanel, VMwareSettingsPanel, useProxmoxDirectWorkspaceState); lifecycle extensions must route through the unified aggregator ledger, source-manager cards, and ConnectionEditor credential slots rather than reintroducing those retired surfaces. +9. Add or change profile management, the extracted agent profiles runtime owner, the agent profile settings catalog, the infrastructure source-manager landing, the pure unified-agent inventory/install model, the connections-ledger workspace shell, the unified ConnectionEditor and its per-type credential slots, route model, shared install section owner, the shared direct-node/discovery infrastructure settings owners plus their model, shared frontend install-command assembly, Proxmox setup/install API transport, TrueNAS platform-connection management, VMware platform-connection management, the shared monitored-system admission preview shell for those platform connections, setup-completion install handoff transport, deploy-fallback manual install transport, and fleet-control presentation through `frontend-modern/src/api/agentProfiles.ts`, `frontend-modern/src/api/nodes.ts`, `frontend-modern/src/components/Settings/AgentProfilesPanel.tsx`, `frontend-modern/src/components/Settings/agentProfileSettings.ts`, `frontend-modern/src/components/Settings/useAgentProfilesPanelState.ts`, `frontend-modern/src/components/Settings/ConnectionsTable.tsx`, `frontend-modern/src/components/Settings/connectionsTableModel.ts`, `frontend-modern/src/components/Settings/useConnectionsLedger.ts`, `frontend-modern/src/components/Settings/useConnectionRowActions.ts`, `frontend-modern/src/components/Settings/ConnectionEditor/ConnectionEditor.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/AddressProbeStep.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/useConnectionEditor.ts`, `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/NodeCredentialSlot.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/TrueNASCredentialSlot.tsx`, `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/VMwareCredentialSlot.tsx`, `frontend-modern/src/components/Settings/infrastructureOperationsModel.tsx`, `frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx`, `frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx`, `frontend-modern/src/components/Settings/InfrastructureSourceManager.tsx`, `frontend-modern/src/components/Settings/infrastructureWorkspaceModel.ts`, `frontend-modern/src/components/Settings/MonitoredSystemAdmissionPreview.tsx`, `frontend-modern/src/components/Settings/platformConnectionsModel.ts`, `frontend-modern/src/components/Settings/useTrueNASSettingsPanelState.ts`, `frontend-modern/src/components/Settings/useVMwareSettingsPanelState.ts`, `frontend-modern/src/components/Settings/proxmoxSettingsModel.ts`, `frontend-modern/src/components/Settings/ConfiguredNodeTables.tsx`, `frontend-modern/src/components/Settings/SettingsSectionNav.tsx`, `frontend-modern/src/components/Settings/infrastructureSettingsModel.ts`, `frontend-modern/src/components/Settings/useInfrastructureConfiguredNodesState.ts`, `frontend-modern/src/components/Settings/useInfrastructureDiscoveryRuntimeState.ts`, `frontend-modern/src/components/Settings/useInfrastructureInstallState.tsx`, `frontend-modern/src/components/Settings/useInfrastructureOperationsState.tsx`, `frontend-modern/src/components/Settings/useInfrastructureSettingsState.ts`, `frontend-modern/src/components/Settings/nodeModalModel.ts`, `frontend-modern/src/components/Settings/useNodeModalState.ts`, `frontend-modern/src/components/SetupWizard/SetupCompletionPanel.tsx`, and `frontend-modern/src/utils/agentInstallCommand.ts`. Phase 9 retired the legacy reporting/inventory surface (InfrastructureOperationsController, InfrastructureInventorySection, InfrastructureActiveRowDetails, InfrastructureIgnoredRowDetails, InfrastructureStopMonitoringDialog, useInfrastructureReportingState) and the per-type shells (PlatformConnectionsWorkspace, ProxmoxSettingsPanel, ProxmoxDirectWorkspace, ProxmoxConfiguredNodesTable, ProxmoxDirectConnectionsCard, ProxmoxDiscoveryResultsCard, ProxmoxDeleteNodeDialog, ProxmoxNodeModalStack, NodeModal shell, TrueNASSettingsPanel, VMwareSettingsPanel, useProxmoxDirectWorkspaceState); lifecycle extensions must route through the unified aggregator ledger, source-manager cards, and ConnectionEditor credential slots rather than reintroducing those retired surfaces. Those lifecycle-owned settings hooks may consume websocket state only through `frontend-modern/src/contexts/appRuntime.ts`; they must not import `frontend-modern/src/App.tsx` or recreate root-shell providers. Discovery configuration is part of that same lifecycle-owned workspace boundary. `InfrastructureSourceManager.tsx` must open one canonical discovery editor through `InfrastructureDiscoverySettingsDialog.tsx`, `DiscoverySettingsForm.tsx`, and `discoverySettingsModel.ts`, while the System/Network shell stays limited to network-boundary controls instead of reintroducing a second editable discovery surface. That same workspace boundary now owns the infrastructure source-management toolbar too: the landing page exposes `Add infrastructure`, `Run discovery`, and `Discovery settings` as first-viewport toolbar actions inside the source manager, while governed source rows expose per-source add actions such as `Install Pulse Agent` from the shared catalog. `Detect address` remains inside the single add-flow source picker/probe path rather than a duplicate toolbar action. The same landing boundary may surface setup confidence from the unified rows and discovered candidates, including connected-system count, API coverage, agent coverage, sources that still need an agent, and discovery review state, without creating a second inventory model or provider-specific summary fetch. Source groups must stay in the governed source catalog order instead of re-sorting by current row count, row-level lifecycle entry points must use `Manage` language, and locked agent-install states must show a compact command inventory without raw token placeholders or disabled copy commands until a token exists. Network discovery settings remain safety-critical: automatic scanning must surface the shared-network/subnet warning before operators save scan mode changes. Agent command-execution handoff copy belongs to that same install surface: `InfrastructureInstallerSection.tsx` may expose the Pulse command-execution toggle for Patrol, but the label must describe Patrol remediation rather than reviving `Patrol auto-fix` or implying a paid monitoring-volume gate. Setup-completion handoff belongs to that same single add-flow boundary. The first-run completion screen must keep credentials as the first surfaced object, then present one compact next-step surface that sends operators to Add infrastructure or directly to the Agent handoff; source-choice explanation may live inside that surface, but lifecycle work must not reintroduce a separate setup-wizard tour, duplicate CTA section, or inline install-command owner before the canonical infrastructure workspace. diff --git a/docs/release-control/v6/internal/subsystems/api-contracts.md b/docs/release-control/v6/internal/subsystems/api-contracts.md index 57d9ea5ec..9681a536d 100644 --- a/docs/release-control/v6/internal/subsystems/api-contracts.md +++ b/docs/release-control/v6/internal/subsystems/api-contracts.md @@ -109,6 +109,11 @@ Own canonical runtime payload shapes between backend and frontend. 11. `frontend-modern/src/components/Settings/apiTokenManagerModel.ts` shared with `security-privacy`: the pure API token settings model is both a security/privacy control surface and a canonical API payload contract boundary. 12. `frontend-modern/src/components/Settings/ConnectionEditor/CredentialSlots/NodeCredentialSlot.tsx` shared with `agent-lifecycle`: the inline node credential slot is both an agent lifecycle control surface and a shared API-backed install/setup contract boundary. 13. `frontend-modern/src/components/Settings/infrastructureOperationsModel.tsx` shared with `agent-lifecycle`: the pure infrastructure operations inventory/install model is both an agent fleet lifecycle control surface and an API token, lookup, assignment, and reporting/install contract boundary. + Docker and Podman install-profile labels and descriptions in that shared + model must derive their customer-facing source name from + `frontend-modern/src/utils/sourcePlatforms.ts` rather than page-local + wording, because those install choices set API-token and install-command + expectations for the operator. 13. `frontend-modern/src/components/Settings/NodeModalAuthenticationSection.tsx` shared with `agent-lifecycle`: the node setup authentication section is both an agent lifecycle control surface and a shared API-backed install/setup contract boundary. 16. `frontend-modern/src/components/Settings/NodeModalBasicInfoSection.tsx` shared with `agent-lifecycle`: the node setup basic-info section is both an agent lifecycle control surface and a shared API-backed install/setup contract boundary. 17. `frontend-modern/src/components/Settings/nodeModalModel.ts` shared with `agent-lifecycle`: the pure node setup modal model is both an agent lifecycle control surface and a shared API-backed install/setup contract boundary. diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index 299f03c8c..7bfa762a4 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -1751,6 +1751,11 @@ activation summaries, `DiagnosticsResultsPanel.tsx` and `diagnosticsModel.ts` must own the card composition, label humanization, and typed payload shape, while the shell remains a layout/composition owner and does not reintroduce inline diagnostics fetches or commerce-specific rendering logic. +Diagnostics cards that summarize Docker and Podman agent coverage must use the +shared `docker` source-platform label from +`frontend-modern/src/utils/sourcePlatforms.ts` for their heading and body copy, +so diagnostics results stay aligned with the governed settings/source-platform +vocabulary instead of inventing a local runtime family label. The settings shell registry now also treats extracted feature prop contracts as canonical shell inputs instead of reaching back into feature panels for type diff --git a/docs/release-control/v6/internal/subsystems/registry.json b/docs/release-control/v6/internal/subsystems/registry.json index 2e587f934..258873f71 100644 --- a/docs/release-control/v6/internal/subsystems/registry.json +++ b/docs/release-control/v6/internal/subsystems/registry.json @@ -692,6 +692,7 @@ "frontend-modern/src/components/Infrastructure/deploy/DeployingStep.tsx", "frontend-modern/src/components/Infrastructure/deploy/PreflightStep.tsx", "frontend-modern/src/components/Infrastructure/deploy/ResultsStep.tsx", + "frontend-modern/src/components/Settings/agentProfileSettings.ts", "frontend-modern/src/components/Settings/AgentProfilesPanel.tsx", "frontend-modern/src/components/Settings/ConfiguredNodeTables.tsx", "frontend-modern/src/components/Settings/ConnectionEditor/AddressProbeStep.tsx", @@ -1005,6 +1006,7 @@ "label": "unified agent settings lifecycle proof", "match_prefixes": [], "match_files": [ + "frontend-modern/src/components/Settings/agentProfileSettings.ts", "frontend-modern/src/components/Settings/InfrastructureInstallerSection.tsx", "frontend-modern/src/components/Settings/infrastructureOperationsModel.tsx", "frontend-modern/src/components/Settings/useInfrastructureInstallState.tsx", @@ -1015,7 +1017,8 @@ "exact_files": [ "frontend-modern/src/api/__tests__/agentProfiles.test.ts", "frontend-modern/src/api/__tests__/monitoring.test.ts", - "frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx" + "frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx", + "frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts" ] }, { diff --git a/frontend-modern/src/components/Settings/DiagnosticsResultsPanel.tsx b/frontend-modern/src/components/Settings/DiagnosticsResultsPanel.tsx index 103944989..df5079974 100644 --- a/frontend-modern/src/components/Settings/DiagnosticsResultsPanel.tsx +++ b/frontend-modern/src/components/Settings/DiagnosticsResultsPanel.tsx @@ -24,6 +24,7 @@ import { DIAGNOSTICS_EMPTY_STATE_COPY, DIAGNOSTICS_PANEL_COPY, } from '@/utils/diagnosticsPresentation'; +import { getSourcePlatformLabel } from '@/utils/sourcePlatforms'; import { titleCaseDelimitedLabel } from '@/utils/textPresentation'; import type { CommercialFunnelDimensionBreakdown, @@ -33,6 +34,8 @@ import type { InfrastructureOnboardingStageCounts, } from '@/components/Settings/diagnosticsModel'; +const DOCKER_PODMAN_SOURCE_LABEL = getSourcePlatformLabel('docker'); + const DiagnosticCard: Component<{ children: JSX.Element; icon: Component<{ class?: string }>; @@ -780,8 +783,12 @@ export const DiagnosticsResultsPanel: Component =
-

Container Runtime Agents

-

Agent-backed container runtime monitoring

+

+ {DOCKER_PODMAN_SOURCE_LABEL} agents +

+

+ Agent-backed {DOCKER_PODMAN_SOURCE_LABEL} monitoring +

diff --git a/frontend-modern/src/components/Settings/__tests__/DiagnosticsResultsPanel.test.tsx b/frontend-modern/src/components/Settings/__tests__/DiagnosticsResultsPanel.test.tsx index bd9c6bef7..25b6553f2 100644 --- a/frontend-modern/src/components/Settings/__tests__/DiagnosticsResultsPanel.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/DiagnosticsResultsPanel.test.tsx @@ -153,6 +153,14 @@ describe('DiagnosticsResultsPanel', () => { ], notes: ['More probed addresses miss than detect a supported API-backed platform.'], }, + dockerAgents: { + agentsOnline: 1, + agentsTotal: 2, + agentsReportingVersion: 2, + agentsWithTokenBinding: 1, + agentsWithoutTokenBinding: 1, + agentsNeedingAttention: 1, + }, errors: [], }; @@ -174,5 +182,8 @@ describe('DiagnosticsResultsPanel', () => { expect(screen.getByText('Credentials Opened')).toBeInTheDocument(); expect(screen.getByText('TrueNAS SCALE')).toBeInTheDocument(); expect(screen.getByText('API')).toBeInTheDocument(); + expect(screen.getByText('Docker / Podman agents')).toBeInTheDocument(); + expect(screen.getByText('Agent-backed Docker / Podman monitoring')).toBeInTheDocument(); + expect(screen.queryByText('Container Runtime Agents')).not.toBeInTheDocument(); }); }); diff --git a/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx b/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx index 5eb4e7745..eab29b81e 100644 --- a/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx @@ -164,6 +164,17 @@ describe('infrastructure operations model', () => { expect(autoProfile?.description).toContain('every detected PVE / PBS service'); }); + it('keeps the Docker install profile aligned with the shared Docker and Podman label', () => { + const dockerProfile = INSTALL_PROFILE_OPTIONS.find((option) => option.value === 'docker'); + + expect(dockerProfile).toBeDefined(); + expect(dockerProfile?.label).toBe('Docker / Podman runtime'); + expect(dockerProfile?.description).toBe( + 'Force Docker / Podman monitoring when automatic detection is restricted.', + ); + expect(dockerProfile?.description).not.toContain('container runtime'); + }); + it('keeps Proxmox node profiles explicit about per-node telemetry coverage', () => { const pveProfile = INSTALL_PROFILE_OPTIONS.find((option) => option.value === 'proxmox-pve'); const pbsProfile = INSTALL_PROFILE_OPTIONS.find((option) => option.value === 'proxmox-pbs'); diff --git a/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts b/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts index d30876d7e..251f56ec8 100644 --- a/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts +++ b/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts @@ -28,9 +28,11 @@ import updatesSettingsPanelSource from '../UpdatesSettingsPanel.tsx?raw'; import agentProfilesPanelSource from '../AgentProfilesPanel.tsx?raw'; import infrastructureWorkspaceSource from '../InfrastructureWorkspace.tsx?raw'; import infrastructureInstallerSectionSource from '../InfrastructureInstallerSection.tsx?raw'; +import infrastructureOperationsModelSource from '../infrastructureOperationsModel.tsx?raw'; import infrastructureSourceManagerSource from '../InfrastructureSourceManager.tsx?raw'; import infrastructureSourcePickerSource from '../InfrastructureSourcePicker.tsx?raw'; import infrastructureWorkspaceModelSource from '../infrastructureWorkspaceModel.ts?raw'; +import agentProfileSettingsSource from '../agentProfileSettings.ts?raw'; import connectionsTableSource from '../ConnectionsTable.tsx?raw'; import monitoredSystemAdmissionPreviewSource from '../MonitoredSystemAdmissionPreview.tsx?raw'; import connectionEditorSource from '../ConnectionEditor/ConnectionEditor.tsx?raw'; @@ -241,6 +243,24 @@ describe('settings architecture guardrails', () => { } }); + it('keeps infrastructure Docker and Podman settings copy on shared source-platform labels', () => { + expect(infrastructureOperationsModelSource).toContain("getSourcePlatformLabel('docker')"); + expect(agentProfileSettingsSource).toContain("getSourcePlatformLabel('docker')"); + expect(diagnosticsResultsPanelSource).toContain("getSourcePlatformLabel('docker')"); + + for (const source of [ + infrastructureOperationsModelSource, + agentProfileSettingsSource, + diagnosticsResultsPanelSource, + ]) { + expect(source).not.toContain('Container Runtime Agents'); + expect(source).not.toContain('Agent-backed container runtime monitoring'); + expect(source).not.toContain('Force container runtime monitoring'); + expect(source).not.toContain('Force a specific container runtime'); + expect(source).not.toContain('Docker Runtime'); + } + }); + it('keeps settings native select controls on the shared labelled primitive', () => { const rawSelectUsers = Object.entries(settingsRuntimeSources) .filter(([, source]) => source.includes('