TenantAtlas/specs/287-cutover-prerequisite-completion/plan.md
ahmido eceeee9c5c Complete Spec 287 prerequisite cutover (#346)
## Summary
- retire the remaining tenant-scoped provider-connection legacy routes and update canonical verification and link behavior
- complete the provider target-scope fallback cleanup so neutral shared scope data falls back to the managed environment when the raw connection tenant identifier is blank
- stop mirroring workspace roles into managed-environment scope persistence and cut the targeted admin-panel test helpers over to the post-cutover context path
- add and update the Spec 287 artifact package and targeted regression coverage for route retirement, provider-core neutralization, workspace-first RBAC, and helper cutover

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/ProviderConnections/TenantlessListRouteTest.php tests/Feature/ProviderConnections/TenantlessListScopingTest.php tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

## Notes
- Filament remains on Livewire v4 and provider registration stays unchanged in `apps/platform/bootstrap/providers.php`.
- No new asset registration or deployment-step changes are included in this slice.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #346
2026-05-10 18:22:34 +00:00

18 KiB

Implementation Plan: Cutover Prerequisite Completion

Branch: 287-cutover-prerequisite-completion | Date: 2026-05-10 | Spec: spec.md Input: Feature specification from specs/287-cutover-prerequisite-completion/spec.md

Summary

Complete the remaining runtime and test-harness seams that still block the later quality-gates / no-legacy package. The narrow implementation path retires the legacy provider-connection route family, finishes provider target-scope core neutralization on the shared provider seams, cleans environment-scope role persistence so workspace membership remains the only role-bearing truth, replaces tenant-panel-era test helpers with post-cutover admin or workspace helpers, and validates only those seams with targeted feature and browser coverage.

This plan is intentionally not a no-legacy guard package. Filament remains v5 on Livewire v4, provider registration remains in apps/platform/bootstrap/providers.php, no new asset or deployment step is introduced, no full-suite baseline is required, and Spec 288 remains the explicit follow-up for quality gates and no-legacy enforcement.

Inherited Baseline / Explicit Delta

Inherited baseline

  • Spec 279 already owns the managed-environment core cutover and remains historical baseline context only.
  • Spec 280 already owns the workspace-first route and panel-shell convergence, but repo truth still shows a surviving legacy provider-connection route family in apps/platform/routes/web.php.
  • Spec 281 already owns provider boundary groundwork, but repo truth still shows Microsoft-shaped shared target-scope and identity fields on platform-core provider seams.
  • Spec 282 already owns governance-artifact retargeting and remains adjacent historical context only.
  • Spec 285 already owns the workspace-first RBAC direction, but repo truth still shows incomplete environment-scope persistence cleanup where managed-environment membership records mirror workspace role values.
  • Spec 286 already owns UI copy cleanup and remains explicitly out of scope for this package.

Explicit delta in this plan

  • Retire the remaining legacy provider-connection route family instead of guarding it.
  • Finish provider target-scope and identity neutralization on shared provider-core seams instead of leaving that work to a later enforcement slice.
  • Complete the runtime cleanup that keeps workspace membership role-bearing and environment scope narrowing-only.
  • Replace tenant-panel-era shared test helpers and the proof-command consumer tests apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php and apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php with post-cutover admin or workspace context helpers.
  • Keep proof targeted to changed seams only and hand global enforcement to Spec 288.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12.52
Primary Dependencies: Pest 4, Filament 5.2.1, Livewire 4.1.4, existing provider target-scope and access-scope services, shared Pest test helpers
Storage: no new persistence; the package completes behavior on existing route, provider-core, access-scope, and test-support seams
Testing: targeted Pest feature tests plus targeted browser validation
Validation Lanes: fast-feedback, confidence, browser
Target Platform: Laravel monolith in apps/platform
Project Type: web application
Performance Goals: keep validation limited to the changed seams; no full-suite or broad guard lane work
Constraints: no global guard suite, no full-suite baseline, no package execution, no guided operations, no UI copy cleanup, no provider capability expansion
Scale/Scope: one bounded prerequisite-completion slice immediately preceding Spec 288

Likely Affected Repo Surfaces

  • apps/platform/routes/web.php
  • apps/platform/app/Services/Providers/ProviderConnectionResolver.php
  • apps/platform/app/Services/Providers/ProviderIdentityResolver.php
  • apps/platform/app/Services/Providers/ProviderIdentityResolution.php
  • apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php
  • apps/platform/app/Services/Providers/ProviderOperationStartGate.php
  • apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeNormalizer.php
  • apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php
  • apps/platform/app/Services/Auth/TenantMembershipManager.php
  • apps/platform/app/Services/Auth/ManagedEnvironmentAccessScopeResolver.php
  • apps/platform/app/Providers/Filament/AdminPanelProvider.php
  • apps/platform/app/Filament/Resources/TenantResource.php
  • apps/platform/app/Filament/Pages/TenantRequiredPermissions.php
  • apps/platform/app/Support/OperationRunLinks.php
  • apps/platform/app/Support/Providers/ProviderReasonTranslator.php
  • apps/platform/app/Support/Verification/VerificationLinkBehavior.php
  • apps/platform/tests/Pest.php
  • targeted feature tests in apps/platform/tests/Feature/ProviderConnections/, apps/platform/tests/Feature/Auth/, apps/platform/tests/Feature/Rbac/, apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php, and apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php
  • targeted browser tests in apps/platform/tests/Browser/

Filament v5 / Surface Notes

  • Livewire v4.0+ compliance: all touched surfaces remain on Filament v5 with Livewire v4.
  • Provider registration location: provider registration remains in apps/platform/bootstrap/providers.php; this package does not add a new panel or change provider registration location.
  • Global search rule: this slice introduces no new globally-searchable resource. Existing provider-connection resource behavior remains unchanged from a global-search standpoint.
  • Destructive actions: no new destructive action is introduced. Any touched existing destructive actions must keep ->action(...), ->requiresConfirmation(), and server authorization.
  • Asset strategy: no new asset registration or deployment step is planned.

Prerequisite Completion Fit

  • Complete runtime truth first, then let Spec 288 enforce that truth.
  • Prefer canonical replacement over compatibility routes, copied role persistence, or tenant-panel test-only fallbacks.
  • Keep Microsoft-specific detail nested under provider-owned seams instead of the shared provider-core contract.
  • Keep the package bounded to five named prerequisite areas and reject adjacent feature work.
  • Use exact targeted validation commands across spec.md, plan.md, tasks.md, and quickstart.md.

UI / Surface Guardrail Plan

  • Guardrail scope: bounded runtime completion over existing provider-connection and provider-backed operator surfaces
  • Native vs custom classification summary: existing native Filament provider-connection surfaces and shared provider summaries only; no new operator-facing page family
  • Shared-family relevance: navigation, provider target-scope summaries, run-launch context, and test harness setup
  • State layers in scope: route, page, detail, shared provider-core payloads, access-scope persistence, and test-support context helpers
  • Audience modes in scope: operator-MSP, support-platform on existing provider surfaces only
  • Decision/diagnostic/raw hierarchy plan: keep current provider-owned diagnostics nested; change only the shared contract and canonical route truth
  • Raw/support gating plan: preserve existing provider-owned raw detail where current support or consent workflows genuinely need it
  • One-primary-action / duplicate-truth control: no new action family is introduced; existing launch and open actions continue to own the workflow
  • Handling modes by drift class or surface: implementation-required for the named seams; out of scope for global enforcement and copy cleanup
  • Repository-signal treatment: direct runtime completion only; no broad source-scan or lint layer
  • Special surface test profiles: standard-native-filament, global-context-shell
  • Required tests or manual smoke: functional-core, targeted browser-smoke
  • Exception path and spread control: provider-owned Microsoft detail only; no other exception expansion
  • Active feature PR close-out entry: RuntimePrerequisite

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes
  • Systems touched: provider route ownership, shared provider target-scope and identity resolution, workspace-first access persistence cleanup, and shared test helpers
  • Shared abstractions reused: existing provider target-scope and identity helpers, existing workspace access resolver seams, and existing tests/Pest.php helper style
  • New abstraction introduced? why?: none
  • Why the existing abstraction was sufficient or insufficient: the abstractions already exist; the incomplete cutover behavior inside them is the real remaining work
  • Bounded deviation / spread control: Microsoft-specific profile detail remains nested only where provider-owned workflows still need it

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes, as shared provider-backed run context and canonical link truth only
  • Central contract reused: ProviderOperationStartGate, existing OperationRun context, and canonical operation links
  • Delegated UX behaviors: existing queued, blocked, and run-link semantics remain delegated; this slice changes only the prerequisite data and route truth they rely on
  • Surface-owned behavior kept local: existing provider launch or open actions only
  • Queued DB-notification policy: N/A
  • Terminal notification path: existing central lifecycle mechanism
  • Exception path: none

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes
  • Provider-owned seams: consent/profile detail, Microsoft-specific identifiers, Graph-specific diagnostics, and provider-owned support metadata
  • Platform-core seams: provider-connection route ownership, shared target-scope and identity outputs, provider-backed run context, and workspace-scoped launch truth
  • Neutral platform terms / contracts preserved: provider connection, target scope, scope kind, scope identifier, scope display name, workspace, managed environment
  • Retained provider-specific semantics and why: existing consent and support flows still need Microsoft tenant/profile data, but only as provider-owned nested detail
  • Bounded extraction or follow-up path: Spec 288 for no-legacy enforcement after this slice lands

Constitution Check

GATE: Must pass before implementation begins and again after design artifacts are complete.

  • Inventory-first: PASS. No new inventory or snapshot truth is introduced.
  • Read/write separation: PASS. The slice completes existing runtime seams without adding a new workflow surface.
  • Graph contract path: PASS by preservation. No new Graph integration family or registry is introduced.
  • Deterministic capabilities: PASS by preservation. Capability families do not expand.
  • RBAC-UX: PASS. Workspace membership remains role-bearing and environment scope becomes narrowing-only on the completed seams.
  • Workspace isolation: PASS. The package preserves workspace-first routing and entitlement boundaries.
  • Managed-environment isolation: PASS. The package narrows environment scope instead of broadening it.
  • Run observability: PASS. Existing OperationRun lifecycle and links remain central.
  • OperationRun start UX: PASS. No new start or completion UX family is added.
  • Data minimization: PASS. No new persistence or compatibility ledger is introduced.
  • Test governance: PASS. Validation stays targeted and explicit.
  • Proportionality / no premature abstraction: PASS. Existing seams are completed rather than wrapped in new frameworks.
  • Persisted truth / behavioral state: PASS. No new persistence or state family is introduced.
  • Provider boundary: PASS. Shared provider-core contracts become more neutral while provider-owned detail stays bounded.

Gate evaluation: PASS.

Post-design re-check: PASS while spec.md, plan.md, tasks.md, and quickstart.md keep the same literal proof commands, and research.md, data-model.md, contracts/cutover-prerequisite-completion.logical.openapi.yaml, and checklists/requirements.md keep the same seam inventory and Spec 288 follow-up boundary.

Test Governance Check

  • Test purpose / classification by changed surface: Feature, Browser
  • Affected validation lanes: fast-feedback, confidence, browser
  • Why this lane mix is the narrowest sufficient proof: the changed seams are concrete runtime and test-support paths, so focused feature tests plus a narrow browser smoke are sufficient and honest
  • Narrowest proving command(s):
    • 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/ProviderConnections/LegacyRedirectTest.php tests/Feature/ProviderConnections/TenantlessListRouteTest.php tests/Feature/ProviderConnections/TenantlessListScopingTest.php tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php)
    • 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 tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php)
    • 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)
  • Fixture / helper / factory / seed / context cost risks: moderate only because the shared tenant-panel helper is being replaced on tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php and tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php
  • Expensive defaults or shared helper growth introduced?: no; the helper cutover must reduce dependence on retired panel state rather than add new implicit defaults
  • Heavy-family additions, promotions, or visibility changes: none
  • Surface-class relief / special coverage rule: standard-native-filament and global-context-shell remain sufficient; no heavy-governance coverage is justified
  • Closing validation and reviewer handoff: rerun the exact commands above, verify Filament stays on Livewire v4, provider registration remains in apps/platform/bootstrap/providers.php, no asset registration or deployment-step drift was added, no full-suite or guard-family work was added, and confirm Spec 288 remains the explicit follow-up
  • Budget / baseline / trend follow-up: contained feature-local increase only
  • Review-stop questions: did the implementation widen into no-legacy guards, UI copy cleanup, package execution, guided operations, or provider capability expansion
  • Escalation path: document-in-feature for contained seam follow-up, reject-or-split for scope expansion
  • Active feature PR close-out entry: RuntimePrerequisite

