TenantAtlas/specs/322-browser-no-drift-regression-guard/plan.md
ahmido ec4ff1074c Spec 322: add browser no-drift regression guards (#379)
## Summary
- add the Spec 322 artifact set for the browser no-drift regression guard
- add Feature navigation guards for admin surface scope, environment CTA URLs, and legacy alias rejection
- add Browser smoke coverage for workspace hubs, environment-owned surfaces, workspace-owned analysis surfaces, and alerts/audit flows
- add the Spec 322 browser support harness used by the new smoke coverage

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Navigation/Spec322AdminSurfaceScopeContractTest.php tests/Feature/Navigation/Spec322LegacyQueryAliasGuardTest.php tests/Feature/Navigation/Spec322EnvironmentCtaUrlContractTest.php --compact`
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Browser/Spec322WorkspaceHubNoDriftSmokeTest.php tests/Browser/Spec322EnvironmentOwnedSurfaceSmokeTest.php tests/Browser/Spec322WorkspaceOwnedAnalysisSmokeTest.php tests/Browser/Spec322AlertsAuditNoDriftSmokeTest.php --compact`
- `cd apps/platform && ./vendor/bin/sail pint --dirty`
- `git diff --check`

## Notes
- a broader filtered regression run still reports existing Baseline Compare feature-test failures outside this diff

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #379
2026-05-17 11:34:31 +00:00

19 KiB

Implementation Plan: Browser No-Drift Regression Guard

Branch: 322-browser-no-drift-regression-guard Date: 2026-05-17 Spec: specs/322-browser-no-drift-regression-guard/spec.md Status: Draft

Summary

Create durable no-drift regression coverage for the Workspace / Environment contracts stabilized by Specs 314 through 321. The implementation is test/guard-first and must not add product behavior except narrow fixes required to make existing contracts deterministic.

The plan adds:

  • Feature/static guards for surface classification, URL generation, canonical environment_id, clear-state contracts, cross-workspace rejection, legacy aliases, /admin/t, Tenant panel provider absence, and provider-boundary Tenant allowlist.
  • Pest Browser smoke tests grouped by surface model for shell, chip, clear, reload, and back/forward alignment.
  • A coverage manifest and test plan so future admin surfaces can update coverage deliberately.

Technical Context

Language / Version: PHP 8.4.15 Primary Framework: Laravel 12.52.0 Admin UI: Filament 5.2.1 Reactive Layer: Livewire 4.1.4 Database: PostgreSQL via Sail Testing: Pest 4.3.1, PHPUnit 12.5 Validation Lanes: Feature/static guards, Browser lane, possible heavy-governance classification if discovery-style guards are broadened Target Platform: Laravel monolith in apps/platform Project Type: Web application Performance Goals: Keep Browser tests focused and grouped so the lane remains stable and reviewable. Constraints: No migrations, no seeders unless fixture determinism is impossible, no package changes, no env/queue/scheduler/storage changes, no Playwright MCP dependency, no backwards compatibility aliases. Scale / Scope: Core admin surface contracts only; optional surfaces are documented rather than silently included.

Package posture:

  • Filament v5 requires Livewire v4.0+; this repo uses Livewire 4.1.4.
  • Laravel 12 panel providers are registered in apps/platform/bootstrap/providers.php; this spec does not add a panel provider.
  • No frontend assets are added. No filament:assets deployment change is expected.

Current Repo Truth

Relevant existing seams:

apps/platform/app/Support/Navigation/WorkspaceHubRegistry.php
apps/platform/app/Support/Navigation/AdminSurfaceScope.php
apps/platform/app/Support/Navigation/WorkspaceHubEnvironmentFilter.php
apps/platform/app/Support/Navigation/WorkspaceHubFilterStateResetter.php
apps/platform/app/Filament/Concerns/ClearsWorkspaceHubEnvironmentFilterState.php
apps/platform/resources/views/filament/partials/workspace-hub-environment-filter-chip.blade.php
apps/platform/app/Support/Navigation/WorkspaceSidebarNavigation.php
apps/platform/app/Support/ManagedEnvironmentLinks.php
apps/platform/app/Support/OperationRunLinks.php
apps/platform/routes/web.php

Existing related tests and smoke coverage:

apps/platform/tests/Feature/Navigation/WorkspaceHubRegistryTest.php
apps/platform/tests/Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php
apps/platform/tests/Feature/Navigation/WorkspaceHubClearFilterContractTest.php
apps/platform/tests/Feature/Navigation/WorkspaceHubSidebarUrlContractTest.php
apps/platform/tests/Feature/Navigation/Spec321AlertsAuditEnvironmentFilterContractTest.php
apps/platform/tests/Feature/Guards/LegacyTenantPlatformContextCleanupTest.php
apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php
apps/platform/tests/Feature/Filament/BaselineCompareEnvironmentRouteContractTest.php
apps/platform/tests/Browser/Spec314WorkspaceHubNavigationContextSmokeTest.php
apps/platform/tests/Browser/Spec316WorkspaceHubClearFilterSmokeTest.php
apps/platform/tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php

Spec 322 should extend or add targeted files rather than replacing these proven anchors.

Project Structure

Spec Artifacts

specs/322-browser-no-drift-regression-guard/spec.md
specs/322-browser-no-drift-regression-guard/plan.md
specs/322-browser-no-drift-regression-guard/tasks.md
specs/322-browser-no-drift-regression-guard/test-plan.md
specs/322-browser-no-drift-regression-guard/coverage-manifest.md
specs/322-browser-no-drift-regression-guard/checklists/requirements.md
specs/322-browser-no-drift-regression-guard/artifacts/screenshots/.gitkeep

Likely Runtime/Test Areas For Later Implementation

apps/platform/tests/Feature/Navigation/Spec322AdminSurfaceScopeContractTest.php
apps/platform/tests/Feature/Navigation/Spec322LegacyQueryAliasGuardTest.php
apps/platform/tests/Feature/Navigation/Spec322EnvironmentCtaUrlContractTest.php
apps/platform/tests/Browser/Spec322WorkspaceHubNoDriftSmokeTest.php
apps/platform/tests/Browser/Spec322EnvironmentOwnedSurfaceSmokeTest.php
apps/platform/tests/Browser/Spec322WorkspaceOwnedAnalysisSmokeTest.php
apps/platform/tests/Browser/Spec322AlertsAuditNoDriftSmokeTest.php
apps/platform/tests/Browser/Support/Spec322WorkspaceEnvironmentBrowserHarness.php

The support harness path is suggested, not mandatory. If existing helper conventions provide enough reuse, implementation should keep helpers local to the test files.

UI / Surface Guardrail Plan

  • Guardrail scope: Workflow-only guardrail over existing surfaces.
  • Native vs custom classification summary: Existing Filament-native surfaces; no new product UI.
  • Shared-family relevance: Navigation, shell, filter chip, clear/reset, browser history.
  • State layers in scope: route path, query string, Livewire properties, Filament table filters, deferred filters, persisted/session filters, shell context, chip visibility, browser history.
  • Audience modes in scope: operator-MSP and support-platform only as existing users; no new disclosure modes.
  • Decision/diagnostic/raw hierarchy plan: N/A - guard assertions only.
  • Raw/support gating plan: N/A.
  • One-primary-action / duplicate-truth control: Existing clear action remains the only filter reset control under test.
  • Handling modes by drift class or surface: Workspace/Environment mismatch is a hard-stop candidate for implementation; optional unreachable browser surfaces are document-in-feature only if Feature coverage proves the contract.
  • Repository-signal treatment: Review-mandatory for new admin surfaces missing manifest/test coverage.
  • Special surface test profiles: global-context-shell.
  • Required tests or manual smoke: Feature/static guards plus Pest Browser smoke tests.
  • Exception path and spread control: Any browser gap must be documented in coverage-manifest.md with deterministic non-browser proof.
  • Active feature PR close-out entry: Guardrail / Smoke Coverage.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes
  • Systems touched: Navigation registry, surface scope enum, Environment filter resolver, filter resetter, shell context, browser tests.
  • Shared abstractions reused: WorkspaceHubRegistry, AdminSurfaceScope, WorkspaceHubEnvironmentFilter, WorkspaceHubFilterStateResetter, ClearsWorkspaceHubEnvironmentFilterState, shared filter chip partial.
  • New abstraction introduced? why?: No runtime abstraction. Test-only helper extraction is allowed only when it reduces repeated fragile browser setup.
  • Why the existing abstraction was sufficient or insufficient: Runtime abstractions are sufficient; current gap is durable cross-surface guard coverage.
  • Bounded deviation / spread control: Test helpers must remain in test support or local browser test scope and must not become product navigation registries.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: no
  • Central contract reused: N/A
  • Delegated UX behaviors: N/A
  • Surface-owned behavior kept local: Existing Operations hub may be used as a workspace hub test surface.
  • Queued DB-notification policy: N/A
  • Terminal notification path: N/A
  • Exception path: none

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes, guard-only
  • Provider-owned seams: Microsoft/Entra/provider Tenant identity terms remain allowed through Spec 317 allowlist.
  • Platform-core seams: Workspace, Managed Environment, Environment filter query key, shell ownership, route ownership.
  • Neutral platform terms / contracts preserved: Workspace, Managed Environment, Environment, Provider Connection.
  • Retained provider-specific semantics and why: Provider Tenant terminology remains where it means external Microsoft/Entra tenant identity.
  • Bounded extraction or follow-up path: none expected; implementation should add a follow-up only if a current provider-boundary term is ambiguous outside the allowlist.

Constitution Check

Pre-Implementation

  • Inventory-first / Snapshots-second: Pass. No inventory or snapshot truth changes.
  • Read/write separation: Pass. No product write actions are introduced.
  • Graph contract path: Pass. No Graph calls are introduced.
  • Deterministic capabilities: Pass. Capability behavior is not changed.
  • Workspace isolation: Pass with required tests. Cross-workspace Environment IDs must be rejected.
  • Tenant isolation / provider boundary: Pass with required legacy alias and provider Tenant allowlist guards.
  • RBAC-UX: Pass with required tests for non-member/unauthorized Environment behavior where applicable.
  • OperationRun UX: N/A.
  • Test governance: Requires explicit Browser lane expansion, manifest, and test-plan documentation.
  • Proportionality: Pass. No runtime persistence, enum/status family, or runtime framework. Test-only helper extraction must stay narrow.
  • Shared Pattern First: Pass. Existing runtime paths are reused.
  • Filament-native UI: Pass. No product UI changes; assertions target existing native/shared surfaces.
  • Spec Candidate Gate: Pass. Direct manual promotion and already referenced follow-up from completed specs.

Post-Design

No constitutional violation is expected.

If implementation discovers that passing the guards requires product behavior changes beyond a narrow fix to existing Specs 314 through 321 contracts, update spec.md and plan.md before continuing.

If implementation adds a runtime registry, persisted entity, enum, or broad helper layer, reopen the proportionality review and stop for review.

Surface Classification Plan

Source classification comes from existing runtime contracts plus Spec 318 audit terminology.

Classification Runtime contract
workspace_hub Workspace-only shell; optional explicit filter when supported
environment_owned_page Workspace + Environment shell; Environment route required
workspace_owned_analysis_surface Workspace-only shell; no remembered Environment shell inheritance
workspace_configuration_surface Workspace-only shell; configuration semantics; no Environment chip unless explicitly supported
system_platform_surface System panel or non-admin platform surface
out_of_scope Not stable/reachable or not part of this guard

The manifest must use these labels and must be updated when future specs add admin surfaces.

Feature / Static Guard Plan

Create or update focused tests for:

  • it('classifies_core_admin_surfaces_without_scope_drift')
  • it('workspace_hub_clean_urls_never_emit_environment_or_legacy_query_params')
  • it('environment_cta_urls_use_the_correct_surface_contract')
  • it('clear_filter_results_match_clean_workspace_hub_entry_for_filterable_hubs')
  • it('environment_id_filters_reject_cross_workspace_environment_ids')
  • it('legacy_environment_query_aliases_do_not_create_filter_or_shell_state')
  • it('has_no_active_legacy_tenant_panel_routes')
  • it('allows_tenant_terms_only_in_provider_boundary_contexts')

Use existing tests where possible and add Spec 322 coverage only for gaps.

Browser Guard Plan

Use Pest Browser. Do not introduce Playwright MCP dependency.

Group browser tests by contract:

  1. Workspace hub clean entry, reload, and sidebar/global/direct origins.
  2. Workspace hub filtered entry, chip, clear, reload, and back/forward.
  3. Environment-owned route/shell contract and invalid clean workspace access.
  4. Workspace-owned analysis and workspace configuration shell cutover.
  5. Alerts/Audit Log focused no-drift smoke.

Screenshots are diagnostic only. Store useful artifacts under:

specs/322-browser-no-drift-regression-guard/artifacts/screenshots/

Data / Migration Plan

No migrations are planned.

No new tables, persisted entities, seeders, packages, env vars, queues, scheduler, storage, deployment assets, or compatibility layers are planned.

If deterministic browser fixtures cannot be produced without a seeder change, update the spec and plan first. Prefer test factories and explicit fixture helpers.

Authorization / Security Plan

  • Use existing workspace and Managed Environment access helpers/factories.
  • Assert cross-workspace and unauthorized Environment IDs do not leak data and do not switch Workspace.
  • Keep UI state out of the authorization boundary; guard server-side behavior via Feature tests where possible.
  • Keep /admin/t and TenantPanelProvider absence guarded.

Filament v5 Output Contract

  1. Livewire v4.0+ compliance: Required. The app uses Livewire 4.1.4; tests and any narrow fixes must not introduce Livewire v3 references.
  2. Provider registration location: No provider changes are planned. Laravel 12 Filament panel providers remain in apps/platform/bootstrap/providers.php.
  3. Globally searchable resources: Spec 322 should not make any resource globally searchable. Existing resources must continue either to have View/Edit pages or have global search disabled according to Filament v5 rules.
  4. Destructive actions: Spec 322 introduces no destructive product actions. If a narrow runtime fix touches an existing destructive action, it must preserve ->action(...), ->requiresConfirmation(), policy/gate authorization, and audit behavior.
  5. Asset strategy: No global or on-demand Filament assets are planned. No deployment filament:assets change is required.
  6. Testing plan: Feature/static guards plus Pest Browser tests for pages/resources as Livewire/browser-visible surfaces. Mutating actions are not introduced.

Test Governance Check

  • Test purpose / classification by changed surface: Feature/static for registries, URLs, aliases, and authorization; Browser for shell/chip/clear/reload/history.
  • Affected validation lanes: fast-feedback, browser, and optional heavy-governance if discovery-style guard breadth expands.
  • Why this lane mix is the narrowest sufficient proof: Feature tests can exhaustively prove deterministic contracts. Browser is required only for browser state and visible shell/chip/history.
  • Narrowest proving commands: Listed in test-plan.md.
  • Fixture / helper / factory / seed / context cost risks: Browser setup can grow. Keep helper defaults explicit and avoid global seed reliance.
  • Expensive defaults or shared helper growth introduced?: Not by default. Any browser harness must be opt-in.
  • Heavy-family additions, promotions, or visibility changes: Explicit Spec322 Browser smoke files.
  • Surface-class relief / special coverage rule: global-context-shell.
  • Closing validation and reviewer handoff: Review manifest, test names, helper cost, focused commands, browser gap documentation, and absence of runtime compatibility aliases.
  • Budget / baseline / trend follow-up: Document runtime if materially higher than existing Spec 314/316 browser smoke.
  • Review-stop questions: Are browser tests focused? Are legacy aliases rejected rather than accepted? Are optional gaps documented? Does any helper create hidden fixture cost?
  • Escalation path: document-in-feature; follow-up-spec only if browser lane cost becomes structural.
  • Active feature PR close-out entry: Guardrail / Smoke Coverage.
  • Why no dedicated follow-up spec is needed: Spec 322 is the dedicated no-drift guardrail package.

Implementation Phases

  1. Confirm existing surface classifications and route/helper names.
  2. Add/update coverage manifest with all required surfaces and current planned coverage.
  3. Add Feature/static guards for classifications, URLs, legacy aliases, cross-workspace rejection, /admin/t, and provider Tenant allowlist.
  4. Add or refactor test-only browser helper patterns if existing duplication becomes brittle.
  5. Add grouped Pest Browser smoke tests for workspace hubs, Environment-owned pages, workspace-owned analysis/configuration surfaces, and Alerts/Audit Log.
  6. Run focused Feature/static tests.
  7. Run focused Browser tests.
  8. Update coverage manifest with actual coverage and any browser gaps.
  9. Run formatting and git diff --check.
  10. Report exact test commands/results and no-runtime-change confirmations.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
Browser lane expansion Shell/chip/clear/reload/history alignment is browser-visible and cannot be proven by static tests alone Existing per-spec smoke tests do not cover the full stabilized chain or Alerts/Audit Log after Spec 321
Coverage manifest Future surfaces need an explicit coverage contract Relying on test file names alone would hide browser gaps and classification drift

Rollout Considerations

  • No runtime rollout impact is expected.
  • No staging/production migration or deployment step is expected.
  • CI should include the focused Feature/static guard command and the Browser lane command when Browser infrastructure is available.
  • Do not claim full suite green unless the full suite is actually run.

Risks And Controls

Risk Control
Browser suite becomes flaky or too broad Group smoke tests by surface model, assert stable text/URL/chip state, move exhaustive alias coverage to Feature tests
Test helper hides expensive setup Keep workspace/environment/session setup explicit and opt-in
Optional surfaces are silently skipped Document gaps and reasons in coverage-manifest.md
Legacy aliases are accidentally accepted in tests Feature guards must assert aliases do not create filter or shell state
Runtime behavior changes beyond guard fixes Update spec/plan before continuing

Validation Plan

See test-plan.md for exact targeted commands.

Minimum final validation:

cd apps/platform
./vendor/bin/sail artisan test tests/Feature/Navigation/Spec322AdminSurfaceScopeContractTest.php tests/Feature/Navigation/Spec322LegacyQueryAliasGuardTest.php tests/Feature/Navigation/Spec322EnvironmentCtaUrlContractTest.php --compact
./vendor/bin/sail artisan test tests/Browser/Spec322WorkspaceHubNoDriftSmokeTest.php tests/Browser/Spec322EnvironmentOwnedSurfaceSmokeTest.php tests/Browser/Spec322WorkspaceOwnedAnalysisSmokeTest.php tests/Browser/Spec322AlertsAuditNoDriftSmokeTest.php --compact
./vendor/bin/sail pint --dirty
git diff --check

Exact file names may be adjusted during implementation if existing repo conventions make narrower updates preferable.