TenantAtlas/specs/283-provider-capability-registry/tasks.md
ahmido 1debe40ced feat: implement provider capability registry (#342)
## Summary
- implement the provider capability registry and derived capability evaluation flow
- update provider connections, onboarding, required-permissions diagnostics, and provider blocker translation to use capability-first summaries
- add bounded unit, feature, and browser test coverage plus the prepared Spec 283 artifacts

## Notes
- branch: `283-provider-capability-registry`
- commit: `74e75c3e`
- no additional validation commands were run in this git/PR flow step

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #342
2026-05-08 21:17:05 +00:00

235 lines
25 KiB
Markdown

---
description: "Task list for Provider Capability Registry"
---
# Tasks: Provider Capability Registry
**Input**: Design documents from `specs/283-provider-capability-registry/`
**Prerequisites**: `specs/283-provider-capability-registry/spec.md`, `specs/283-provider-capability-registry/plan.md`, `specs/283-provider-capability-registry/checklists/requirements.md`, `specs/283-provider-capability-registry/research.md`, `specs/283-provider-capability-registry/data-model.md`, `specs/283-provider-capability-registry/quickstart.md`, and `specs/283-provider-capability-registry/contracts/provider-capability-registry.logical.openapi.yaml`
**Implementation Posture**: Runtime implementation complete. Targeted unit, feature, browser smoke, and dirty-file formatting validation passed in the implementation loop.
**Tests**: REQUIRED (Pest). Keep proof bounded to `apps/platform/tests/Unit/Providers/ProviderCapabilityRegistryTest.php`, `apps/platform/tests/Unit/Verification/TenantPermissionCapabilityMappingTest.php`, `apps/platform/tests/Feature/Providers/ProviderCapabilityEvaluationTest.php`, `apps/platform/tests/Feature/Providers/ProviderOperationCapabilityGateTest.php`, `apps/platform/tests/Feature/Filament/ProviderConnectionCapabilitySummaryTest.php`, `apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingCapabilityAssistTest.php`, `apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCapabilityGroupingTest.php`, `apps/platform/tests/Feature/SupportDiagnostics/ProviderCapabilityReasonTranslationTest.php`, and `apps/platform/tests/Browser/Spec283ProviderCapabilityRegistrySmokeTest.php`.
**Operations**: No new `OperationRun` family. Reuse `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`, the existing `ProviderOperationStartResultPresenter` path, `OperationUxPresenter`, and the current `OperationRunService` lifecycle ownership. This slice only adds a shared provider capability prerequisite contract over that existing provider-operation path.
**RBAC**: Workspace membership remains the first `404` boundary, managed-environment access remains the second `404` boundary, and current user capability denials such as `PROVIDER_VIEW`, `PROVIDER_MANAGE`, `PROVIDER_MANAGE_DEDICATED`, `PROVIDER_RUN`, `TENANT_MANAGE`, and `TENANT_SYNC` remain `403`. Provider application capability failures remain a distinct derived result and must not be folded into user RBAC.
**Shared Pattern Reuse**: Reuse `ProviderOperationRegistry`, `ProviderOperationStartGate`, `ProviderReasonTranslator`, `ProviderNextStepsRegistry`, `TenantPermissionCheckClusters`, `TenantRequiredPermissionsViewModelBuilder`, `ProviderConnectionSurfaceSummary`, `ProviderConnectionResource`, `TenantRequiredPermissions`, `ManagedTenantOnboardingWizard`, `RequiredPermissionsLinks`, and the current contextual-help or support-diagnostic seams. Do not introduce a provider-capability table, a provider framework, a broader taxonomy, a user RBAC rewrite, route cutover work, copy-neutralization work, or adjacent Spec `284` through `287` scope.
**Filament / Panel Guardrails**: Filament remains v5 on Livewire v4. Provider registration remains in `apps/platform/bootstrap/providers.php`. `ProviderConnectionResource` remains non-globally-searchable while keeping `View` and `Edit` pages. Any touched destructive action must continue to use `->action(...)`, `->requiresConfirmation()`, and current server authorization. Asset strategy stays unchanged.
**Compatibility Posture**: Reject provider-capability persistence, future-facing capability inventories, shared raw Graph permission names as primary vocabulary, user RBAC or route-shell rewrites, and keep Specs `284` through `287` deferred.
**External Prerequisite**: Spec `281` provider-connection-scope groundwork must already be merged or otherwise present on the implementation branch before any runtime or test task starts.
**Organization**: Tasks are grouped by user story so provider-connection summary truth, provider-operation capability gating, onboarding and required-permissions convergence, and support-diagnostic consistency remain independently testable.
**Review Outcome**: `implementation-ready`
**Workflow Outcome**: `keep`
**Test-governance Outcome**: `keep`
## Test Governance Checklist
- [x] Lane assignment stays `fast-feedback`, `confidence`, and one narrow `browser` lane.
- [x] New or changed tests stay in the named unit, feature, and browser files only.
- [x] Workspace, managed-environment, provider-connection, and permission-evidence fixtures remain explicit and opt-in; no hidden shared defaults or provider-capability persistence is planned.
- [x] Planned validation commands match `spec.md`, `plan.md`, and `quickstart.md` exactly.
- [x] `standard-native-filament`, `workflow-hub`, and shared provider-operation expectations stay explicit for touched surfaces.
- [x] Any attempt to absorb Specs `284` through `287` resolves as `split` or `reject-or-split`, not hidden follow-up inside `283`.
## Canonical Initial Capability Inventory
- `provider_connection_check` -> `provider.connection.check`
- `inventory_read` -> `inventory.sync`
- `configuration_read` -> `compliance.snapshot`
- `restore_execute` -> `restore.execute`
- `directory_groups_read` -> `directory.groups.sync`
- `directory_role_definitions_read` -> `directory.role_definitions.sync`
This bounded inventory is authoritative for Spec `283` tasks and must not widen into future-facing capability keys during implementation.
## Phase 0: External Gate
**Purpose**: Confirm the provider-boundary prerequisite from Spec `281` is available before implementation begins.
- [x] T000 Confirm Spec `281` is already merged or otherwise present on the implementation branch before any runtime or test task begins.
---
## Phase 1: Setup (Shared Context)
**Purpose**: Confirm the bounded provider-capability inventory, proof files, and deferred-scope posture before runtime edits begin.
- [x] T001 Review `specs/283-provider-capability-registry/spec.md`, `plan.md`, `checklists/requirements.md`, `research.md`, `data-model.md`, `quickstart.md`, and `contracts/provider-capability-registry.logical.openapi.yaml` together so implementation stays on Spec `283` only.
- [x] T002 [P] Confirm the current provider-connection and Filament guardrail seams in `apps/platform/app/Models/ProviderConnection.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php`, and `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` before changing shared summaries.
- [x] T003 [P] Confirm the current provider-operation seams in `apps/platform/app/Services/Providers/ProviderOperationRegistry.php`, `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`, and any cooperating presenter or result classes that already own blocked-versus-started feedback.
- [x] T004 [P] Confirm the current required-permissions and verification seams in `apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php`, `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php`, and `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php` before changing diagnostic grouping.
- [x] T005 [P] Confirm the current onboarding and supporting-link seams in `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, `apps/platform/app/Support/Links/RequiredPermissionsLinks.php`, and `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php` before capability summaries are introduced.
- [x] T006 [P] Confirm the current provider reason, help, and boundary seams in `apps/platform/app/Support/Providers/ProviderReasonTranslator.php`, `apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php`, `apps/platform/app/Support/ProductKnowledge/ContextualHelpCatalog.php`, `apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php`, `apps/platform/config/provider_boundaries.php`, and `specs/283-provider-capability-registry/checklists/requirements.md` so Specs `284` through `287` remain explicitly out of scope.
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Establish the proving suite and the canonical shared capability contract that every story depends on.
**Critical**: No user-story work should begin until this phase is complete.
- [x] T007 [P] Add failing coverage in `apps/platform/tests/Unit/Providers/ProviderCapabilityRegistryTest.php` for the initial capability inventory, operator-facing labels, provider-owned requirement mappings, and the bounded current-release key set.
- [x] T008 [P] Add failing coverage in `apps/platform/tests/Unit/Verification/TenantPermissionCapabilityMappingTest.php` for mapping current permission-cluster evidence into the shared capability contract without promoting raw Graph permission names into the primary vocabulary.
- [x] T009 [P] Add failing coverage in `apps/platform/tests/Feature/Providers/ProviderCapabilityEvaluationTest.php` for `supported`, `missing`, `blocked`, `unknown`, and `not_applicable` capability results derived from existing provider connection and permission evidence.
- [x] T010 [P] Add failing coverage in `apps/platform/tests/Feature/Providers/ProviderOperationCapabilityGateTest.php` for provider-backed operation types resolving one or more capability keys before the shared start gate allows or blocks the request.
- [x] T011 [P] Add the narrow browser smoke in `apps/platform/tests/Browser/Spec283ProviderCapabilityRegistrySmokeTest.php` for one provider-connection or onboarding flow into required-permissions diagnostics under the live Filament shell.
- [x] T012 Introduce the bounded shared capability contract in the smallest viable support seam under `apps/platform/app/Support/Providers/Capabilities/` and update `apps/platform/config/provider_boundaries.php` only as needed so later story work consumes one canonical capability definition and evaluation path without reopening Specs `284` through `287`.
**Checkpoint**: The proving files exist, the provider-capability contract is explicit, and later stories can reuse one canonical shared capability definition and evaluation path.
---
## Phase 3: User Story 1 - Inspect a provider connection with one capability-first summary (Priority: P1)
**Goal**: Provider-connections list and detail surfaces tell the operator which workflows the current connection supports without forcing raw provider requirements to become the first explanation layer.
**Independent Test**: Open the provider-connections list and one connection detail page for a managed environment, then confirm the default-visible summary shows the relevant workflow capability, its status, and one next step while raw provider evidence stays secondary.
### Tests for User Story 1
- [x] T013 [P] [US1] Extend `apps/platform/tests/Feature/Filament/ProviderConnectionCapabilitySummaryTest.php` after T012 to prove `ProviderConnectionResource` list, view, and edit-adjacent summary surfaces show the shared capability label, capability status, and next step first while keeping raw provider detail nested and preserving workspace or managed-environment `404` versus in-scope capability `403` behavior.
- [x] T014 [P] [US1] Extend `apps/platform/tests/Feature/Providers/ProviderCapabilityEvaluationTest.php` after T012 to prove the same provider connection produces the same capability result for provider-connections summary consumers and later shared consumers.
### Implementation for User Story 1
- [x] T015 [US1] Update the new capability registry and evaluator seam plus `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php` so provider-connection summary adapters can ask for shared capability results without reformatting raw evidence locally.
- [x] T016 [US1] Update `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php`, and `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` so provider-connections surfaces converge on the shared capability-first summary while preserving non-global-search posture and existing confirmation-protected destructive actions.
**Checkpoint**: Provider-connections list and detail surfaces now tell one capability-first story before any raw provider requirement detail is disclosed.
---
## Phase 4: User Story 2 - Start provider work with the same capability contract (Priority: P1)
**Goal**: Provider-backed operations start or block using the same capability keys and status semantics shown on provider-connections and later onboarding or diagnostics surfaces.
**Independent Test**: Trigger one blocked provider-backed action and one allowed provider-backed action, then confirm the start result and any resulting run context use the shared capability contract instead of raw provider requirement names as the primary explanation.
### Tests for User Story 2
- [x] T017 [P] [US2] Extend `apps/platform/tests/Feature/Providers/ProviderOperationCapabilityGateTest.php` after T012 to prove blocked and allowed provider-backed operations evaluate shared capability keys before dispatch, carry the resulting capability context through the shared start path, and keep existing user RBAC denials distinct from provider capability blockers.
- [x] T018 [P] [US2] Extend `apps/platform/tests/Feature/SupportDiagnostics/ProviderCapabilityReasonTranslationTest.php` after T012 to prove missing-permission or blocked-operation translations adopt the same capability vocabulary as the start-gate result.
### Implementation for User Story 2
- [x] T019 [US2] Update `apps/platform/app/Services/Providers/ProviderOperationRegistry.php` so current provider-backed operation types map to explicit provider capability keys in addition to the existing user RBAC capability requirements.
- [x] T020 [US2] Update `apps/platform/app/Services/Providers/ProviderOperationStartGate.php` and any cooperating provider-operation result presenter seams so the shared start path evaluates required provider capability keys, blocks or starts accordingly, and records capability context as shared run metadata.
- [x] T021 [US2] Update `apps/platform/app/Support/Providers/ProviderReasonTranslator.php` and `apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php` only where required so blocked-operation guidance names the missing capability first and routes operators to the existing required-permissions path.
**Checkpoint**: Provider-operation start and blocked flows now carry one capability-first explanation that matches the provider-connections summary contract.
---
## Phase 5: User Story 3 - See the same capability truth in onboarding and required permissions (Priority: P2)
**Goal**: Onboarding readiness and the required-permissions page use the same capability labels and status meanings so operators can move from summary to diagnostic evidence without reinterpreting the blocker.
**Independent Test**: Open onboarding verification for a managed environment with missing provider prerequisites, then open the required-permissions assist and confirm both surfaces use the same capability label and status while keeping raw permission rows as supporting evidence.
### Tests for User Story 3
- [x] T022 [P] [US3] Extend `apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingCapabilityAssistTest.php` after T012 to prove onboarding readiness and the capability assist consume the same capability label, status, and next-step contract as other shared consumers while preserving workspace or managed-environment `404` boundaries for out-of-scope actors.
- [x] T023 [P] [US3] Extend `apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCapabilityGroupingTest.php` after T012 to prove the required-permissions page groups or summarizes row-level evidence under the shared capability headings without hiding the raw provider-owned evidence.
### Implementation for User Story 3
- [x] T024 [US3] Update `apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php` and `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php` so the required-permissions view model can expose shared capability groups plus nested permission evidence.
- [x] T025 [US3] Update `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php` so the page header or primary summary stays capability-first while the existing diagnostic matrix remains the canonical deep dive for raw evidence.
- [x] T026 [US3] Update `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` and confirm `apps/platform/app/Support/Links/RequiredPermissionsLinks.php` only changes if necessary so onboarding readiness, assist flows, and supporting links converge on the shared capability contract.
**Checkpoint**: Onboarding and required-permissions diagnostics now describe the same provider blocker with the same capability vocabulary and evidence hierarchy.
---
## Phase 6: User Story 4 - Translate provider blockers consistently in support surfaces (Priority: P3)
**Goal**: Shared help and support-diagnostic consumers describe provider blockers with the same capability vocabulary used on operator-facing surfaces.
**Independent Test**: Trigger or simulate one provider blocker caused by missing permissions or degraded provider state, then confirm contextual help and support-diagnostic outputs use the same capability-first explanation as the main surfaces.
### Tests for User Story 4
- [x] T027 [P] [US4] Extend `apps/platform/tests/Feature/SupportDiagnostics/ProviderCapabilityReasonTranslationTest.php` after T012 to prove contextual-help or support-diagnostic consumers use the same capability labels and next-step guidance as provider-connections, onboarding, and operation-start flows.
### Implementation for User Story 4
- [x] T028 [US4] Update `apps/platform/app/Support/ProductKnowledge/ContextualHelpCatalog.php`, `apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php`, and any directly touched provider-diagnostic consumer seams so they use the shared capability contract rather than page-local or raw requirement vocabulary. Note: no catalog/resolver code change was required after review; `ProviderReasonTranslator` is the active diagnostic seam for provider blockers in this slice.
**Checkpoint**: Shared help and support-diagnostic outputs now reinforce the same capability-first explanation seen elsewhere.
---
## Phase 7: Polish & Cross-Cutting Validation
**Purpose**: Run the exact bounded proof set, perform the final Filament and provider-boundary review, and confirm the slice stayed inside Spec `283`.
- [x] T029 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/Providers/ProviderCapabilityRegistryTest.php tests/Unit/Verification/TenantPermissionCapabilityMappingTest.php)`.
- [x] T030 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Providers/ProviderCapabilityEvaluationTest.php tests/Feature/Providers/ProviderOperationCapabilityGateTest.php tests/Feature/Filament/ProviderConnectionCapabilitySummaryTest.php tests/Feature/Onboarding/ManagedTenantOnboardingCapabilityAssistTest.php tests/Feature/RequiredPermissions/RequiredPermissionsCapabilityGroupingTest.php tests/Feature/SupportDiagnostics/ProviderCapabilityReasonTranslationTest.php)`.
- [x] T031 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec283ProviderCapabilityRegistrySmokeTest.php)`.
- [x] T032 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)`.
- [x] T033 [P] Review `apps/platform/app/Services/Providers/ProviderOperationRegistry.php`, `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`, `apps/platform/app/Support/Providers/ProviderReasonTranslator.php`, `apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php`, `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php`, `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php`, `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, `apps/platform/app/Support/Links/RequiredPermissionsLinks.php`, `apps/platform/config/provider_boundaries.php`, and `apps/platform/bootstrap/providers.php` to confirm Filament v5 or Livewire v4 compliance, unchanged provider registration location, unchanged asset strategy, preserved destructive-action confirmation plus authorization, truthful non-global-search posture, derived-only capability state, and Specs `284` through `287` staying deferred.
---
## Dependencies & Execution Order
### Phase Dependencies
- **Phase 0 (External Gate)**: no dependencies; complete before implementation starts.
- **Phase 1 (Setup)**: depends on Phase 0.
- **Phase 2 (Foundational)**: depends on Phase 1 and blocks all story work.
- **Phase 3 (US1)**: depends on Phase 2 and establishes the canonical provider-connection capability summary contract.
- **Phase 4 (US2)**: depends on Phase 2 and should ship with or immediately after US1 so provider-operation start results match the provider-connection summary contract.
- **Phase 5 (US3)**: depends on US1 and US2 because onboarding and diagnostics should reuse the final shared capability contract rather than an intermediate one.
- **Phase 6 (US4)**: depends on US2 and US3 so support surfaces inherit the final explanation contract.
- **Phase 7 (Polish)**: depends on all desired user stories being complete.
### User Story Dependencies
- **US1 (P1)**: independently testable after Phase 2 and is the first required increment.
- **US2 (P1)**: independently testable after Phase 2, but should ship after or with US1 because the shared start-gate language should match the summary language.
- **US3 (P2)**: independently testable after US1 and US2 and should follow once the shared capability contract is stable.
- **US4 (P3)**: independently testable after US2 and US3 and closes the remaining explanation drift in support surfaces.
### Within Each User Story
- Write or extend the listed Pest coverage first and make it fail for the intended gap.
- Apply the smallest shared-seam changes needed to satisfy the story without reopening Specs `284` through `287`.
- Re-run the narrowest relevant validation command for that story before moving to the next story.
## Parallel Execution Examples
- **Setup**: T002 through T006 can run in parallel once T000 and T001 set the bounded scope.
- **Foundational**: T007 through T011 can run in parallel before T012 converges the canonical capability contract.
- **US1**: T013 and T014 can run in parallel; T015 and T016 should merge serially around the shared summary and Filament resource files.
- **US2**: T017 and T018 can run in parallel; T019 through T021 should follow serially around the shared provider-operation seams.
- **US3**: T022 and T023 can run in parallel; T024 through T026 should merge serially around the diagnostic and onboarding surfaces.
- **US4**: T027 can run alongside related implementation prep, then T028 finalizes shared help and support alignment.
- **Polish**: T029 through T032 can run in parallel after implementation is complete; T033 should close the bounded-scope review last.
## Implementation Strategy
### Suggested MVP Scope
- MVP = **US1 + US2**. Land the shared capability contract first on provider-connections and provider-operation starts so the most visible workflow decisions stop depending on raw provider requirement language.
### Incremental Delivery
1. Complete Phase 0, Phase 1, and Phase 2.
2. Deliver US1 so provider-connections exposes one capability-first summary contract.
3. Deliver US2 so blocked and allowed provider-backed workflows use the same capability contract.
4. Deliver US3 so onboarding and required-permissions diagnostics inherit the same summary and evidence hierarchy.
5. Deliver US4 so support and contextual-help surfaces stop drifting from the operator-facing explanation.
6. Finish with the exact validation commands and final bounded-scope review in Phase 7.
### Team Strategy
1. Parallelize the failing test work first.
2. Serialize merges around `apps/platform/app/Support/Providers/Capabilities/`, `apps/platform/app/Services/Providers/`, `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, and `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` to avoid conflicting contract-shape edits.
3. Reject any implementation branch that introduces persistence, future-facing capability keys, provider frameworks, RBAC redesign, route-shell rewrites, or adjacent-spec cutover work.
## Deferred Follow-Ups / Non-Goals
- Spec `284` provider-neutral artifact source or taxonomy work
- Spec `285` workspace-first RBAC and environment-access redesign
- Spec `286` broader UI copy, IA, and localization neutralization
- Spec `287` cutover quality gates and no-legacy enforcement beyond this bounded capability slice