# Research: Quality Gates / No-Legacy Enforcement ## Decision 1: Spec `288` owns enforcement only, not runtime completion - Use this package to enforce the post-`287` cutover truth through bounded guard tests, targeted browser smoke, and contributor-facing quality-gate docs. - Do not reopen route migration, provider-core runtime rewrites, RBAC redesign, or any product-surface rewrite here. - Keep Spec `289` explicitly reserved for Package Execution Contract work. ## Decision 2: Guard exact retired route/path families instead of broad `/admin/t` bans - The cutover still has valid canonical managed-environment routes, so the guard layer must forbid only the exact retired management-only families and duplicate-prefix emissions. - The enforcement inventory should pin concrete forbidden shapes such as `/admin/tenants/{tenant:slug}/provider-connections...`, `/admin/t/{tenant}/provider-connections`, `/admin/t/{tenant}/required-permissions`, `/admin/t/{tenant}/memberships`, and duplicate `/admin/t/t/{tenant}/...` emissions. - Do not turn this package into a blanket ban on every surviving `/admin/t/...` route without repo proof that the whole family is retired. ## Decision 3: Helper enforcement targets retired panel bootstrapping, not generic tenant vocabulary - The risk to guard is the return of retired tenant-panel bootstrapping semantics, not the presence of every `tenant`-named helper or variable. - Guard scans should target direct `tenant` panel selection, retired bootstrapping helpers such as `setTenantPanelContext()`, and any similar owned-seam helper that would recreate panel-era assumptions. - Any exception beyond pinned historical directories must be file-scoped and justified. ## Decision 4: Provider-core enforcement should reuse existing boundary seams - Reuse `ProviderBoundaryCatalog`, `ProviderOperationRegistry`, and the current provider-boundary tests instead of inventing a new provider-core validator. - The enforcement targets are shared identity resolution and shared operation-definition seams where provider-specific request shaping or provider binding truth would be a regression. - Provider-owned nested detail remains allowed only where the provider itself is the subject. ## Decision 5: Role-authority enforcement should prove current semantics, not redesign them - Reuse the existing workspace-first policy and managed-environment scope tests to prove the current contract remains true. - The core invariants are: workspace membership is the only role-bearing authority, wrong-scope denials stay `404`, in-scope capability denials stay `403`, and direct role edits on managed-environment scope rows remain rejected. - Do not let this package become an RBAC rewrite. ## Decision 6: Targeted browser proof should stay anchored to the current Spec `281` and Spec `285` smoke tests - The two highest-signal user-visible anchors already exist in `apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php` and `apps/platform/tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php`. - Extend those tests to keep canonical route continuity honest after the new guard pack lands. - Do not widen the browser lane beyond those named surfaces under this spec. ## Decision 7: Broader baseline fallout is classified only through the current lane/report seams - Use `apps/platform/tests/Support/TestLaneManifest.php`, `apps/platform/tests/Support/TestLaneReport.php`, and the existing classification-contract tests to describe how cutover guard or browser failures should be reported. - Do not run or own a full-suite repair program here. - README guidance should point contributors to the targeted proof commands and the classification-only boundary. ## Rejected Alternatives ### Rejected: absorb runtime cutover repair into `288` That would collapse the intentional `287` / `288` split and make it impossible to tell whether the package is guardrail work or unfinished runtime work. ### Rejected: ban every `tenant`-named helper or route token globally That would create false positives and force ad hoc exceptions because some canonical managed-environment flows still use bounded tenant-language or route segments legitimately. ### Rejected: introduce a new linting or baseline-report framework The repo already has working guard, browser, manifest, and report seams. A second framework would increase ownership cost without improving the cutover signal. ### Rejected: take ownership of full-suite repair under the label of “baseline classification” The user explicitly excluded full-suite repair work. Classification is in scope; broad stabilization is not. ## Evidence Anchors - `apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php` already proves one retired provider-management path family must stay `404` without redirects. - `apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php` already proves the legacy `tenant` panel is gone at runtime, but it does not yet own the full helper and route inventory. - `apps/platform/tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php` already guards one provider-boundary seam and current provider operation definitions. - `apps/platform/tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php` and `apps/platform/tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php` already prove the intended role-authority semantics. - `apps/platform/tests/Feature/Guards/BrowserLaneIsolationTest.php`, `apps/platform/tests/Feature/Guards/CiLaneFailureClassificationContractTest.php`, `apps/platform/tests/Feature/Guards/CiHeavyBrowserWorkflowContractTest.php`, `apps/platform/tests/Support/TestLaneManifest.php`, and `apps/platform/tests/Support/TestLaneReport.php` already define the current classification/report seams. - `README.md` already documents lane ownership and budgets, making it the right place for the contributor-facing quality-gate rule. ## Implementation Boundary Summary - The package is implementation-ready only when the enforcement layer stays inside the named guard, browser, and documentation seams. - If implementation starts changing live provider-core behavior, RBAC behavior, or unrelated product flows to make the guards pass, stop and split that work out of `288`. - The canonical executable command set lives only in `spec.md`, `plan.md`, `tasks.md`, and `quickstart.md`; this note references that authority without restating a second variant.