TenantAtlas/specs/288-quality-gates-no-legacy-enforcement/research.md
ahmido 0a1377c5f5 feat(spec-288): add no-legacy quality gates (#347)
## Summary
- add Spec 288 no-legacy route/helper and provider-core/role-authority guard coverage
- extend the pinned Spec 281 and Spec 285 browser smokes plus lane/report classification wording for classification-only fallout handling
- add the Spec 288 artifact package and contributor-facing quality-gate guidance while keeping Package Execution deferred to Spec 289

## Validation
- `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/Guards/Spec288NoLegacyRouteAndHelperGuardTest.php tests/Feature/Guards/Spec288ProviderCoreAndRoleAuthorityGuardTest.php tests/Feature/Guards/AdminWorkspaceRoutesGuardTest.php tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php tests/Feature/Guards/BrowserLaneIsolationTest.php tests/Feature/Guards/CiLaneFailureClassificationContractTest.php tests/Feature/Guards/CiHeavyBrowserWorkflowContractTest.php tests/Unit/Auth/NoRoleStringChecksTest.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)`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #347
2026-05-10 21:24:14 +00:00

76 lines
6.3 KiB
Markdown

# 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.