# Legacy Surface Audit: Spec 297 **Prepared**: 2026-05-12 **Status**: Implementation and verification complete on branch `297-managed-environment-canonical-route-cutover`. ## Commands Run During Prep | Command | Result | |---|---| | `git status --short --branch` | Clean on `platform-dev` before Spec Kit branch creation | | `.specify/scripts/bash/create-new-feature.sh --json --number 297 --short-name managed-environment-canonical-route-cutover ...` | Created branch and spec directory `297-managed-environment-canonical-route-cutover` | | `.specify/scripts/bash/setup-plan.sh --json` | Created `plan.md` from template | | `cd apps/platform && ./vendor/bin/sail artisan route:list \| rg "admin/t\|admin/tenants\|provider-connections\|required-permissions\|workspaces/.*/environments\|operations"` | Found active `/admin/tenants` routes plus canonical workspace/environment and workspace operations routes | | `cd apps/platform && ./vendor/bin/sail artisan route:list --path=admin/tenants` | Shows 4 TenantResource routes | | `cd apps/platform && ./vendor/bin/sail artisan route:list --path=admin/workspaces` | Shows canonical `/admin/workspaces/{workspace}/environments...` and `/admin/workspaces/{workspace}/operations...` route families | | `cd apps/platform && ./vendor/bin/sail artisan route:list --path=admin/provider-connections` | Shows tenantless provider-connection resource routes | | `cd apps/platform && ./vendor/bin/sail artisan route:list --columns=...` | Unsupported option in current Artisan route:list; retried without `--columns` | | `cd apps/platform && rg "TenantPanelProvider|panel:\\s*'tenant'|panel:\\s*\\\"tenant\\\"|/admin/t/|/admin/tenants|TenantResource::getUrl|TenantDashboard::getUrl|TenantRequiredPermissions::getUrl|setTenantPanelContext|admin\\.operations" . --glob '!vendor' --glob '!node_modules'` | Found active runtime and test references requiring implementation classification | | `git status --short --branch` | `## 297-managed-environment-canonical-route-cutover`; only untracked spec package present before runtime edits | | `git diff --stat` | Empty before runtime edits | | `git log -1 --oneline` | `928d49b5 Merge remote-tracking branch 'origin/platform-dev' into platform-dev` | | `cd apps/platform && ./vendor/bin/sail artisan route:list \| rg "admin/t\|admin/tenants\|provider-connections\|required-permissions\|workspaces/.*/environments\|operations"` | Confirmed active `/admin/tenants` TenantResource routes, canonical workspace/environment routes, canonical workspace operations routes, tenantless provider-connection routes, and canonical required-permissions route | | `cd apps/platform && rg "TenantPanelProvider|panel:\\s*'tenant'|panel:\\s*\\\"tenant\\\"|/admin/t/|/admin/tenants|TenantResource::getUrl|TenantDashboard::getUrl|TenantRequiredPermissions::getUrl|setTenantPanelContext|admin\\.operations" . --glob '!vendor' --glob '!node_modules'` | Confirmed retired panel provider file, `TenantResource::getUrl(...)` runtime links, canonical `TenantDashboard::getUrl(...)` references, provider-connection legacy URL parser compatibility, legacy intended-URL acceptance, old Pest helper name, and historical/guard references | ## Findings | Finding | Runtime/Test/Copy | Active? | Decision | Fixed? | |---|---|---:|---|---:| | `apps/platform/app/Providers/Filament/TenantPanelProvider.php` exists | Runtime | No | Deleted; `bootstrap/providers.php` remains Admin/System only | Yes | | `/admin/tenants` route family exists via TenantResource | Runtime | No | Retired as active product surface; route scan now returns no matches | Yes | | `/admin/workspaces/{workspace}/environments...` route family exists | Runtime | Yes | Reuse as canonical managed-environment route family | N/A | | `/admin/workspaces/{workspace}/operations...` route family exists | Runtime | Yes | Reuse as canonical operations route family | N/A | | `/admin/provider-connections...` tenantless route family exists | Runtime | Yes | Keep as canonical provider-connection route family | N/A | | `setTenantPanelContext()` exists in `tests/Pest.php` | Test | No | Renamed to `setAdminEnvironmentContext()` with no alias; remaining hits are guard regex literals only | Yes | | Runtime `TenantResource::getUrl(...)` references remain | Runtime | No | Replaced with `ManagedEnvironmentLinks` or canonical resource query URLs; app/resource scan is clean | Yes | | Runtime `TenantDashboard::getUrl(...)` references remain | Runtime | No | Replaced in app/runtime surfaces; dashboard page `getUrl()` itself delegates to canonical helper | Yes | | Runtime `TenantRequiredPermissions::getUrl(...)` references remain | Runtime/Test | No | Replaced with canonical required-permissions route/helper | Yes | | Tests still assert `/admin/t...` or `/admin/tenants...` in multiple historical and current files | Test | Yes | Rebaselined to retired-route assertions, canonical routes, or historical-only allowed references | Yes | | Old product copy may remain in touched active surfaces | Copy | Bounded | Touched active surfaces neutralized; remaining hits are outside touched files, guard fixtures, provider/technical names, or follow-up copy scope | Yes | | `AdminPanelProvider` explicitly registers `TenantResource::class` | Runtime | No | Removed explicit registration; `TenantResource` stays technical/dormant with canonical URL override and global search disabled | Yes | | `TenantResource` is still used as a table/form/action owner by canonical workspace pages | Runtime | Yes | Kept as technical owner only; URL generation is canonical and resource routes are inactive | Yes | | `ProviderConnectionResource::extractTenantExternalIdFromUrl()` accepts old `/admin/tenants` and `/admin/t` referers | Runtime compatibility | No | Removed legacy referer parsing; canonical `managed_environment_id` query/context remains | Yes | | `WorkspaceIntendedUrl` accepts `/admin/t...` and `/admin/tenants...` as safe admin intended URLs | Runtime | No | Rejects retired tenant routes at store/consume time | Yes | | `WorkspaceRedirectResolver` preserves matching `/admin/t...` and `/admin/tenants...` intended URLs | Runtime | No | Rejects retired tenant routes and normalizes exact legacy `/admin/operations` to workspace-scoped operations | Yes | | `TenantRequiredPermissions::reRunVerificationUrl()` uses `TenantResource::getUrl('view')` | Runtime | No | Uses canonical managed-environment detail helper | Yes | | `ManageTenantMemberships` back action uses `TenantResource::getUrl('view')` | Runtime | No | Uses canonical managed-environment detail helper | Yes | | `ProviderConnectionResource` environment backlink uses `TenantResource::getUrl('view')` | Runtime | No | Uses canonical managed-environment detail helper | Yes | ## Allowed Reference Classes | Reference | Why allowed | Follow-up | |---|---|---| | Historical specs and audit docs | Repository history, not active runtime truth | None | | Internal model/table/class names such as `Tenant` | DB/model rename is out of scope | Separate DB/model rename spec only if product requires it | | Microsoft Entra tenant ID / provider-specific tenant copy | External provider terminology | None | | Guard tests that assert old paths are 404 | Regression protection | Keep focused and explicit | | `TenantResource` class name and internal helper references | Technical resource/model naming remains out of scope | Keep only if URL output is canonical and resource is not active as `/admin/tenants` | | Copy scan hits in `lang/en/localization.php`, `FindingExceptionsQueue`, baseline compare, governance-action internals, and assignment relation internals | Outside touched active cutover surfaces, guard fixtures, or technical/historical tenant-domain wording | Future localization/spec only if product asks for broad copy neutralization | ## Implementation Verification Commands | Command | Result | |---|---| | `cd apps/platform && ./vendor/bin/sail artisan route:list \| rg "admin/tenants\|admin/t/"` | No matches; retired routes are inactive | | `cd apps/platform && ./vendor/bin/sail artisan route:list \| rg "workspaces/.*/environments\|provider-connections\|required-permissions\|operations"` | Shows canonical workspace/environment, provider-connection, required-permissions, and workspace operations route families | | `cd apps/platform && rg "filament\\.admin\\.resources\\.tenants\|/admin/tenants\|/admin/t/\|TenantResource::getUrl\|TenantDashboard::getUrl\|TenantRequiredPermissions::getUrl\|setTenantPanelContext\|panel:\\s*'tenant'\|panel:\\s*\\\"tenant\\\"" app resources routes --glob '!vendor' --glob '!node_modules'` | No matches | | `cd apps/platform && rg "setTenantPanelContext\|panel:\\s*'tenant'\|panel:\\s*\\\"tenant\\\"" tests --glob '!vendor' --glob '!node_modules'` | Only `Spec288NoLegacyRouteAndHelperGuardTest` regex guard literals remain | | `cd apps/platform && rg "Tenant dashboard\|Tenant detail\|Open tenant\|Select tenant\|Tenant scope\|Remove tenant\|Restore tenant\|Tenant memberships" app resources lang tests --glob '!vendor' --glob '!node_modules'` | Remaining hits classified as allowed/out-of-scope above | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php tests/Feature/Guards/ManagedEnvironmentCanonicalRouteContractTest.php tests/Feature/Workspaces/WorkspaceIntendedUrlLegacyRejectionTest.php tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php` | 51 passed, 173 assertions | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards` | 265 passed, 4653 assertions | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces` | 96 passed, 276 assertions | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections` | 78 passed, 588 assertions | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions` | 21 passed, 82 assertions | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament` | 765 passed, 5 skipped, 4975 assertions | | `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php` | 2 passed, 29 assertions | | `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` | Pass | | `git diff --check` | Pass | ## Implementation Refresh Requirements Before runtime edits, refresh this audit with: ```bash git status --short --branch git diff --stat cd apps/platform ./vendor/bin/sail artisan route:list | rg "admin/t|admin/tenants|provider-connections|required-permissions|workspaces/.*/environments|operations" rg "TenantPanelProvider|panel:\s*'tenant'|panel:\s*\"tenant\"|/admin/t/|/admin/tenants|TenantResource::getUrl|TenantDashboard::getUrl|TenantRequiredPermissions::getUrl|setTenantPanelContext|admin\.operations" . --glob '!vendor' --glob '!node_modules' ``` Update the `Fixed?` column as implementation progresses.