Review Checklist Status

  • Review checklist artifact: checklists/requirements.md
  • Review outcome class: acceptable-special-case
  • Workflow outcome: keep
  • Test-governance outcome: keep
  • Resolution note: the package is implementation-ready as a bounded prerequisite-completion slice and no longer depends on a blocked-by-prerequisites posture
  • Escalation rule: if implementation starts adding guard suites, full-suite baselines, or adjacent product features, stop and split the work out of 287

Rollout Considerations

  • Retire the legacy provider-connection route family before widening targeted validation so the canonical route truth settles first.
  • Complete provider target-scope neutralization before touching the browser proof so the live provider surfaces already speak the intended shared contract.
  • Cut over the shared test helper before updating apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php and apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php so targeted tests do not drift through two helper systems.
  • Keep Spec 288 untouched during runtime completion; it should start from the completed baseline produced by this slice.

Risk Controls

  • Reject any implementation that keeps legacy provider-connection aliases as compatibility routes for convenience.
  • Reject any implementation that solves provider target-scope cleanup by hiding Microsoft-only fields in new platform-core wrappers instead of neutralizing the shared contract.
  • Reject any implementation that preserves copied role-bearing state on environment-scope persistence after the cleanup.
  • Reject any implementation that adds a global guard family, broad source-scan package, or full-suite baseline under this spec.

Research & Design Outputs

  • research.md records the completion-first decisions, bounded runtime scope, rejected guard-suite alternative, and evidence anchors.
  • data-model.md captures the derived seam inventory, canonical replacements, and invariants.
  • quickstart.md gives reviewers the scope boundary, review scenarios, and exact targeted proof commands.
  • contracts/cutover-prerequisite-completion.logical.openapi.yaml models the logical completion seams and the targeted validation contract.
  • checklists/requirements.md records the review outcome and bounded scope rules.

Project Structure

Documentation (this feature)

specs/287-cutover-prerequisite-completion/
├── checklists/
│   └── requirements.md
├── contracts/
│   └── cutover-prerequisite-completion.logical.openapi.yaml
├── data-model.md
├── plan.md
├── quickstart.md
├── research.md
├── spec.md
└── tasks.md

Source Code (repository root)

apps/platform/
├── app/
├── routes/
└── tests/
    ├── Browser/
    ├── Feature/
    └── Pest.php

Structure Decision: keep the package inside the existing Laravel app, route, provider, access-service, and Pest test-support structure. No new base directory is needed.