## 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
315 lines
19 KiB
Markdown
315 lines
19 KiB
Markdown
# 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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```bash
|
|
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.
|