TenantAtlas/specs/288-quality-gates-no-legacy-enforcement/data-model.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

68 lines
5.7 KiB
Markdown

# Data Model: Quality Gates / No-Legacy Enforcement
## Overview
`288` introduces no new persisted entity, table, lifecycle state, or runtime DTO. The "data model" for this package is a bounded enforcement inventory that defines which route/path families, helper patterns, provider-core seams, role-authority invariants, browser gates, and baseline-classification rules must remain true after Spec `287`.
## Canonical Enforcement Categories
| Enforcement Key | Meaning | Primary Targets | Canonical Enforcement |
|---|---|---|---|
| `legacy_route_path_contract` | exact retired management route/path families must stay forbidden | guard scans, legacy redirect tests, route emission assertions | targeted no-legacy route/path guard plus supporting runtime regression tests |
| `route_emission_contract` | cutover-owned builders and launch points emit canonical admin/workspace routes only | runtime launch-point tests and emitted URL assertions | emitted URLs use canonical admin/workspace managed-environment shapes |
| `tenant_panel_helper_contract` | retired tenant-panel bootstrapping must not re-enter shared test support or other owned seams | `tests/Pest.php` and owned test/support seams | explicit helper/panel-bootstrapping guard inventory |
| `provider_core_boundary_contract` | platform-core provider seams stay provider-neutral | provider-boundary guards and shared provider catalogs | shared identity/operation seams reject provider-specific request shaping or binding truth |
| `environment_scope_role_authority_contract` | workspace membership stays role-bearing and environment scope stays narrowing-only | policy tests, managed-environment scope tests, role-string guard | current wrong-scope `404`, in-scope `403`, and direct role-edit rejection semantics remain true |
| `browser_smoke_gate_contract` | the visible canonical provider and RBAC environment flows stay honest | Spec `281` and Spec `285` browser smokes | targeted browser proof only |
| `baseline_classification_contract` | broader baseline fallout is classified without becoming repair scope | lane manifest, report contract, README guidance | classification-only wording via existing report seams |
## Pinned Forbidden Families and Replacements
| Enforcement Key | Retired Pattern / Drift | Canonical Replacement |
|---|---|---|
| `legacy_route_path_contract` | `/admin/tenants/{tenant:slug}/provider-connections...` | `/admin/provider-connections...` |
| `legacy_route_path_contract` | `/admin/t/{tenant}/provider-connections`, `/admin/t/{tenant}/required-permissions`, `/admin/t/{tenant}/memberships` | canonical admin/workspace managed-environment routes and launch points |
| `legacy_route_path_contract` | duplicate `/admin/t/t/{tenant}/...` emission | one canonical managed-environment route prefix only |
| `tenant_panel_helper_contract` | `setTenantPanelContext()` or direct `tenant` panel bootstrapping on owned seams | admin/workspace context setup or an explicit file-scoped exception |
| `provider_core_boundary_contract` | `graphOptions`, `client_request_id`, or provider binding keys in platform-core seams | provider-neutral shared seams with provider-owned nested detail only |
| `environment_scope_role_authority_contract` | managed-environment scope acting like a second role-bearing matrix | workspace membership role truth plus narrowing-only scope rows |
| `baseline_classification_contract` | broader baseline fallout silently becoming repair scope | explicit classification-only documentation and report labeling |
## Pinned Historical / Immutable Exclusions
| Exclusion Class | Meaning | Representative Paths |
|---|---|---|
| `immutable_history` | files that intentionally preserve removed vocabulary or route families as historical truth | `database/migrations/**`, `references/**` |
| `spec_history` | spec and planning artifacts that must be able to mention retired patterns explicitly | `specs/**`, `spechistory/**`, `docs/**` |
| `generated_or_external` | code or artifacts outside normal enforcement ownership | `vendor/**`, `storage/**`, `public/build/**`, `bootstrap/cache/**` |
## Allowed Provider-Owned Detail
| Detail Class | Meaning | Examples |
|---|---|---|
| `provider_owned_profile_detail` | provider-specific detail is allowed where the provider itself is the subject | Microsoft tenant identifiers, authority tenant strings, consent URLs |
| `provider_owned_support_detail` | lower-level support detail remains nested provider truth | provider-specific diagnostics or raw metadata |
## Role-Authority Invariants
- `workspace_memberships` remain the only role-bearing authority source.
- `managed_environment_memberships` remain a narrowing-only scope overlay.
- Wrong-scope denials stay `404`.
- In-scope capability denials stay `403`.
- Direct role edits on managed-environment scope rows remain rejected.
## Invariants
- `288` introduces no new persistence and no new product-facing workflow surface.
- The same enforcement categories and the same Spec `289` follow-up boundary must appear across `spec.md`, `plan.md`, `tasks.md`, `quickstart.md`, `data-model.md`, the logical contract, and `checklists/requirements.md`.
- The literal proof commands live only in `spec.md`, `plan.md`, `tasks.md`, and `quickstart.md`; the remaining artifacts reference that canonical command set rather than restating another variant.
- Browser proof remains limited to the two named browser smoke files.
- Baseline fallout remains classification-only and must not silently become repair scope.
## Out of Scope Data Changes
- no database migrations
- no new provider registry or provider-core abstraction layer
- no new role family or persisted access overlay
- no full-suite baseline artifact or new baseline ledger
- no package execution state or workflow contract