TenantAtlas/specs/281-provider-connection-scope/tasks.md
Ahmed Darrazi 19132dc433
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m28s
feat: normalize provider connection scope contracts
2026-05-07 21:27:15 +02:00

215 lines
26 KiB
Markdown

---
description: "Task list for Provider Connection Scope & Microsoft Profile Extraction"
---
# Tasks: Provider Connection Scope & Microsoft Profile Extraction
**Input**: Design documents from `specs/281-provider-connection-scope/`
**Prerequisites**: `specs/281-provider-connection-scope/spec.md`, `specs/281-provider-connection-scope/plan.md`, `specs/281-provider-connection-scope/checklists/requirements.md`, `specs/281-provider-connection-scope/research.md`, `specs/281-provider-connection-scope/data-model.md`, `specs/281-provider-connection-scope/quickstart.md`, and `specs/281-provider-connection-scope/contracts/provider-connection-scope.logical.openapi.yaml`
**Implementation Posture**: Runtime work, targeted test execution, browser smoke, and dirty-file formatting validation have been completed for this package.
**Tests**: REQUIRED (Pest). Keep proof bounded to `apps/platform/tests/Feature/Providers/ProviderConnectionTargetScopeNeutralityTest.php`, `apps/platform/tests/Feature/Providers/ProviderIdentityResolutionNeutralityTest.php`, `apps/platform/tests/Feature/Providers/ProviderOperationStartGateTargetScopeContextTest.php`, `apps/platform/tests/Feature/Filament/ProviderConnectionResourceScopeSummaryTest.php`, `apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingProviderConnectionScopeTest.php`, `apps/platform/tests/Feature/Guards/ProviderConnectionMicrosoftScopeLeakGuardTest.php`, and `apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.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 changes the shared target-scope and identity context carried through that existing provider-operation path.
**RBAC**: Workspace membership remains the first `404` boundary, managed-environment access remains the second `404` boundary, and `PROVIDER_VIEW`, `PROVIDER_MANAGE`, `PROVIDER_MANAGE_DEDICATED`, and `PROVIDER_RUN` denials remain `403`.
**Shared Pattern Reuse**: Reuse `ProviderConnectionTargetScopeDescriptor`, `ProviderConnectionTargetScopeNormalizer`, `ProviderConnectionSurfaceSummary`, `ProviderConnectionResolver`, `ProviderIdentityResolution`, `ProviderOperationStartGate`, `ProviderConnectionResource`, and `ManagedTenantOnboardingWizard`. Do not introduce app-wide provider frameworks, provider-profile tables, capability registries, artifact taxonomy work, RBAC redesign, routing cutover work, or copy-neutralization work.
**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 shared `tenantContext` as canonical platform-core naming, reject shared `target_scope.entra_tenant_id`, reject dual-write compatibility aliases for Microsoft-shaped shared truth, and keep Specs `282` through `287` deferred.
**Organization**: Tasks are grouped by user story so provider-connection summary truth, provider-operation context, onboarding convergence, and managed-environment related-context drill-in stay 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 feature and browser files only.
- [x] Workspace, managed-environment, provider-connection, optional credential, and run fixtures remain explicit and opt-in; no new defaults, registry setup, or provider-profile persistence is planned.
- [x] Planned validation commands match `spec.md`, `plan.md`, and `quickstart.md` exactly.
- [x] `standard-native-filament`, `workflow-hub`, and `global-context-shell` expectations stay explicit for touched surfaces.
- [x] Any attempt to absorb Specs `282` through `287` resolves as `split` or `reject-or-split`, not hidden follow-up inside `281`.
## Phase 1: Setup (Shared Context)
**Purpose**: Confirm the bounded provider-boundary inventory, the proof files, and the explicit deferred-scope posture before implementation begins.
- [x] T001 Review `specs/281-provider-connection-scope/spec.md`, `specs/281-provider-connection-scope/plan.md`, `specs/281-provider-connection-scope/checklists/requirements.md`, `specs/281-provider-connection-scope/research.md`, `specs/281-provider-connection-scope/data-model.md`, `specs/281-provider-connection-scope/quickstart.md`, and `specs/281-provider-connection-scope/contracts/provider-connection-scope.logical.openapi.yaml` together so implementation stays on Spec `281` only.
- [x] T002 [P] Confirm the current persisted-truth 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 shared target-scope and surface-summary seams in `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php`, `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeNormalizer.php`, `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php`, and `apps/platform/app/Support/Providers/TargetScope/ProviderIdentityContextMetadata.php`.
- [x] T004 [P] Confirm the current provider-resolution and identity-result seams in `apps/platform/app/Services/Providers/ProviderConnectionResolver.php`, `apps/platform/app/Services/Providers/ProviderConnectionResolution.php`, `apps/platform/app/Services/Providers/ProviderIdentityResolver.php`, `apps/platform/app/Services/Providers/ProviderIdentityResolution.php`, `apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php`, and `apps/platform/app/Services/Providers/CredentialManager.php`.
- [x] T005 [P] Confirm the current provider-operation and provider-owned consumer seams in `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`, `apps/platform/app/Services/Providers/AdminConsentUrlFactory.php`, `apps/platform/app/Support/Links/RequiredPermissionsLinks.php`, and `apps/platform/app/Services/Providers/ProviderGateway.php`.
- [x] T006 [P] Confirm the current provider-boundary classification and deferred-scope limits in `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php`, `apps/platform/config/provider_boundaries.php`, `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, `apps/platform/app/Filament/Resources/TenantResource.php`, and `specs/281-provider-connection-scope/checklists/requirements.md` so Specs `282` through `287` remain explicitly out of scope.
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Establish the proving suite and the canonical shared target-scope or provider-boundary ownership 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/Feature/Providers/ProviderConnectionTargetScopeNeutralityTest.php` for the neutral target-scope contract across `ProviderConnectionResolver`, `ProviderConnectionSurfaceSummary`, and `ProviderOperationStartGate` so the same provider connection does not produce parallel Microsoft-shaped shared truth.
- [x] T008 [P] Add failing coverage in `apps/platform/tests/Feature/Providers/ProviderIdentityResolutionNeutralityTest.php` for the `ProviderIdentityResolution` contract shift away from shared `tenantContext` naming and toward `target_scope`, effective client identity, credential source, blocked reason, and nested provider context.
- [x] T009 [P] Add failing coverage in `apps/platform/tests/Feature/Providers/ProviderOperationStartGateTargetScopeContextTest.php` for started and blocked provider operations to use neutral shared `target_scope` context plus nested provider context instead of shared `target_scope.entra_tenant_id`.
- [x] T010 [P] Add failing guard coverage in `apps/platform/tests/Feature/Guards/ProviderConnectionMicrosoftScopeLeakGuardTest.php` for Microsoft-shaped shared-contract regressions, including shared `tenantContext`, shared `target_scope.entra_tenant_id`, or new compatibility aliases reappearing in platform-core seams.
- [x] T011 [P] Add the narrow browser smoke in `apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php` for the managed-environment related-context entry, the provider-connections detail summary, and onboarding summary continuity under the live Filament shell.
- [x] T012 Reconcile shared seam ownership in `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php`, `apps/platform/config/provider_boundaries.php`, `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php`, `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeNormalizer.php`, and `apps/platform/app/Support/Providers/TargetScope/ProviderIdentityContextMetadata.php` so later story work consumes one canonical neutral `target_scope` contract and keeps Microsoft profile detail nested.
**Checkpoint**: The proving suite exists, the platform-core versus provider-owned boundary is explicit, and later stories can reuse one canonical neutral target-scope contract without reopening Specs `282` through `287`.
---
## Phase 3: User Story 1 - Inspect a provider connection with one neutral target-scope summary (Priority: P1)
**Goal**: Provider-connections list and detail surfaces tell the operator immediately which managed environment and target scope a connection represents without forcing Microsoft-specific field names into the shared summary.
**Independent Test**: Open the provider-connections list and one connection detail page for a managed environment, then confirm the default-visible summary shows provider, target scope, and health first while Microsoft profile detail stays nested under provider-owned disclosure.
### Tests for User Story 1
- [x] T013 [P] [US1] Extend `apps/platform/tests/Feature/Providers/ProviderConnectionTargetScopeNeutralityTest.php` after T012 to prove `ProviderConnectionResolver` and `ProviderConnectionSurfaceSummary` return the same neutral `target_scope` contract for valid, blocked, and review-needed connections without depending on shared `entra_tenant_id` naming.
- [x] T014 [P] [US1] Extend `apps/platform/tests/Feature/Filament/ProviderConnectionResourceScopeSummaryTest.php` after T012 to prove `ProviderConnectionResource` list, view, and edit context surfaces show provider, target scope, lifecycle, consent, and verification first, keep provider-owned Microsoft profile detail secondary, and remain non-globally-searchable with `View` and `Edit` destinations intact.
### Implementation for User Story 1
- [x] T015 [US1] Update `apps/platform/app/Services/Providers/ProviderConnectionResolver.php` and `apps/platform/app/Services/Providers/ProviderConnectionResolution.php` so the platform-core connection-resolution contract publishes the canonical neutral `target_scope` descriptor instead of shared Microsoft-shaped naming.
- [x] T016 [US1] Update `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php` and `apps/platform/app/Models/ProviderConnection.php` only as needed so target-scope summary text derives from the canonical descriptor and still handles invalid or review-needed scope states explicitly.
- [x] T017 [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 summary adapter, keep provider profile or context detail nested, and preserve current confirmation-protected destructive actions.
**Checkpoint**: Provider-connections list and detail surfaces now tell one neutral target-scope story before any provider-specific profile detail is disclosed.
---
## Phase 4: User Story 2 - Start provider work without Microsoft-shaped shared run context (Priority: P1)
**Goal**: Provider-backed operations started from provider-connections or onboarding surfaces record neutral shared target-scope context so later run follow-up, audit, and support flows do not depend on Microsoft-only keys.
**Independent Test**: Start one provider-backed operation from a provider connection and verify that the resulting run can be identified by provider connection and target scope without relying on shared `target_scope.entra_tenant_id`.
### Tests for User Story 2
- [x] T018 [P] [US2] Extend `apps/platform/tests/Feature/Providers/ProviderIdentityResolutionNeutralityTest.php` after T012 to prove shared identity results no longer expose `tenantContext` as platform-core truth and instead expose `target_scope`, effective client identity, credential source, blocked reason, and nested provider context across platform and dedicated credential paths.
- [x] T019 [P] [US2] Extend `apps/platform/tests/Feature/Providers/ProviderOperationStartGateTargetScopeContextTest.php` after T012 to prove started and blocked results record neutral `target_scope` plus nested provider context details and never require shared `target_scope.entra_tenant_id`.
### Implementation for User Story 2
- [x] T020 [US2] Update `apps/platform/app/Services/Providers/ProviderIdentityResolution.php`, `apps/platform/app/Services/Providers/ProviderIdentityResolver.php`, and `apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php` so the canonical shared identity contract shifts away from `tenantContext` naming while preserving provider-owned Microsoft detail as nested context only.
- [x] T021 [US2] Update `apps/platform/app/Services/Providers/ProviderOperationStartGate.php` and `apps/platform/app/Support/Providers/TargetScope/ProviderIdentityContextMetadata.php` so shared `OperationRun` context, blocked or start feedback, and shared audit metadata carry the canonical neutral `target_scope` descriptor plus nested provider context.
- [x] T022 [US2] Update `apps/platform/app/Services/Providers/CredentialManager.php`, `apps/platform/app/Services/Providers/AdminConsentUrlFactory.php`, and `apps/platform/app/Services/Providers/ProviderGateway.php` only where required to consume the shifted identity contract without reintroducing shared `tenantContext` or shared `target_scope.entra_tenant_id` aliases.
**Checkpoint**: Provider-operation start and blocked flows now carry one neutral shared run-context contract, with Microsoft detail available only through nested provider-owned context.
---
## Phase 5: User Story 3 - See the same connection story in onboarding and provider settings (Priority: P2)
**Goal**: The onboarding wizard describes provider connections with the same target-scope summary used on the provider-connections resource so operators do not need to reinterpret the same connection in a second vocabulary.
**Independent Test**: Select or create a provider connection from onboarding and confirm that the displayed target-scope summary matches the one shown on the provider-connections resource for the same record.
### Tests for User Story 3
- [x] T023 [P] [US3] Extend `apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingProviderConnectionScopeTest.php` after T012 to prove onboarding option lists and selected-connection readiness reuse the same `ProviderConnectionSurfaceSummary` target-scope contract as the provider-connections resource for the same record, and that provider-owned required-permissions guidance stays nested under `permission_overview.required_permissions_url` rather than becoming a second shared summary path.
### Implementation for User Story 3
- [x] T024 [US3] Update `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` and confirm `apps/platform/app/Support/Links/RequiredPermissionsLinks.php` required no code change so connection selection, readiness, verification, and required-permissions guidance consume the shared `ProviderConnectionSurfaceSummary` contract while keeping provider-owned guidance nested under `permission_overview` instead of local identity wording.
- [x] T025 [US3] Update `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, and `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` together where needed so `ProviderConnectionResource` and onboarding converge on one summary presenter rather than parallel formatting branches.
**Checkpoint**: Provider-connections and onboarding now describe the same connection with the same summary contract and supporting detail hierarchy.
---
## Phase 6: User Story 4 - Jump from managed-environment detail into provider connections without duplicate truth (Priority: P3)
**Goal**: The managed-environment detail page advertises provider-connection state and takes operators into the provider-connections resource without duplicating the full provider profile summary on the overview page.
**Independent Test**: Open one managed-environment detail page, use its provider-connections related-context entry, and verify that the overview stays summary-first while the provider-connections resource becomes the primary decision surface.
### Tests for User Story 4
- [x] T026 [P] [US4] Extend `apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php` after T012 to prove the managed-environment detail entry opens provider connections scoped to the current environment and the live shell still shows the same shared target-scope summary without duplicating full provider profile detail on the overview page.
### Implementation for User Story 4
- [x] T027 [US4] Update `apps/platform/app/Filament/Resources/TenantResource.php` so managed-environment related-context provider summaries stay minimal, reuse the shared target-scope summary contract, and deep-link into `ProviderConnectionResource` with the current `managed_environment_id` context.
- [x] T028 [US4] Update `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` and `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php` only as needed so environment-scoped deep links preserve the same shared target-scope summary and keep provider-profile disclosure on the primary decision surface instead of the overview page.
**Checkpoint**: Managed-environment detail stays calm and summary-first, while provider-connections remains the primary decision surface for connection identity and troubleshooting.
---
## Phase 7: Polish & Cross-Cutting Validation
**Purpose**: Run the exact bounded proof set, perform the final Filament and provider-boundary review, and confirm the package stayed inside Spec `281`.
- [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/Feature/Providers/ProviderConnectionTargetScopeNeutralityTest.php tests/Feature/Providers/ProviderIdentityResolutionNeutralityTest.php tests/Feature/Providers/ProviderOperationStartGateTargetScopeContextTest.php tests/Feature/Filament/ProviderConnectionResourceScopeSummaryTest.php tests/Feature/Onboarding/ManagedTenantOnboardingProviderConnectionScopeTest.php tests/Feature/Guards/ProviderConnectionMicrosoftScopeLeakGuardTest.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/Browser/Spec281ProviderConnectionScopeSmokeTest.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 bin pint --dirty --format agent)`.
- [x] T032 [P] Review `apps/platform/app/Models/ProviderConnection.php`, `apps/platform/app/Services/Providers/ProviderConnectionResolver.php`, `apps/platform/app/Services/Providers/ProviderIdentityResolution.php`, `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`, `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php`, `apps/platform/app/Support/Links/RequiredPermissionsLinks.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, `apps/platform/app/Filament/Resources/TenantResource.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, `ProviderConnectionResource` non-global-search posture, preserved destructive-action confirmation plus authorization, provider-owned required-permissions guidance staying nested under `permission_overview`, and that Specs `282` through `287` remained deferred without new provider-profile tables, registries, taxonomy work, RBAC redesign, routing cutover, or copy-neutralization work.
---
## Dependencies & Execution Order
### Phase Dependencies
- **Phase 1 (Setup)**: no dependencies; start immediately.
- **Phase 2 (Foundational)**: depends on Phase 1 and blocks all user-story work.
- **Phase 3 (US1)**: depends on Phase 2 and establishes the canonical neutral provider-connection summary contract.
- **Phase 4 (US2)**: depends on Phase 2 and should land after or with US1 so provider-operation context carries the same canonical target-scope contract shown on provider-connections surfaces.
- **Phase 5 (US3)**: depends on US1 and should land after or with US2 when onboarding readiness also consumes the shifted identity contract.
- **Phase 6 (US4)**: depends on US1 and US3 so managed-environment related context advertises the final shared summary instead of an intermediate 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 implementation increment.
- **US2 (P1)**: independently testable after Phase 2, but should ship after or with US1 because shared run context should match the final provider-connection summary contract.
- **US3 (P2)**: independently testable after US1 and should follow once the shared summary presenter is stable.
- **US4 (P3)**: independently testable after US1 and US3 and closes the summary-first versus drill-in boundary on managed-environment detail.
### 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 `282` 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 T001 sets the bounded scope.
- **Foundational**: T007 through T011 can run in parallel before T012 converges the canonical boundary and target-scope ownership.
- **US1**: T013 and T014 can run in parallel; T015 through T017 should merge serially around resolver, summary, and Filament resource files.
- **US2**: T018 and T019 can run in parallel; T020 through T022 should follow serially around the shared identity and start-gate seams.
- **US3**: T023 can run alongside T024, then T025 should converge the shared presenter.
- **US4**: T026 can run alongside T027, then T028 should finalize the deep-link and summary-first resource behavior.
- **Polish**: T029 through T031 can run in parallel after implementation is complete; T032 should close the bounded-scope review last.
## Implementation Strategy
### Suggested MVP Scope
- MVP = **US1**. Land the neutral provider-connection summary contract first so every later consumer reads one canonical target-scope story.
### Incremental Delivery
1. Complete Phase 1 and Phase 2.
2. Deliver US1 so provider-connections stops depending on Microsoft-shaped shared summary truth.
3. Deliver US2 so provider-operation start and blocked flows record the same neutral shared target-scope contract.
4. Deliver US3 so onboarding reuses the same summary presenter and identity language.
5. Deliver US4 so managed-environment detail stays summary-first and drills into the provider-connections decision surface cleanly.
6. Finish with the exact validation commands and the 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/TargetScope/`, `apps/platform/app/Services/Providers/`, and `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` to avoid conflicting contract-shape edits.
3. Reject any implementation branch that introduces provider-profile persistence, shared compatibility aliases, registry or taxonomy work, routing cutover work, RBAC redesign, or copy-neutralization tasks reserved for Specs `282` through `287`.
## Deferred Follow-Ups / Non-Goals
- Spec `282` governance-artifact retargeting to `ManagedEnvironment`
- Spec `283` provider capability registry work
- 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 feature-local proof