Add platform support floor projection

This commit is contained in:
rcourtman
2026-04-25 23:01:01 +01:00
parent acbed82d75
commit 97bf4af36d
15 changed files with 1260 additions and 181 deletions
@@ -14,154 +14,434 @@
"id": "agent",
"family": "Pulse-managed host",
"governance_state": "supported",
"onboarding_paths": ["install-workspace"],
"readiness_stage": "supported",
"primary_mode": "agent-backed",
"onboarding_paths": [
"install-workspace"
],
"canonical_projections": [
"agent",
"storage",
"physical-disk"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "n/a",
"storage": "supported",
"recovery": "n/a",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "supported"
},
"ui_label": "Agent",
"ui_tone": "bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-400",
"aliases": [],
"display_tokens": ["Agent"],
"display_tokens": [
"Agent"
],
"storage_family": "onprem"
},
{
"id": "docker",
"family": "Container runtime",
"governance_state": "supported",
"onboarding_paths": ["install-workspace"],
"readiness_stage": "supported",
"primary_mode": "agent-backed",
"onboarding_paths": [
"install-workspace"
],
"canonical_projections": [
"agent",
"app-container",
"docker-service"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "supported",
"storage": "n/a",
"recovery": "n/a",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "supported"
},
"ui_label": "Containers",
"ui_tone": "bg-sky-100 text-sky-700 dark:bg-sky-900 dark:text-sky-400",
"aliases": [],
"display_tokens": ["Containers", "Docker"],
"display_tokens": [
"Containers",
"Docker"
],
"storage_family": "container"
},
{
"id": "kubernetes",
"family": "Cluster runtime",
"governance_state": "supported",
"onboarding_paths": ["install-workspace"],
"readiness_stage": "supported",
"primary_mode": "agent-backed",
"onboarding_paths": [
"install-workspace"
],
"canonical_projections": [
"k8s-cluster",
"k8s-node",
"pod",
"k8s-deployment"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "supported",
"storage": "n/a",
"recovery": "supported",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "supported"
},
"ui_label": "K8s",
"ui_tone": "bg-cyan-100 text-cyan-700 dark:bg-cyan-900 dark:text-cyan-400",
"aliases": ["k8s"],
"display_tokens": ["K8s", "Kubernetes"],
"aliases": [
"k8s"
],
"display_tokens": [
"K8s",
"Kubernetes"
],
"storage_family": "container"
},
{
"id": "proxmox-pve",
"family": "Proxmox",
"governance_state": "supported",
"onboarding_paths": ["platform-connections"],
"readiness_stage": "supported",
"primary_mode": "api-backed",
"onboarding_paths": [
"platform-connections"
],
"canonical_projections": [
"agent",
"vm",
"system-container",
"storage",
"ceph",
"physical-disk"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "supported",
"storage": "supported",
"recovery": "supported",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "augmentation-only"
},
"ui_label": "PVE",
"ui_tone": "bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-400",
"aliases": ["pve", "proxmox"],
"display_tokens": ["PVE", "Proxmox VE"],
"aliases": [
"pve",
"proxmox"
],
"display_tokens": [
"PVE",
"Proxmox VE"
],
"storage_family": "virtualization"
},
{
"id": "proxmox-pbs",
"family": "Proxmox",
"governance_state": "supported",
"onboarding_paths": ["platform-connections"],
"readiness_stage": "supported",
"primary_mode": "api-backed",
"onboarding_paths": [
"platform-connections"
],
"canonical_projections": [
"pbs",
"storage"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "n/a",
"storage": "supported",
"recovery": "supported",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "read-only"
},
"ui_label": "PBS",
"ui_tone": "bg-indigo-100 text-indigo-700 dark:bg-indigo-900 dark:text-indigo-400",
"aliases": ["pbs"],
"display_tokens": ["PBS", "Proxmox Backup Server"],
"aliases": [
"pbs"
],
"display_tokens": [
"PBS",
"Proxmox Backup Server"
],
"storage_family": "virtualization"
},
{
"id": "proxmox-pmg",
"family": "Proxmox",
"governance_state": "supported",
"onboarding_paths": ["platform-connections"],
"readiness_stage": "supported",
"primary_mode": "api-backed",
"onboarding_paths": [
"platform-connections"
],
"canonical_projections": [
"pmg"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "read-only"
},
"ui_label": "PMG",
"ui_tone": "bg-rose-100 text-rose-700 dark:bg-rose-900 dark:text-rose-400",
"aliases": ["pmg"],
"display_tokens": ["PMG", "Proxmox Mail Gateway"],
"aliases": [
"pmg"
],
"display_tokens": [
"PMG",
"Proxmox Mail Gateway"
],
"storage_family": "virtualization"
},
{
"id": "truenas",
"family": "TrueNAS",
"governance_state": "supported",
"onboarding_paths": ["platform-connections"],
"readiness_stage": "supported",
"primary_mode": "api-backed",
"onboarding_paths": [
"platform-connections"
],
"canonical_projections": [
"agent",
"app-container",
"storage",
"physical-disk"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "supported",
"storage": "supported",
"recovery": "supported",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "supported"
},
"ui_label": "TrueNAS",
"ui_tone": "bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-400",
"aliases": [],
"display_tokens": ["TrueNAS"],
"display_tokens": [
"TrueNAS"
],
"storage_family": "onprem"
},
{
"id": "vmware-vsphere",
"family": "VMware",
"governance_state": "admitted",
"onboarding_paths": ["platform-connections"],
"readiness_stage": "first-lab-ready",
"primary_mode": "api-backed",
"onboarding_paths": [
"platform-connections"
],
"canonical_projections": [
"agent",
"vm",
"storage"
],
"support_floor": {
"setup": "supported",
"visibility": "supported",
"workloads": "supported",
"storage": "supported",
"recovery": "n/a",
"alerts": "supported",
"assistant_read": "supported",
"assistant_control": "read-only"
},
"ui_label": "vSphere",
"ui_tone": "bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300",
"aliases": ["vmware"],
"display_tokens": ["vSphere", "VMware vSphere"],
"aliases": [
"vmware"
],
"display_tokens": [
"vSphere",
"VMware vSphere"
],
"storage_family": "virtualization"
},
{
"id": "unraid",
"family": "Unraid",
"governance_state": "presentation-only",
"readiness_stage": "presentation-only",
"primary_mode": "presentation-only",
"onboarding_paths": [],
"canonical_projections": [],
"support_floor": {
"setup": "n/a",
"visibility": "n/a",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "n/a",
"assistant_read": "n/a",
"assistant_control": "n/a"
},
"ui_label": "Unraid",
"ui_tone": "bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-300",
"aliases": [],
"display_tokens": ["Unraid"],
"display_tokens": [
"Unraid"
],
"storage_family": "onprem"
},
{
"id": "synology-dsm",
"family": "Synology",
"governance_state": "presentation-only",
"readiness_stage": "presentation-only",
"primary_mode": "presentation-only",
"onboarding_paths": [],
"canonical_projections": [],
"support_floor": {
"setup": "n/a",
"visibility": "n/a",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "n/a",
"assistant_read": "n/a",
"assistant_control": "n/a"
},
"ui_label": "Synology",
"ui_tone": "bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300",
"aliases": [],
"display_tokens": ["Synology", "DSM"],
"display_tokens": [
"Synology",
"DSM"
],
"storage_family": "onprem"
},
{
"id": "microsoft-hyperv",
"family": "Hyper-V",
"governance_state": "presentation-only",
"readiness_stage": "presentation-only",
"primary_mode": "presentation-only",
"onboarding_paths": [],
"canonical_projections": [],
"support_floor": {
"setup": "n/a",
"visibility": "n/a",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "n/a",
"assistant_read": "n/a",
"assistant_control": "n/a"
},
"ui_label": "Hyper-V",
"ui_tone": "bg-cyan-100 text-cyan-700 dark:bg-cyan-900 dark:text-cyan-300",
"aliases": ["hyper-v"],
"display_tokens": ["Hyper-V"],
"aliases": [
"hyper-v"
],
"display_tokens": [
"Hyper-V"
],
"storage_family": "virtualization"
},
{
"id": "aws",
"family": "AWS",
"governance_state": "presentation-only",
"readiness_stage": "presentation-only",
"primary_mode": "presentation-only",
"onboarding_paths": [],
"canonical_projections": [],
"support_floor": {
"setup": "n/a",
"visibility": "n/a",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "n/a",
"assistant_read": "n/a",
"assistant_control": "n/a"
},
"ui_label": "AWS",
"ui_tone": "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300",
"aliases": [],
"display_tokens": ["AWS"],
"display_tokens": [
"AWS"
],
"storage_family": "cloud"
},
{
"id": "azure",
"family": "Azure",
"governance_state": "presentation-only",
"readiness_stage": "presentation-only",
"primary_mode": "presentation-only",
"onboarding_paths": [],
"canonical_projections": [],
"support_floor": {
"setup": "n/a",
"visibility": "n/a",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "n/a",
"assistant_read": "n/a",
"assistant_control": "n/a"
},
"ui_label": "Azure",
"ui_tone": "bg-sky-100 text-sky-700 dark:bg-sky-900 dark:text-sky-300",
"aliases": [],
"display_tokens": ["Azure"],
"display_tokens": [
"Azure"
],
"storage_family": "cloud"
},
{
"id": "gcp",
"family": "GCP",
"governance_state": "presentation-only",
"readiness_stage": "presentation-only",
"primary_mode": "presentation-only",
"onboarding_paths": [],
"canonical_projections": [],
"support_floor": {
"setup": "n/a",
"visibility": "n/a",
"workloads": "n/a",
"storage": "n/a",
"recovery": "n/a",
"alerts": "n/a",
"assistant_read": "n/a",
"assistant_control": "n/a"
},
"ui_label": "GCP",
"ui_tone": "bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300",
"aliases": [],
"display_tokens": ["GCP"],
"display_tokens": [
"GCP"
],
"storage_family": "cloud"
}
]
@@ -1,6 +1,6 @@
# Pulse v6 Platform Support Model
Last updated: 2026-04-21
Last updated: 2026-04-25
Status: ACTIVE
This file is the canonical governed model for platform support in Pulse v6.
@@ -221,17 +221,40 @@ Rules:
5. `azure`
6. `gcp`
### Current support rows
Support floor fields are recorded in this order: `setup`, `visibility`,
`workloads`, `storage`, `recovery`, `alerts`, `assistant_read`,
`assistant_control`.
| Platform | Governance | Readiness | Primary mode | Onboarding | Canonical projections | Support floor |
| --- | --- | --- | --- | --- | --- | --- |
| `agent` | `supported` | `supported` | `agent-backed` | `install-workspace` | `agent`, `storage`, `physical-disk` | `setup=supported`; `visibility=supported`; `workloads=n/a`; `storage=supported`; `recovery=n/a`; `alerts=supported`; `assistant_read=supported`; `assistant_control=supported` |
| `docker` | `supported` | `supported` | `agent-backed` | `install-workspace` | `agent`, `app-container`, `docker-service` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=n/a`; `recovery=n/a`; `alerts=supported`; `assistant_read=supported`; `assistant_control=supported` |
| `kubernetes` | `supported` | `supported` | `agent-backed` | `install-workspace` | `k8s-cluster`, `k8s-node`, `pod`, `k8s-deployment` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=n/a`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=supported` |
| `proxmox-pve` | `supported` | `supported` | `api-backed` | `platform-connections` | `agent`, `vm`, `system-container`, `storage`, `ceph`, `physical-disk` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=supported`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=augmentation-only` |
| `proxmox-pbs` | `supported` | `supported` | `api-backed` | `platform-connections` | `pbs`, `storage` | `setup=supported`; `visibility=supported`; `workloads=n/a`; `storage=supported`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=read-only` |
| `proxmox-pmg` | `supported` | `supported` | `api-backed` | `platform-connections` | `pmg` | `setup=supported`; `visibility=supported`; `workloads=n/a`; `storage=n/a`; `recovery=n/a`; `alerts=supported`; `assistant_read=supported`; `assistant_control=read-only` |
| `truenas` | `supported` | `supported` | `api-backed` | `platform-connections` | `agent`, `app-container`, `storage`, `physical-disk` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=supported`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=supported` |
| `vmware-vsphere` | `admitted` | `first-lab-ready` | `api-backed` | `platform-connections` | `agent`, `vm`, `storage` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=supported`; `recovery=n/a`; `alerts=supported`; `assistant_read=supported`; `assistant_control=read-only` |
Presentation-only platform vocabulary uses `governance=presentation-only`,
`readiness=presentation-only`, `primary_mode=presentation-only`, no onboarding
paths, no canonical projections, and `n/a` for every support-floor field.
### Machine-readable projection
`PLATFORM_SUPPORT_MANIFEST.json` is the machine-readable projection of the
supported, admitted, and presentation-only platform vocabulary declared here,
plus the canonical platform-family and onboarding-path classification for
supported and admitted platforms. Tests and shared frontend vocabulary may
consume that manifest, and the tracked frontend projection in
plus the canonical platform-family, readiness-stage, primary-mode,
onboarding-path, projection, and support-floor classification for supported
and admitted platforms. Tests and shared frontend vocabulary may consume that
manifest, and the tracked frontend projection in
`frontend-modern/src/utils/platformSupportManifest.generated.ts` must be
generated from it, but neither projection may introduce platform ids or
governance states or platform families or onboarding paths that are not
declared in this document.
governance states, platform families, readiness stages, primary modes,
onboarding paths, projections, or support-floor claims that are not declared in
this document.
### Runtime variants
+192 -128
View File
@@ -3858,6 +3858,187 @@
"kind": "file"
}
]
},
{
"id": "L21",
"name": "Platform admission execution",
"target_score": 6,
"current_score": 6,
"status": "partial",
"completion": {
"state": "bounded-residual",
"summary": "Platform admission execution now has a first-class governed floor: the platform support manifest carries readiness stage, primary mode, canonical projections, onboarding paths, and per-surface support-floor classification into a generated frontend projection, while VMware vSphere remains admitted at first-lab-ready instead of being mislabeled as fully supported. Live vCenter proof, deeper recovery/control coverage, and future admitted-platform runtime depth remain a named post-RC hardening track.",
"tracking": [
{
"kind": "lane-followup",
"id": "platform-admission-execution-post-rc-hardening"
}
]
},
"blockers": [],
"subsystems": [],
"evidence": [
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/PLATFORM_SUPPORT_MODEL.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/records/vmware-vcenter-phase1-proof-blocked-2026-03-30.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/agent-lifecycle.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/ai-runtime.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/alerts.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/api-contracts.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/frontend-primitives.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/monitoring.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/registry.json",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/storage-recovery.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/unified-resources.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_ALERTS_AND_ASSISTANT_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_API_RUNTIME_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_ONBOARDING_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_PROOF_MATRIX.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_RESOURCE_PROJECTION_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/scripts/canonical-platform-audit.mjs",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/types/__tests__/resource.test.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/__tests__/infrastructureOnboardingPresentation.test.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/__tests__/sourcePlatformOptions.test.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/__tests__/sourcePlatforms.test.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/infrastructureOnboardingPresentation.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/platformSupportManifest.generated.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/platformSupportManifest.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/sourcePlatformOptions.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "frontend-modern/src/utils/sourcePlatforms.ts",
"kind": "file"
},
{
"repo": "pulse",
"path": "internal/api/vmware_handlers.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "internal/mock/platform_support_contract_test.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "internal/monitoring/vmware_poller.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "internal/vmware/provider.go",
"kind": "file"
},
{
"repo": "pulse",
"path": "scripts/release_control/generate_platform_support_frontend_module.py",
"kind": "file"
}
]
}
],
"release_gates": [
@@ -4565,6 +4746,17 @@
],
"subsystem_ids": []
},
{
"id": "platform-admission-execution-post-rc-hardening",
"summary": "Track broader platform-admission execution beyond the current first-lab-ready support-floor projection, including live vCenter proof before VMware can move to supported, recovery/control expansion, and future admitted-platform proof across setup, canonical projections, alerts, assistant read, and bounded control.",
"owner": "project-owner",
"status": "planned",
"recorded_at": "2026-04-25",
"lane_ids": [
"L21"
],
"subsystem_ids": []
},
{
"id": "policy-aware-data-governance-post-rc-hardening",
"summary": "Track broader policy-aware data-governance hardening beyond the current resource-policy floor, including enterprise DLP posture, provider-retention disclosure, non-resource prompt-secret detection, and additional external-model boundary proof where future paid or hosted AI surfaces add new data paths.",
@@ -4615,110 +4807,6 @@
"kind": "file"
}
]
},
{
"id": "platform-admission-execution",
"summary": "The platform support model now governs admission decisions, and VMware vSphere is already the current admitted strategic next-platform direction, but the lane map still underrepresents the cross-surface work needed to carry an admitted first-class platform from architecture lock to a proved support floor across setup, canonical projections, alerts, assistant read, and bounded control classification.",
"owner": "project-owner",
"status": "planned",
"recorded_at": "2026-03-30",
"lane_ids": [
"L6",
"L13",
"L15"
],
"subsystem_ids": [
"ai-runtime",
"alerts",
"api-contracts",
"monitoring",
"storage-recovery",
"unified-resources"
],
"proposed_resolution": "new-lane",
"coverage_impact": 12,
"evidence": [
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/PLATFORM_SUPPORT_MODEL.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/records/vmware-vcenter-phase1-proof-blocked-2026-03-30.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/SOURCE_OF_TRUTH.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/agent-lifecycle.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/ai-runtime.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/alerts.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/monitoring.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/storage-recovery.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/subsystems/unified-resources.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_ALERTS_AND_ASSISTANT_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_API_RUNTIME_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_ONBOARDING_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_PROOF_MATRIX.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_PROOF_RECORD_TEMPLATE.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VCENTER_PHASE1_RESOURCE_PROJECTION_SPEC.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/VMWARE_VSPHERE_PHASE1_EXECUTION_PLAN.md",
"kind": "file"
}
]
}
],
"candidate_lanes": [
@@ -4738,30 +4826,6 @@
"subsystem_ids": [
"agent-lifecycle"
]
},
{
"id": "platform-admission-execution",
"name": "Platform admission execution",
"summary": "Carry admitted first-class platform directions from architecture lock to proved support floors through one governed lane covering shared onboarding, canonical resource projection, support-floor proof, and bounded assistant/control classification, starting with the active VMware vSphere direction.",
"status": "accepted",
"recorded_at": "2026-03-30",
"target_id": "v6-product-lane-expansion",
"current_lane_ids": [
"L6",
"L13",
"L15"
],
"coverage_gap_ids": [
"platform-admission-execution"
],
"subsystem_ids": [
"ai-runtime",
"alerts",
"api-contracts",
"monitoring",
"storage-recovery",
"unified-resources"
]
}
],
"work_claims": [],
@@ -131,6 +131,14 @@ platform-connection lifecycle state. Once a TrueNAS or VMware setup form marks
the connection disabled, lifecycle surfaces must treat a canonical zero-delta
or removal-only preview as a valid save path instead of holding the dialog in
an add-only capacity posture.
The lifecycle-owned onboarding presentation helper must consume the governed
platform support manifest for readiness stage, primary mode, canonical
projections, and support-floor posture.
`frontend-modern/src/utils/infrastructureOnboardingPresentation.ts` may adapt
those facts into source-strategy copy, but it must not turn an admitted
`first-lab-ready` platform such as VMware into a product-level supported
claim, invent platform-local projections, or classify assistant control beyond
the manifest's support-floor row.
## Extension Points
@@ -148,6 +148,11 @@ work extends shared components instead of creating new local variants.
123. `frontend-modern/scripts/header-audit.mjs`
124. `frontend-modern/src/components/Settings/DataHandlingPanel.tsx`
125. `frontend-modern/src/components/Settings/dataHandlingPanelModel.ts`
126. `frontend-modern/scripts/canonical-platform-audit.mjs`
127. `frontend-modern/src/utils/platformSupportManifest.generated.ts`
128. `frontend-modern/src/utils/platformSupportManifest.ts`
129. `frontend-modern/src/utils/sourcePlatformOptions.ts`
130. `frontend-modern/src/utils/sourcePlatforms.ts`
## Shared Boundaries
@@ -157,6 +162,8 @@ work extends shared components instead of creating new local variants.
4. `frontend-modern/src/components/Settings/SecurityAuthPanel.tsx` shared with `security-privacy`: the authentication settings surface is both a security/privacy control surface and a canonical settings-shell presentation boundary.
5. `frontend-modern/src/components/Settings/SecurityOverviewPanel.tsx` shared with `security-privacy`: the security overview settings surface is both a security/privacy control surface and a canonical settings-shell presentation boundary.
6. `frontend-modern/src/stores/aiChat.ts` shared with `ai-runtime`: the assistant drawer and session store is both an AI runtime control surface and a canonical app-shell presentation boundary.
7. `frontend-modern/src/utils/platformSupportManifest.generated.ts` shared with `unified-resources`: the generated platform support projection is both a canonical unified-resource platform union boundary and a shared frontend source/platform vocabulary boundary.
8. `frontend-modern/src/utils/sourcePlatforms.ts` shared with `unified-resources`: the source platform normalizer is both a canonical unified-resource source adapter boundary and a shared frontend source/platform vocabulary boundary.
## Extension Points
@@ -393,6 +393,22 @@
"api-contracts"
]
},
{
"path": "frontend-modern/src/utils/platformSupportManifest.generated.ts",
"rationale": "the generated platform support projection is both a canonical unified-resource platform union boundary and a shared frontend source/platform vocabulary boundary",
"subsystems": [
"frontend-primitives",
"unified-resources"
]
},
{
"path": "frontend-modern/src/utils/sourcePlatforms.ts",
"rationale": "the source platform normalizer is both a canonical unified-resource source adapter boundary and a shared frontend source/platform vocabulary boundary",
"subsystems": [
"frontend-primitives",
"unified-resources"
]
},
{
"path": "internal/api/access_control_handlers.go",
"rationale": "RBAC role and user-assignment handlers are both an organization settings control surface and a canonical API payload contract boundary",
@@ -687,6 +703,7 @@
"frontend-modern/src/utils/clusterEndpointPresentation.ts",
"frontend-modern/src/utils/configuredNodeCapabilityPresentation.ts",
"frontend-modern/src/utils/configuredNodeStatusPresentation.ts",
"frontend-modern/src/utils/infrastructureOnboardingPresentation.ts",
"frontend-modern/src/utils/infrastructureSettingsPresentation.ts",
"frontend-modern/src/utils/nodeModalPresentation.ts",
"frontend-modern/src/utils/proxmoxSettingsPresentation.ts",
@@ -858,6 +875,20 @@
"frontend-modern/src/utils/__tests__/agentInstallCommand.test.ts"
]
},
{
"id": "infrastructure-onboarding-presentation-helper",
"label": "infrastructure onboarding presentation helper proof",
"match_prefixes": [],
"match_files": [
"frontend-modern/src/utils/infrastructureOnboardingPresentation.ts"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts",
"frontend-modern/src/utils/__tests__/infrastructureOnboardingPresentation.test.ts"
]
},
{
"id": "proxmox-lifecycle-client-surface",
"label": "proxmox lifecycle API client proof",
@@ -2859,6 +2890,7 @@
"frontend-modern/src/components/shared/"
],
"owned_files": [
"frontend-modern/scripts/canonical-platform-audit.mjs",
"frontend-modern/scripts/header-audit.mjs",
"frontend-modern/src/components/Settings/AIChatMaintenanceSection.tsx",
"frontend-modern/src/components/Settings/AIModelSelectionSection.tsx",
@@ -2945,12 +2977,16 @@
"frontend-modern/src/utils/discoveryPresentation.ts",
"frontend-modern/src/utils/emptyStatePresentation.ts",
"frontend-modern/src/utils/environmentLockPresentation.ts",
"frontend-modern/src/utils/platformSupportManifest.generated.ts",
"frontend-modern/src/utils/platformSupportManifest.ts",
"frontend-modern/src/utils/problemResourcePresentation.ts",
"frontend-modern/src/utils/reportableResourceTypes.ts",
"frontend-modern/src/utils/reportingPresentation.ts",
"frontend-modern/src/utils/reportingResourceTypes.ts",
"frontend-modern/src/utils/semanticTonePresentation.ts",
"frontend-modern/src/utils/settingsShellPresentation.ts",
"frontend-modern/src/utils/sourcePlatformOptions.ts",
"frontend-modern/src/utils/sourcePlatforms.ts",
"frontend-modern/src/utils/ssoProviderPresentation.ts",
"frontend-modern/src/utils/systemLogsPresentation.ts",
"frontend-modern/src/utils/systemSettingsPresentation.ts",
@@ -3274,6 +3310,25 @@
"frontend-modern/src/utils/__tests__/updatesPresentation.test.ts"
]
},
{
"id": "platform-support-manifest-frontend-projection",
"label": "platform support manifest frontend projection proof",
"match_prefixes": [],
"match_files": [
"frontend-modern/scripts/canonical-platform-audit.mjs",
"frontend-modern/src/utils/platformSupportManifest.generated.ts",
"frontend-modern/src/utils/platformSupportManifest.ts",
"frontend-modern/src/utils/sourcePlatformOptions.ts",
"frontend-modern/src/utils/sourcePlatforms.ts"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"frontend-modern/src/types/__tests__/resource.test.ts",
"frontend-modern/src/utils/__tests__/sourcePlatformOptions.test.ts",
"frontend-modern/src/utils/__tests__/sourcePlatforms.test.ts"
]
},
{
"id": "system-logs-presentation-helper",
"label": "system logs presentation helper proof",
@@ -4841,6 +4896,7 @@
"frontend-modern/src/types/resource.ts",
"frontend-modern/src/utils/agentResources.ts",
"frontend-modern/src/utils/canonicalResourceTypes.ts",
"frontend-modern/src/utils/platformSupportManifest.generated.ts",
"frontend-modern/src/utils/resourceBadgePresentation.ts",
"frontend-modern/src/utils/resourceChangePresentation.ts",
"frontend-modern/src/utils/resourceCorrelationPresentation.ts",
@@ -4851,6 +4907,7 @@
"frontend-modern/src/utils/resourceTypeCompat.ts",
"frontend-modern/src/utils/resourceTypePresentation.ts",
"frontend-modern/src/utils/serviceHealthPresentation.ts",
"frontend-modern/src/utils/sourcePlatforms.ts",
"frontend-modern/src/utils/sourceTypePresentation.ts",
"frontend-modern/src/utils/workloadTypePresentation.ts",
"internal/api/resources.go"
@@ -4998,6 +5055,21 @@
"frontend-modern/src/utils/__tests__/resourceChangePresentation.test.ts"
]
},
{
"id": "platform-support-resource-source-projection",
"label": "platform support resource source projection proof",
"match_prefixes": [],
"match_files": [
"frontend-modern/src/utils/platformSupportManifest.generated.ts",
"frontend-modern/src/utils/sourcePlatforms.ts"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"frontend-modern/src/types/__tests__/resource.test.ts",
"frontend-modern/src/utils/__tests__/sourcePlatforms.test.ts"
]
},
{
"id": "resource-runtime-adapter-helpers",
"label": "resource runtime adapter helper proof",
@@ -100,8 +100,9 @@ cross-source deduplication.
78. `frontend-modern/src/hooks/useUnifiedResources.ts`
79. `frontend-modern/src/types/resource.ts`
80. `frontend-modern/src/utils/sourcePlatforms.ts`
81. `internal/unifiedresources/kubernetes_metric_ids.go`
82. `internal/unifiedresources/policy_posture.go`
81. `frontend-modern/src/utils/platformSupportManifest.generated.ts`
82. `internal/unifiedresources/kubernetes_metric_ids.go`
83. `internal/unifiedresources/policy_posture.go`
## Shared Boundaries
@@ -119,7 +120,9 @@ cross-source deduplication.
12. `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts` shared with `performance-and-scalability`: infrastructure summary chart polling, cache hydration, and summary-state orchestration are both a canonical unified-resource consumer surface and a fleet-scale summary chart hot-path boundary.
13. `frontend-modern/src/components/Infrastructure/useUnifiedResourceTableState.ts` shared with `performance-and-scalability`: unified resource table state, grouping, and windowing are both a canonical unified-resource consumer surface and a fleet-scale performance hot-path boundary.
14. `frontend-modern/src/components/Infrastructure/useUnifiedResourceTableViewportSync.ts` shared with `performance-and-scalability`: unified resource table viewport sync and selected-row reveal are both a canonical unified-resource consumer surface and a fleet-scale performance hot-path boundary.
15. `internal/api/resources.go` shared with `api-contracts`: the unified resource endpoint is both a backend payload contract surface and a unified-resource runtime boundary.
15. `frontend-modern/src/utils/platformSupportManifest.generated.ts` shared with `frontend-primitives`: the generated platform support projection is both a canonical unified-resource platform union boundary and a shared frontend source/platform vocabulary boundary.
16. `frontend-modern/src/utils/sourcePlatforms.ts` shared with `frontend-primitives`: the source platform normalizer is both a canonical unified-resource source adapter boundary and a shared frontend source/platform vocabulary boundary.
17. `internal/api/resources.go` shared with `api-contracts`: the unified resource endpoint is both a backend payload contract surface and a unified-resource runtime boundary.
## Extension Points
@@ -18,6 +18,19 @@ describe('infrastructureOnboardingPresentation', () => {
expect(vmware.label).toBe('VMware vCenter');
expect(vmware.governanceState).toBe('admitted');
expect(vmware.readinessStage).toBe('first-lab-ready');
expect(vmware.primaryMode).toBe('api-backed');
expect(vmware.canonicalProjections).toEqual(['agent', 'vm', 'storage']);
expect(vmware.supportFloor).toMatchObject({
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
});
});
it('frames Pulse Agent as the low-overhead per-machine path for full node-local telemetry', () => {
@@ -8,6 +8,11 @@ import {
resolvePlatformTypeFromSources,
resolveSourceTypeFromSources,
} from '@/utils/sourcePlatforms';
import {
getSourcePlatformCanonicalProjections,
getSourcePlatformReadinessStage,
getSourcePlatformSupportFloor,
} from '@/utils/platformSupportManifest';
describe('sourcePlatforms', () => {
describe('normalizeSourcePlatformKey', () => {
@@ -119,6 +124,23 @@ describe('sourcePlatforms', () => {
});
});
describe('governed platform support projection', () => {
it('keeps admitted VMware on the first-lab-ready support floor', () => {
expect(getSourcePlatformReadinessStage('vmware')).toBe('first-lab-ready');
expect(getSourcePlatformCanonicalProjections('vmware')).toEqual(['agent', 'vm', 'storage']);
expect(getSourcePlatformSupportFloor('vmware')).toMatchObject({
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
});
});
});
describe('resolvePlatformTypeFromSources', () => {
it('prefers canonical platform priority from source arrays', () => {
expect(resolvePlatformTypeFromSources(['agent', 'docker'])).toBe('docker');
@@ -2,6 +2,9 @@ import type { ConnectionType } from '@/api/connections';
import {
getSourcePlatformManifestEntry,
type PlatformGovernanceState,
type PlatformPrimaryMode,
type PlatformReadinessStage,
type PlatformSupportFloor,
} from '@/utils/platformSupportManifest';
export type InfrastructureOnboardingConnectionType = Extract<
@@ -18,6 +21,10 @@ export interface InfrastructureOnboardingProductPresentation {
sourceStrategy: InfrastructureSourceStrategy;
autoDetect: boolean;
governanceState: PlatformGovernanceState;
readinessStage: PlatformReadinessStage;
primaryMode: PlatformPrimaryMode;
canonicalProjections: readonly string[];
supportFloor: PlatformSupportFloor;
defaultSurfaceKeys: readonly string[];
}
@@ -167,6 +174,11 @@ const governanceStateForType = (
return getSourcePlatformManifestEntry(sourcePlatformId)?.governanceState ?? 'supported';
};
const manifestEntryForType = (type: InfrastructureOnboardingConnectionType) => {
const sourcePlatformId = PRODUCT_PRESENTATION[type].sourcePlatformId;
return sourcePlatformId ? getSourcePlatformManifestEntry(sourcePlatformId) : null;
};
const API_PRODUCT_ORDER: InfrastructureOnboardingConnectionType[] = [
'vmware',
'truenas',
@@ -260,11 +272,29 @@ const SOURCE_PICKER_GROUPS: InfrastructureSourcePickerGroupPresentation[] = [
export const getInfrastructureOnboardingProductPresentation = (
type: InfrastructureOnboardingConnectionType,
): InfrastructureOnboardingProductPresentation => ({
type,
...PRODUCT_PRESENTATION[type],
governanceState: governanceStateForType(type),
});
): InfrastructureOnboardingProductPresentation => {
const manifestEntry = manifestEntryForType(type);
return {
type,
...PRODUCT_PRESENTATION[type],
governanceState: manifestEntry?.governanceState ?? governanceStateForType(type),
readinessStage: manifestEntry?.readinessStage ?? 'supported',
primaryMode: manifestEntry?.primaryMode ?? 'agent-backed',
canonicalProjections: manifestEntry?.canonicalProjections ?? ['agent'],
supportFloor:
manifestEntry?.supportFloor ??
({
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
} satisfies PlatformSupportFloor),
};
};
export const getInfrastructureSourceStrategyPresentation = (
strategy: InfrastructureSourceStrategy,
@@ -1,11 +1,11 @@
// This file is generated by scripts/release_control/generate_platform_support_frontend_module.py.
// Do not edit by hand.
// Source: docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json
// Source SHA256: 55c8ab8c350f52aeb9bfa8658ac413b85ef925de54409481f31fbd3a675bf30e
// Source SHA256: 31ea4c3a28507c3d60b40d747b93aadbbf7c5b4b51b546e9e803fb34eb519acd
export const PLATFORM_SUPPORT_MANIFEST_SOURCE = {
path: 'docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json',
sha256: '55c8ab8c350f52aeb9bfa8658ac413b85ef925de54409481f31fbd3a675bf30e',
sha256: '31ea4c3a28507c3d60b40d747b93aadbbf7c5b4b51b546e9e803fb34eb519acd',
} as const;
export const PLATFORM_SUPPORT_MANIFEST = {
schemaVersion: 1,
@@ -23,7 +23,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'agent',
family: 'Pulse-managed host',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'agent-backed',
onboardingPaths: ['install-workspace'],
canonicalProjections: ['agent', 'storage', 'physical-disk'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
uiLabel: 'Agent',
uiTone: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-400',
aliases: [],
@@ -34,7 +47,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'docker',
family: 'Container runtime',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'agent-backed',
onboardingPaths: ['install-workspace'],
canonicalProjections: ['agent', 'app-container', 'docker-service'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'n/a',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
uiLabel: 'Containers',
uiTone: 'bg-sky-100 text-sky-700 dark:bg-sky-900 dark:text-sky-400',
aliases: [],
@@ -45,7 +71,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'kubernetes',
family: 'Cluster runtime',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'agent-backed',
onboardingPaths: ['install-workspace'],
canonicalProjections: ['k8s-cluster', 'k8s-node', 'pod', 'k8s-deployment'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'n/a',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
uiLabel: 'K8s',
uiTone: 'bg-cyan-100 text-cyan-700 dark:bg-cyan-900 dark:text-cyan-400',
aliases: ['k8s'],
@@ -56,7 +95,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'proxmox-pve',
family: 'Proxmox',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'api-backed',
onboardingPaths: ['platform-connections'],
canonicalProjections: ['agent', 'vm', 'system-container', 'storage', 'ceph', 'physical-disk'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'augmentation-only',
},
uiLabel: 'PVE',
uiTone: 'bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-400',
aliases: ['pve', 'proxmox'],
@@ -67,7 +119,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'proxmox-pbs',
family: 'Proxmox',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'api-backed',
onboardingPaths: ['platform-connections'],
canonicalProjections: ['pbs', 'storage'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'supported',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
},
uiLabel: 'PBS',
uiTone: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900 dark:text-indigo-400',
aliases: ['pbs'],
@@ -78,7 +143,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'proxmox-pmg',
family: 'Proxmox',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'api-backed',
onboardingPaths: ['platform-connections'],
canonicalProjections: ['pmg'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
},
uiLabel: 'PMG',
uiTone: 'bg-rose-100 text-rose-700 dark:bg-rose-900 dark:text-rose-400',
aliases: ['pmg'],
@@ -89,7 +167,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'truenas',
family: 'TrueNAS',
governanceState: 'supported',
readinessStage: 'supported',
primaryMode: 'api-backed',
onboardingPaths: ['platform-connections'],
canonicalProjections: ['agent', 'app-container', 'storage', 'physical-disk'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
uiLabel: 'TrueNAS',
uiTone: 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-400',
aliases: [],
@@ -100,7 +191,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'vmware-vsphere',
family: 'VMware',
governanceState: 'admitted',
readinessStage: 'first-lab-ready',
primaryMode: 'api-backed',
onboardingPaths: ['platform-connections'],
canonicalProjections: ['agent', 'vm', 'storage'],
supportFloor: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
},
uiLabel: 'vSphere',
uiTone: 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300',
aliases: ['vmware'],
@@ -111,7 +215,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'unraid',
family: 'Unraid',
governanceState: 'presentation-only',
readinessStage: 'presentation-only',
primaryMode: 'presentation-only',
onboardingPaths: [],
canonicalProjections: [],
supportFloor: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
uiLabel: 'Unraid',
uiTone: 'bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-300',
aliases: [],
@@ -122,7 +239,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'synology-dsm',
family: 'Synology',
governanceState: 'presentation-only',
readinessStage: 'presentation-only',
primaryMode: 'presentation-only',
onboardingPaths: [],
canonicalProjections: [],
supportFloor: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
uiLabel: 'Synology',
uiTone: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300',
aliases: [],
@@ -133,7 +263,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'microsoft-hyperv',
family: 'Hyper-V',
governanceState: 'presentation-only',
readinessStage: 'presentation-only',
primaryMode: 'presentation-only',
onboardingPaths: [],
canonicalProjections: [],
supportFloor: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
uiLabel: 'Hyper-V',
uiTone: 'bg-cyan-100 text-cyan-700 dark:bg-cyan-900 dark:text-cyan-300',
aliases: ['hyper-v'],
@@ -144,7 +287,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'aws',
family: 'AWS',
governanceState: 'presentation-only',
readinessStage: 'presentation-only',
primaryMode: 'presentation-only',
onboardingPaths: [],
canonicalProjections: [],
supportFloor: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
uiLabel: 'AWS',
uiTone: 'bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300',
aliases: [],
@@ -155,7 +311,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'azure',
family: 'Azure',
governanceState: 'presentation-only',
readinessStage: 'presentation-only',
primaryMode: 'presentation-only',
onboardingPaths: [],
canonicalProjections: [],
supportFloor: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
uiLabel: 'Azure',
uiTone: 'bg-sky-100 text-sky-700 dark:bg-sky-900 dark:text-sky-300',
aliases: [],
@@ -166,7 +335,20 @@ export const PLATFORM_SUPPORT_MANIFEST = {
id: 'gcp',
family: 'GCP',
governanceState: 'presentation-only',
readinessStage: 'presentation-only',
primaryMode: 'presentation-only',
onboardingPaths: [],
canonicalProjections: [],
supportFloor: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
uiLabel: 'GCP',
uiTone: 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300',
aliases: [],
@@ -305,6 +487,196 @@ export const SOURCE_PLATFORM_FAMILY = {
azure: 'Azure',
gcp: 'GCP',
} as const;
export const SOURCE_PLATFORM_READINESS_STAGE = {
agent: 'supported',
docker: 'supported',
kubernetes: 'supported',
'proxmox-pve': 'supported',
'proxmox-pbs': 'supported',
'proxmox-pmg': 'supported',
truenas: 'supported',
'vmware-vsphere': 'first-lab-ready',
unraid: 'presentation-only',
'synology-dsm': 'presentation-only',
'microsoft-hyperv': 'presentation-only',
aws: 'presentation-only',
azure: 'presentation-only',
gcp: 'presentation-only',
} as const;
export const SOURCE_PLATFORM_PRIMARY_MODE = {
agent: 'agent-backed',
docker: 'agent-backed',
kubernetes: 'agent-backed',
'proxmox-pve': 'api-backed',
'proxmox-pbs': 'api-backed',
'proxmox-pmg': 'api-backed',
truenas: 'api-backed',
'vmware-vsphere': 'api-backed',
unraid: 'presentation-only',
'synology-dsm': 'presentation-only',
'microsoft-hyperv': 'presentation-only',
aws: 'presentation-only',
azure: 'presentation-only',
gcp: 'presentation-only',
} as const;
export const SOURCE_PLATFORM_CANONICAL_PROJECTIONS = {
agent: ['agent', 'storage', 'physical-disk'],
docker: ['agent', 'app-container', 'docker-service'],
kubernetes: ['k8s-cluster', 'k8s-node', 'pod', 'k8s-deployment'],
'proxmox-pve': ['agent', 'vm', 'system-container', 'storage', 'ceph', 'physical-disk'],
'proxmox-pbs': ['pbs', 'storage'],
'proxmox-pmg': ['pmg'],
truenas: ['agent', 'app-container', 'storage', 'physical-disk'],
'vmware-vsphere': ['agent', 'vm', 'storage'],
unraid: [],
'synology-dsm': [],
'microsoft-hyperv': [],
aws: [],
azure: [],
gcp: [],
} as const;
export const SOURCE_PLATFORM_SUPPORT_FLOOR = {
agent: {
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
docker: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'n/a',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
kubernetes: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'n/a',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
'proxmox-pve': {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'augmentation-only',
},
'proxmox-pbs': {
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'supported',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
},
'proxmox-pmg': {
setup: 'supported',
visibility: 'supported',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
},
truenas: {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'supported',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'supported',
},
'vmware-vsphere': {
setup: 'supported',
visibility: 'supported',
workloads: 'supported',
storage: 'supported',
recovery: 'n/a',
alerts: 'supported',
assistantRead: 'supported',
assistantControl: 'read-only',
},
unraid: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
'synology-dsm': {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
'microsoft-hyperv': {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
aws: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
azure: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
gcp: {
setup: 'n/a',
visibility: 'n/a',
workloads: 'n/a',
storage: 'n/a',
recovery: 'n/a',
alerts: 'n/a',
assistantRead: 'n/a',
assistantControl: 'n/a',
},
} as const;
export const SOURCE_PLATFORM_ONBOARDING_PATHS = {
agent: ['install-workspace'],
docker: ['install-workspace'],
@@ -401,6 +773,12 @@ export const SOURCE_PLATFORM_STORAGE_FAMILY = {
} as const;
export type PlatformGovernanceState =
(typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['governanceState'];
export type PlatformReadinessStage =
(typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['readinessStage'];
export type PlatformPrimaryMode = (typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['primaryMode'];
export type PlatformSupportFloor =
(typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['supportFloor'];
export type PlatformSupportFloorValue = PlatformSupportFloor[keyof PlatformSupportFloor];
export type GeneratedSourcePlatformOnboardingPath =
(typeof SOURCE_PLATFORM_ONBOARDING_PATH_KEYS)[number];
export type SourcePlatformStorageFamily =
@@ -6,6 +6,7 @@ import {
PLATFORM_SUPPORT_MANIFEST_SOURCE,
PRESENTATION_ONLY_PLATFORM_IDS,
PLATFORM_SUPPORT_MANIFEST,
SOURCE_PLATFORM_CANONICAL_PROJECTIONS,
SOURCE_PLATFORM_ONBOARDING_PATH_KEYS,
SOURCE_PLATFORM_ONBOARDING_PATHS,
SOURCE_PLATFORM_PRESENTATION,
@@ -14,11 +15,18 @@ import {
SOURCE_PLATFORM_DISPLAY_TOKENS,
SOURCE_PLATFORM_FAMILY,
SOURCE_PLATFORM_MANIFEST_ENTRIES,
SOURCE_PLATFORM_PRIMARY_MODE,
SOURCE_PLATFORM_READINESS_STAGE,
SOURCE_PLATFORM_STORAGE_FAMILY,
SOURCE_PLATFORM_SUPPORT_FLOOR,
SUPPORTED_PLATFORM_IDS,
type GeneratedKnownSourcePlatform,
type GeneratedSourcePlatformOnboardingPath,
type GeneratedSourcePlatformManifestEntry,
type PlatformPrimaryMode,
type PlatformReadinessStage,
type PlatformSupportFloor,
type PlatformSupportFloorValue,
type PlatformGovernanceState,
type SourcePlatformFamily,
type SourcePlatformStorageFamily,
@@ -28,6 +36,10 @@ export type SourcePlatformManifestEntry = GeneratedSourcePlatformManifestEntry;
export type {
GeneratedKnownSourcePlatform,
GeneratedSourcePlatformOnboardingPath as SourcePlatformOnboardingPath,
PlatformPrimaryMode,
PlatformReadinessStage,
PlatformSupportFloor,
PlatformSupportFloorValue,
PlatformGovernanceState,
SourcePlatformFamily,
SourcePlatformStorageFamily,
@@ -46,6 +58,7 @@ export {
PLATFORM_TYPE_KEYS,
PRESENTATION_ONLY_PLATFORM_IDS,
PLATFORM_SUPPORT_MANIFEST,
SOURCE_PLATFORM_CANONICAL_PROJECTIONS,
SOURCE_PLATFORM_ONBOARDING_PATH_KEYS,
SOURCE_PLATFORM_ONBOARDING_PATHS,
SOURCE_PLATFORM_PRESENTATION,
@@ -54,6 +67,9 @@ export {
SOURCE_PLATFORM_DISPLAY_TOKENS,
SOURCE_PLATFORM_FAMILY,
SOURCE_PLATFORM_MANIFEST_ENTRIES,
SOURCE_PLATFORM_PRIMARY_MODE,
SOURCE_PLATFORM_READINESS_STAGE,
SOURCE_PLATFORM_SUPPORT_FLOOR,
SUPPORTED_PLATFORM_IDS,
};
@@ -76,6 +92,38 @@ export const getSourcePlatformStorageFamily = (
return SOURCE_PLATFORM_STORAGE_FAMILY[manifestPlatform.id];
};
export const getSourcePlatformReadinessStage = (
value: string | null | undefined,
): PlatformReadinessStage | null => {
const manifestPlatform = getSourcePlatformManifestEntry(value);
if (!manifestPlatform) return null;
return SOURCE_PLATFORM_READINESS_STAGE[manifestPlatform.id];
};
export const getSourcePlatformPrimaryMode = (
value: string | null | undefined,
): PlatformPrimaryMode | null => {
const manifestPlatform = getSourcePlatformManifestEntry(value);
if (!manifestPlatform) return null;
return SOURCE_PLATFORM_PRIMARY_MODE[manifestPlatform.id];
};
export const getSourcePlatformCanonicalProjections = (
value: string | null | undefined,
): readonly string[] => {
const manifestPlatform = getSourcePlatformManifestEntry(value);
if (!manifestPlatform) return [];
return SOURCE_PLATFORM_CANONICAL_PROJECTIONS[manifestPlatform.id];
};
export const getSourcePlatformSupportFloor = (
value: string | null | undefined,
): PlatformSupportFloor | null => {
const manifestPlatform = getSourcePlatformManifestEntry(value);
if (!manifestPlatform) return null;
return SOURCE_PLATFORM_SUPPORT_FLOOR[manifestPlatform.id];
};
export const getSourcePlatformOnboardingPaths = (
value: string | null | undefined,
): readonly GeneratedSourcePlatformOnboardingPath[] => {
@@ -26,14 +26,18 @@ type platformSupportManifest struct {
}
type platformSupportManifestEntry struct {
ID string `json:"id"`
GovernanceState string `json:"governance_state"`
OnboardingPaths []string `json:"onboarding_paths"`
UILabel string `json:"ui_label"`
UITone string `json:"ui_tone"`
Aliases []string `json:"aliases"`
DisplayTokens []string `json:"display_tokens"`
StorageFamily string `json:"storage_family"`
ID string `json:"id"`
GovernanceState string `json:"governance_state"`
ReadinessStage string `json:"readiness_stage"`
PrimaryMode string `json:"primary_mode"`
OnboardingPaths []string `json:"onboarding_paths"`
CanonicalProjections []string `json:"canonical_projections"`
SupportFloor map[string]string `json:"support_floor"`
UILabel string `json:"ui_label"`
UITone string `json:"ui_tone"`
Aliases []string `json:"aliases"`
DisplayTokens []string `json:"display_tokens"`
StorageFamily string `json:"storage_family"`
}
func TestPlatformSupportManifestMatchesSupportModel(t *testing.T) {
@@ -126,6 +130,22 @@ func TestVMwareFixturesRemainAdmittedButNotSupported(t *testing.T) {
if !strings.Contains(model, "| `vmware-vsphere` | platform connections to `vCenter` only |") {
t.Fatal("expected platform support model to keep the vmware-vsphere platform-connections admission floor")
}
vmwareManifest := requireManifestPlatform(t, manifest, "vmware-vsphere")
if vmwareManifest.ReadinessStage != "first-lab-ready" {
t.Fatalf("vmware readiness stage = %q, want first-lab-ready", vmwareManifest.ReadinessStage)
}
if vmwareManifest.PrimaryMode != "api-backed" {
t.Fatalf("vmware primary mode = %q, want api-backed", vmwareManifest.PrimaryMode)
}
if diff := diffPlatformSets([]string{"agent", "storage", "vm"}, vmwareManifest.CanonicalProjections); diff != "" {
t.Fatalf("vmware canonical projections drifted from the admission model:\n%s", diff)
}
if got := vmwareManifest.SupportFloor["recovery"]; got != "n/a" {
t.Fatalf("vmware recovery support floor = %q, want n/a", got)
}
if got := vmwareManifest.SupportFloor["assistant_control"]; got != "read-only" {
t.Fatalf("vmware assistant control support floor = %q, want read-only", got)
}
graph := buildFixtureGraph(DefaultConfig, time.Date(2026, time.April, 10, 12, 0, 0, 0, time.UTC))
if len(graph.PlatformFixtures.VMware.Hosts) == 0 {
@@ -475,6 +495,18 @@ func manifestPlatformOnboardingPaths(manifest platformSupportManifest) map[strin
return rows
}
func requireManifestPlatform(t *testing.T, manifest platformSupportManifest, platformID string) platformSupportManifestEntry {
t.Helper()
for _, platform := range manifest.Platforms {
if platform.ID == platformID {
return platform
}
}
t.Fatalf("expected platform support manifest entry for %s", platformID)
return platformSupportManifestEntry{}
}
func requireNonEmptyPlatformList(t *testing.T, platforms []string, label string) []string {
t.Helper()
@@ -20,8 +20,21 @@ DEFAULT_GENERIC_PRESENTATION = {
"tone": "bg-surface-alt text-base-content",
}
VALID_GOVERNANCE_STATES = {"supported", "admitted", "presentation-only"}
VALID_PRIMARY_MODES = {"api-backed", "agent-backed", "hybrid", "presentation-only"}
VALID_READINESS_STAGES = {"supported", "first-lab-ready", "presentation-only"}
VALID_STORAGE_FAMILIES = {"onprem", "container", "virtualization", "cloud"}
VALID_ONBOARDING_PATHS = {"install-workspace", "platform-connections"}
SUPPORT_FLOOR_FIELDS = (
"setup",
"visibility",
"workloads",
"storage",
"recovery",
"alerts",
"assistant_read",
"assistant_control",
)
VALID_SUPPORT_FLOOR_VALUES = {"supported", "augmentation-only", "read-only", "n/a"}
def require_dict(value: Any, label: str) -> dict[str, Any]:
@@ -124,6 +137,61 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
f"{governance_state} platform {platform_id} must declare at least one onboarding path"
)
primary_mode = require_string(record.get("primary_mode"), f"platforms[{index}].primary_mode")
if primary_mode not in VALID_PRIMARY_MODES:
raise ValueError(
f"expected platforms[{index}].primary_mode to be one of {sorted(VALID_PRIMARY_MODES)}"
)
readiness_stage = require_string(
record.get("readiness_stage"), f"platforms[{index}].readiness_stage"
)
if readiness_stage not in VALID_READINESS_STAGES:
raise ValueError(
f"expected platforms[{index}].readiness_stage to be one of "
f"{sorted(VALID_READINESS_STAGES)}"
)
if governance_state == "supported" and readiness_stage != "supported":
raise ValueError(f"supported platform {platform_id} must use readiness_stage supported")
if governance_state == "admitted" and readiness_stage == "supported":
raise ValueError(f"admitted platform {platform_id} must not use readiness_stage supported")
if governance_state == "presentation-only":
if readiness_stage != "presentation-only":
raise ValueError(
f"presentation-only platform {platform_id} must use readiness_stage presentation-only"
)
if primary_mode != "presentation-only":
raise ValueError(
f"presentation-only platform {platform_id} must use primary_mode presentation-only"
)
canonical_projections = unique_preserve_order(
require_string_list(
record.get("canonical_projections"),
f"platforms[{index}].canonical_projections",
)
)
if governance_state != "presentation-only" and not canonical_projections:
raise ValueError(f"{governance_state} platform {platform_id} must declare projections")
if governance_state == "presentation-only" and canonical_projections:
raise ValueError(f"presentation-only platform {platform_id} must not declare projections")
support_floor_record = require_dict(record.get("support_floor"), f"platforms[{index}].support_floor")
support_floor: dict[str, str] = {}
for field in SUPPORT_FLOOR_FIELDS:
value = require_string(
support_floor_record.get(field),
f"platforms[{index}].support_floor.{field}",
)
if value not in VALID_SUPPORT_FLOOR_VALUES:
raise ValueError(
f"expected platforms[{index}].support_floor.{field} to be one of "
f"{sorted(VALID_SUPPORT_FLOOR_VALUES)}"
)
camel_field = field.split("_")[0] + "".join(part.title() for part in field.split("_")[1:])
support_floor[camel_field] = value
if governance_state == "presentation-only" and any(value != "n/a" for value in support_floor.values()):
raise ValueError(f"presentation-only platform {platform_id} support floor must be n/a")
aliases = unique_preserve_order(
[
require_lowercase_identifier(alias, f"platforms[{index}].aliases")
@@ -146,7 +214,11 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
"id": platform_id,
"family": require_string(record.get("family"), f"platforms[{index}].family"),
"governanceState": governance_state,
"readinessStage": readiness_stage,
"primaryMode": primary_mode,
"onboardingPaths": onboarding_paths,
"canonicalProjections": canonical_projections,
"supportFloor": support_floor,
"uiLabel": require_string(record.get("ui_label"), f"platforms[{index}].ui_label"),
"uiTone": require_string(record.get("ui_tone"), f"platforms[{index}].ui_tone"),
"aliases": aliases,
@@ -199,6 +271,18 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
family_by_id = {
platform["id"]: platform["family"] for platform in platforms
}
readiness_stage_by_id = {
platform["id"]: platform["readinessStage"] for platform in platforms
}
primary_mode_by_id = {
platform["id"]: platform["primaryMode"] for platform in platforms
}
canonical_projections_by_id = {
platform["id"]: platform["canonicalProjections"] for platform in platforms
}
support_floor_by_id = {
platform["id"]: platform["supportFloor"] for platform in platforms
}
onboarding_paths_by_id = {
platform["id"]: platform["onboardingPaths"] for platform in platforms
}
@@ -237,6 +321,10 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
"displayTokens": display_tokens,
"onboardingPathKeys": onboarding_path_keys,
"familyById": family_by_id,
"readinessStageById": readiness_stage_by_id,
"primaryModeById": primary_mode_by_id,
"canonicalProjectionsById": canonical_projections_by_id,
"supportFloorById": support_floor_by_id,
"onboardingPathsById": onboarding_paths_by_id,
"presentation": {**presentation, "generic": DEFAULT_GENERIC_PRESENTATION},
"storageFamilyById": storage_family_by_id,
@@ -284,11 +372,22 @@ def render_module(normalized: dict[str, Any], manifest_hash: str) -> str:
render_const("SOURCE_PLATFORM_DISPLAY_TOKENS", normalized["displayTokens"]),
render_const("SOURCE_PLATFORM_ONBOARDING_PATH_KEYS", normalized["onboardingPathKeys"]),
render_const("SOURCE_PLATFORM_FAMILY", normalized["familyById"]),
render_const("SOURCE_PLATFORM_READINESS_STAGE", normalized["readinessStageById"]),
render_const("SOURCE_PLATFORM_PRIMARY_MODE", normalized["primaryModeById"]),
render_const("SOURCE_PLATFORM_CANONICAL_PROJECTIONS", normalized["canonicalProjectionsById"]),
render_const("SOURCE_PLATFORM_SUPPORT_FLOOR", normalized["supportFloorById"]),
render_const("SOURCE_PLATFORM_ONBOARDING_PATHS", normalized["onboardingPathsById"]),
render_const("SOURCE_PLATFORM_PRESENTATION", normalized["presentation"]),
render_const("SOURCE_PLATFORM_STORAGE_FAMILY", normalized["storageFamilyById"]),
"export type PlatformGovernanceState =\n"
" (typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['governanceState'];\n",
"export type PlatformReadinessStage =\n"
" (typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['readinessStage'];\n",
"export type PlatformPrimaryMode =\n"
" (typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['primaryMode'];\n",
"export type PlatformSupportFloor =\n"
" (typeof SOURCE_PLATFORM_MANIFEST_ENTRIES)[number]['supportFloor'];\n",
"export type PlatformSupportFloorValue = PlatformSupportFloor[keyof PlatformSupportFloor];\n",
"export type GeneratedSourcePlatformOnboardingPath =\n"
" (typeof SOURCE_PLATFORM_ONBOARDING_PATH_KEYS)[number];\n",
"export type SourcePlatformStorageFamily =\n"
@@ -84,7 +84,7 @@ class SubsystemLookupTest(unittest.TestCase):
{"v6-rc-cut", "v6-rc-stabilization", "v6-ga-promotion", "v6-product-lane-expansion"},
)
self.assertEqual(result["scope"]["control_plane_repo"], "pulse")
self.assertEqual(result["status_summary"]["lane_count"], 20)
self.assertEqual(result["status_summary"]["lane_count"], 21)
file_entry = result["files"][0]
matches = {match["subsystem"] for match in file_entry["matches"]}