## 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
29 KiB
Feature Specification: Browser No-Drift Regression Guard
Feature Branch: 322-browser-no-drift-regression-guard
Created: 2026-05-17
Status: Draft
Input: User supplied full Spec 322 draft: "Browser No-Drift Regression Guard"
Type: Durable regression coverage / browser contract guard / no-drift enforcement
Runtime Posture: Test/guard-first. No new product behavior unless required to make guards deterministic.
Dependencies
- Spec 314: Workspace Hub Navigation Context Contract
- Spec 315: Environment CTA Explicit Filter Contract
- Spec 316: Workspace Hub Clear Filter Contract
- Spec 317: Legacy Tenant / Environment Context Cleanup
- Spec 318: Admin Surface Scope & Shell Context Audit
- Spec 319: Environment-Owned Surface Routing & Shell Context Contract
- Spec 320: Workspace-Owned Analysis Surface Registration & Shell Cutover
- Spec 321: Alerts / Audit Log Environment Filter Contract Decision
Spec Candidate Check
- Problem: Workspace, Environment, filter, shell, clear-state, and legacy Tenant cleanup contracts now span routes, Filament pages/resources, Livewire state, session persistence, sidebar/global navigation, and browser history. Without durable guards, future specs can reintroduce hidden Environment shell inheritance or stale filter state.
- Today's failure: A future page or helper could emit
tenant,managed_environment_id, remembered Environment state, or a workspace-clean URL that silently renders Environment-owned data. Operators would see mismatched shell, URL, filter chip, and data scope. - User-visible improvement: Operators get consistent Workspace-only hubs, explicit Environment-owned pages, visible filtered state, reliable clear behavior, and no resurrected legacy Tenant platform context.
- Smallest enterprise-capable version: Add focused Feature/static guards plus grouped Pest Browser contract smoke tests for core high-risk surfaces, with a coverage manifest documenting any browser gaps.
- Explicit non-goals: No product redesign, no new Environment filters, no Alert/Audit contract change beyond Spec 321, no migrations, no seeders unless deterministic browser fixtures are impossible, no packages, no compatibility aliases, no Playwright MCP dependency, no visual-regression framework.
- Permanent complexity imported: New or updated Pest Feature tests, Pest Browser smoke tests, test-only helper structure where existing browser conventions are insufficient, coverage manifest, test plan, and ongoing maintenance obligation for new admin surfaces.
- Why now: Specs 314 through 321 intentionally stabilized the contracts and repeatedly deferred durable no-drift coverage to Spec 322. Spec 321 is now implemented on the current branch history, so the guard can cover the full chain.
- Why not local: Local tests per surface already exist, but drift risk is cross-surface and browser-state-dependent. A single future change can break URL/chip/shell/session/history alignment across several surfaces.
- Approval class: Core Enterprise
- Red flags triggered: Cross-surface coverage and test infrastructure. Defense: the scope is test-only and protects workspace isolation, Environment ownership, auditability, and operator trust without adding runtime product frameworking.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 1 | Wiederverwendung: 2 | Gesamt: 10/12
- Decision: approve
Candidate Source And Guardrail Result
Candidate Source: Direct user-provided manual promotion for Spec 322. The candidate is also referenced as deferred follow-up in Specs 319, 320, and 321.
Completed-Spec Guardrail: Specs 314 through 321 were inspected as completed or historical context and remain unchanged by this preparation. This package creates a new Spec 322 path and does not rewrite close-out, validation, completed tasks, smoke evidence, or review history from earlier specs.
Close alternatives deferred:
- Customer Review Workspace v1 polish: productization lane after context foundations are protected.
- Decision-Based Governance Inbox v1 polish: product lane after no-drift guards exist.
- Localization v1 and commercial lifecycle maturity: roadmap product lanes, not guardrail completion.
- Broad visual regression framework: deferred as too heavy for the current need.
Summary
Add durable browser and regression coverage to prevent Workspace / Environment context drift from returning.
Specs 314 through 321 established these product contracts:
- Workspace hubs use Workspace-only shell ownership.
- Environment Dashboard CTAs use canonical
?environment_id=...when they intentionally filter a workspace hub. - Clear filter removes URL, Livewire, Filament table, deferred table, session, and persisted state.
- Legacy Tenant platform context is removed or quarantined.
- Environment-owned pages require Environment route/shell context.
- Workspace-owned analysis pages cut over to Workspace-only shell.
- Alerts and Audit Log have explicit Spec 321 contracts.
Spec 322 turns those contracts into maintainable guards.
Product Context
TenantPilot is workspace-first.
Workspace is the primary platform context. Managed Environment is a secondary operational context inside a Workspace. Provider Tenant remains only a provider-boundary concept, such as Microsoft/Entra/Graph tenant identity.
The guarded admin surface models are:
| Model | Expected contract |
|---|---|
| Workspace Hub | Workspace-only shell, clean workspace-wide URL, optional canonical environment_id filter if supported, visible chip when filtered, clear returns to clean state |
| Environment-Owned Page | Workspace + Environment shell, route encodes Environment ownership, no clean workspace-only rendering, no workspace-hub environment_id model |
| Workspace-Owned Analysis Surface | Workspace-only shell, no remembered Environment inheritance, optional environment_id only where explicitly supported |
| Workspace Configuration Surface | Workspace-only shell, no Environment filter unless explicitly supported |
Spec Scope Fields
- Scope: canonical-view / workspace shell and Environment route guardrail
- Primary Routes:
/admin,/admin/workspaces/{workspace}/operations,/admin/provider-connections,/admin/finding-exceptions/queue,/admin/evidence/overview,/admin/reviews,/admin/reviews/workspace,/admin/governance/inbox,/admin/governance/decisions,/admin/audit-log,/admin/alerts,/admin/alerts/alert-deliveries,/admin/alerts/alert-rules,/admin/alerts/alert-destinations,/admin/settings/workspace,/admin/workspaces/{workspace}/environments/{environment}, Environment-owned subroutes,/admin/baseline-profiles,/admin/baseline-snapshots,/admin/findings/my-work,/admin/findings/intake,/admin/findings/hygiene,/admin/cross-environment-compare - Data Ownership: No new persisted data. Guards must prove existing workspace-owned and Environment-owned records remain scoped by current Workspace and authorized Environment membership.
- RBAC: Tests must use existing workspace membership and Managed Environment access fixtures. Cross-workspace or unauthorized Environment IDs must resolve as safe no-access / deny-as-not-found behavior.
For canonical-view specs:
- Default filter behavior when Environment context is active: Workspace hubs and workspace-owned analysis surfaces must remain Workspace-only unless a valid canonical
environment_idquery parameter is present and the surface explicitly supports it. - Explicit entitlement checks preventing cross-environment leakage: Feature tests must prove cross-workspace and unauthorized Environment IDs do not switch Workspace, do not leak data, and do not create shell/filter state.
Cross-Cutting / Shared Pattern Reuse
- Cross-cutting feature?: yes
- Interaction class(es): navigation, context shell, filter chip, clear filter, browser history, global/sidebar entries, Environment Dashboard CTAs, test lane governance
- Systems touched:
WorkspaceHubRegistry,AdminSurfaceScope,WorkspaceHubEnvironmentFilter,WorkspaceHubFilterStateResetter,ClearsWorkspaceHubEnvironmentFilterState, shared chip partial, route helpers, browser tests, Feature guards - Existing pattern(s) to extend: Existing Spec 314, 316, 319, 320, and 321 guard tests and browser smoke tests
- Shared contract / presenter / builder / renderer to reuse: Existing navigation/filter/reset helpers and existing Pest Browser conventions
- Why the existing shared path is sufficient or insufficient: Existing paths are sufficient for runtime behavior. Spec 322 may add test-only helper organization if required to avoid copying brittle browser setup across every surface.
- Allowed deviation and why: Test-only helper extraction is allowed when it remains under test support paths and does not become a runtime surface registry.
- Consistency impact: URL, visible chip, shell text, data scope, clear action, reload, and browser history must remain aligned.
- Review focus: Verify guards protect contracts without changing product behavior or accepting legacy aliases.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no
- Shared OperationRun UX contract/layer reused: N/A
- Delegated start/completion UX behaviors: N/A
- Local surface-owned behavior that remains: Existing Operations hub and OperationRun links may be used as tested surfaces only.
- Queued DB-notification policy: N/A
- Terminal notification path: N/A
- Exception required?: none
Provider Boundary / Platform Core Check
- Shared provider/platform boundary touched?: yes, in guard assertions only
- Boundary classification: mixed; platform-core shell/query contracts are guarded while provider-boundary Tenant terminology remains allowlisted where it means Microsoft/Entra/provider tenant identity
- Seams affected: query keys, URL helpers, provider-boundary terminology allowlist, legacy Tenant route guards
- Neutral platform terms preserved or introduced: Workspace, Managed Environment, Environment, Provider Connection
- Provider-specific semantics retained and why:
tenantremains allowed only in provider-boundary contexts documented by Spec 317 allowlist. - Why this does not deepen provider coupling accidentally: The spec rejects Tenant as Environment/platform synonym and adds guards against old query aliases.
- Follow-up path: none unless implementation discovers a current provider-boundary ambiguity not covered by Spec 317.
UI / Surface Guardrail Impact
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Browser regression guards for existing admin surfaces | no product UI change | Existing Filament surfaces | navigation, shell, filter chip | shell, URL-query, Livewire, table filters, session, browser history | no | Test-only guardrail |
| Coverage manifest | no | N/A | test governance | none | no | Documentation artifact for guard coverage |
Decision-First Surface Role
Spec 322 does not add or materially change operator-facing surfaces. The guarded surfaces keep their existing roles:
- Workspace hubs remain Secondary Context / operational workspace surfaces.
- Environment-owned pages remain Environment-specific decision/diagnostic surfaces.
- Workspace-owned analysis surfaces remain workspace-level analysis surfaces.
- Configuration surfaces remain workspace configuration surfaces.
Audience-Aware Disclosure
N/A - no product-facing detail/status surface is added or materially changed.
UI/UX Surface Classification
No operator-facing surface classification changes are introduced. The classifications are documented in coverage-manifest.md for guard coverage only.
Operator Surface Contract
No new page contract is introduced. The tests must assert that existing page contracts remain truthful:
- Workspace hub shell copy must not imply an active Environment when the URL is clean.
- Filtered workspace hubs must show visible Environment chip state.
- Environment-owned pages must show Workspace + active Environment shell context.
- Configuration surfaces must not show Environment filter chips from query aliases.
Proportionality Review
- New source of truth?: no runtime source of truth; yes test-documentation truth in
coverage-manifest.md - New persisted entity/table/artifact?: no persisted entity/table; yes Spec Kit documentation artifacts
- New abstraction?: no runtime abstraction; possible test-only harness helpers if duplication requires them
- New enum/state/reason family?: no
- New cross-domain UI framework/taxonomy?: no runtime UI framework; the manifest uses test classifications already established by Specs 318 through 321
- Current operator problem: Operators and reviewers need confidence that Workspace/Environment context cannot silently drift across navigation, filters, reload, and history.
- Existing structure is insufficient because: Current focused tests cover slices but do not provide a durable coverage map and grouped browser guard suite across the whole stabilized chain.
- Narrowest correct implementation: Add explicit Feature/static guards plus focused Browser smoke files grouped by surface model, reusing existing helpers and only extracting test helpers if repeated setup becomes brittle.
- Ownership cost: Browser lane runtime and future maintenance when new admin surfaces are added.
- Alternative intentionally rejected: Full visual regression framework and broad Playwright MCP dependency.
- Release truth: Current-release guardrail over existing implemented contracts.
Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope. Legacy query aliases must not be supported or redirected.
Testing / Lane / Runtime Impact
- Test purpose / classification: Feature, Heavy-Governance, Browser
- Validation lane(s): fast-feedback for static/Feature guards; browser for critical shell/filter/history smoke; heavy-governance if a registry/discovery guard is added or materially expanded
- Why this classification and these lanes are sufficient: URL generation, classification, legacy alias rejection, and cross-workspace rejection are deterministic Feature tests. Shell/chip/reload/back-forward alignment is browser-visible and belongs in Browser lane.
- New or expanded test families: Expanded Spec 322 browser no-drift family plus feature guard files under
apps/platform/tests/Feature/Navigationor existing guard directories. - Fixture / helper cost impact: Existing workspace/environment factories and browser fixture patterns should be reused. Any new helper must keep workspace, membership, session, and Environment setup explicit.
- Heavy-family visibility / justification: Browser tests are explicitly named
Spec322...SmokeTestand grouped by surface model to keep lane cost visible. - Special surface test profile: global-context-shell
- Standard-native relief or required special coverage: Special coverage required because shell, URL, Livewire/table/session, and browser history can drift independently.
- Reviewer handoff: Reviewers must verify lane fit, helper cost, surface manifest accuracy, and that Browser tests do not become one large flaky scenario.
- Budget / baseline / trend impact: Browser lane expands. Runtime must be documented in implementation close-out if material.
- Escalation needed: document-in-feature unless the Browser lane becomes structurally expensive; then follow-up-spec.
- Active feature PR close-out entry: Guardrail / Smoke Coverage
- Planned validation commands: See
test-plan.md.
User Scenarios & Testing
User Story 1 - Workspace hubs stay clean and reload-safe (Priority: P1)
As a workspace operator who previously worked inside a Managed Environment, I can open workspace hubs from sidebar/global/direct clean URLs and see Workspace-only shell, no Environment filter chip, and no legacy query state.
Why this priority: Clean workspace hub entry is the foundation for all other scope contracts.
Independent Test: Start from an Environment Dashboard with remembered Environment state, open each required workspace hub clean URL or sidebar/global link, reload, and assert clean URL, Workspace-only shell, no chip, and no legacy query params.
Acceptance Scenarios:
- Given an active remembered Environment, when Operations opens through its clean workspace URL, then no Environment query parameter, shell, or chip is present.
- Given a clean workspace hub is reloaded, when the page returns, then no stale Environment shell or chip appears.
User Story 2 - Filtered workspace hubs expose visible and clearable Environment focus (Priority: P1)
As an operator drilling from an Environment-owned page into a filterable workspace hub, I can see the canonical environment_id filter as a visible chip and clear it back to the clean workspace-wide page.
Why this priority: Hidden filters create the highest trust risk because data can be narrowed while the shell looks workspace-wide.
Independent Test: Open each filterable hub with ?environment_id={id}, assert chip and filtered data, clear it, reload, and assert workspace-wide state.
Acceptance Scenarios:
- Given a valid current Workspace Environment ID, when Provider Connections opens with
environment_id, then the shell remains Workspace-only and the chip names that Environment. - Given the filter is cleared, when the browser reloads, then URL, chip, table state, and shell remain clean.
User Story 3 - Browser history never creates URL/chip/shell mismatch (Priority: P1)
As an operator using browser back and forward after filtering and clearing, I see URL, visible chip, shell context, and data scope remain aligned.
Why this priority: Browser history was a high-risk source of stale Livewire/session state in Specs 314 through 316.
Independent Test: For required high-risk hubs, open filtered URL, clear, go back, go forward, and assert alignment after each transition.
Acceptance Scenarios:
- Given back returns to a URL containing
environment_id, then the chip exists and shell remains Workspace-only. - Given forward returns to a clean URL, then the chip is absent and shell remains Workspace-only.
User Story 4 - Environment-owned pages require Environment route and shell (Priority: P1)
As an operator entering an Environment-owned page, I see Workspace + Environment shell context and cannot access that page through an old clean workspace-only URL or remembered fallback.
Why this priority: Baseline Compare and adjacent Environment-owned pages must not regress into workspace-hub filter semantics.
Independent Test: Open Environment-owned pages from Environment Dashboard or canonical Environment routes, reload, navigate away/back, and assert Environment shell. Attempt former clean workspace-only access where routes exist and assert safe 404/no-access/redirect behavior.
Acceptance Scenarios:
- Given Baseline Compare opens from Environment Dashboard, then its URL contains the Environment route segment and no workspace-hub
environment_idquery model. - Given an old workspace-only Baseline Compare URL with
environment_id, then it does not render a valid Environment page.
User Story 5 - Workspace-owned analysis and configuration surfaces cut away from Environment shell (Priority: P2)
As an operator opening analysis or configuration pages from an Environment origin, I see Workspace-only shell and no remembered Environment shell inheritance.
Why this priority: These surfaces are likely future navigation targets and must stay workspace-owned.
Independent Test: Start from Environment Dashboard, open each analysis/configuration surface by clean URL or navigation, reload, and assert Workspace-only shell and no chip unless the URL explicitly supports filtering.
Acceptance Scenarios:
- Given Baseline Profiles opens from Environment Dashboard, then shell is Workspace-only and no Environment chip appears.
- Given Alert Rules opens with a stray
environment_id, then no Environment chip or shell context appears.
User Story 6 - Legacy Tenant aliases remain invalid (Priority: P2)
As a reviewer or future implementer, I have deterministic guards proving legacy Tenant query aliases and /admin/t routes cannot create Environment filter or shell state.
Why this priority: Spec 317 cleanup must not be undone by future helper or copied test fixture drift.
Independent Test: Feature tests cover all legacy alias keys across representative surfaces; browser smoke covers a representative subset without making the browser suite huge.
Acceptance Scenarios:
- Given
tenant,tenant_id,managed_environment_id,environment,tenant_scope, ortableFiltersare present on a workspace hub URL, then no Environment filter state appears. - Given
/admin/t/...is requested, then it is not an active route and no Tenant panel provider is registered.
Edge Cases
- Cross-workspace
environment_idis supplied to a filterable workspace hub. - A valid current Workspace Environment ID is supplied but the actor lacks access.
- Legacy aliases appear together with unrelated query parameters.
- Legacy aliases appear together with canonical
environment_id; only canonical behavior is allowed, and no legacy alias may survive generated links. - Livewire table filters or deferred filters have remembered Environment-like state.
- Session-persisted table filters survive from an earlier page visit.
- Browser back/forward restores a filtered URL after clear.
- Environment-owned page has a legacy workspace-only route or landing alias.
- Alert/Audit rows with null Environment attribution exist.
- Optional pages are unreachable or lack deterministic fixtures.
- Browser profile or local environment blocks browser execution.
Requirements
Functional Requirements
- FR-001: The coverage manifest MUST list every required surface with classification, clean URL, filtered URL support, Environment route requirement, clear support, Browser coverage status, Feature coverage status, and notes.
- FR-002: Workspace hub clean-entry guards MUST cover Operations, Governance Inbox, Decision Register, Finding Exceptions Queue, Provider Connections, Evidence Overview, Reviews, Customer Reviews, Alert Deliveries, and Audit Log.
- FR-003: Filtered workspace hub guards MUST cover filterable hubs using canonical
environment_idand MUST reject legacy query aliases. - FR-004: Clear-filter guards MUST prove URL, Livewire state, Filament table filters, deferred filters, persisted/session state, chip state, and shell context return to clean workspace-wide state where the surface supports clearing.
- FR-005: Browser back/forward guards MUST cover Provider Connections, Finding Exceptions Queue, Customer Reviews, Evidence Overview, Alert Deliveries, and Audit Log.
- FR-006: Environment-owned page guards MUST cover Environment Dashboard, Baseline Compare, Required Permissions, Provider Readiness / Onboarding Readiness, and Inventory or Inventory Coverage if browser-stable.
- FR-007: Baseline Compare MUST have a browser guard and a clean workspace-only invalid-access guard.
- FR-008: Workspace-owned analysis guards MUST cover Baseline Profiles, Baseline Snapshots, My Findings, Findings Intake, Findings Hygiene, and Cross-environment Compare.
- FR-009: Workspace configuration guards MUST cover Alert Rules, Alert Destinations, and Workspace Settings as Workspace-only surfaces.
- FR-010: Legacy Tenant alias guards MUST cover
tenant,tenant_id,managed_environment_id,environment,tenant_scope, andtableFilters. - FR-011: No active
/admin/troute and no activeTenantPanelProvidermay exist. - FR-012: Provider-boundary Tenant terminology MUST remain allowed only through the Spec 317 allowlist or equivalent current guard.
- FR-013: Cross-workspace Environment IDs MUST be rejected with safe no-access behavior and must not leak data or switch Workspace.
- FR-014: Browser helpers MUST avoid brittle selectors where stable text, route, ARIA, or
data-testidhooks already exist. - FR-015: Browser tests MUST stay grouped and focused rather than one large all-in-one scenario.
- FR-016: Any browser gap MUST be documented in the coverage manifest with a blocker reason and backed by deterministic Feature/Unit coverage.
- FR-017: No product behavior may be changed except narrow fixes required to satisfy existing Specs 314 through 321 contracts.
- FR-018: No migrations, seeders, packages, env vars, queues, scheduler, storage, or deployment asset changes are allowed unless the spec is updated before implementation continues.
Non-Functional Requirements
- NFR-001: Browser tests MUST avoid sleeps and volatile row-count assertions unless seeded data makes them deterministic.
- NFR-002: Feature/static guards SHOULD cover exhaustive alias and registry checks so Browser tests remain smoke-level.
- NFR-003: Test setup MUST keep workspace, membership, Environment access, session, and provider fixture cost explicit.
- NFR-004: Test names MUST make heavy/browser lane cost visible, using
Spec322prefixes. - NFR-005: Filament v5 / Livewire v4 patterns MUST remain in test code. No Livewire v3 or Filament v3/v4 assumptions.
- NFR-006: Browser screenshots MAY be diagnostic, but assertions are authoritative.
- NFR-007: Guard failures MUST identify the surface and mismatch clearly enough for follow-up repair.
- NFR-008: The implementation MUST not introduce Playwright MCP dependency; use Pest Browser coverage unless the spec is explicitly revised.
Data / Truth-Source Requirements
- DTR-001: The coverage manifest is the documentation truth for Spec 322 guard coverage, not runtime product truth.
- DTR-002: Test data must use existing factories and persisted records only to prove scope alignment.
- DTR-003: Environment filtering truth remains canonical
environment_id; legacy aliases are invalid inputs. - DTR-004: Provider Tenant terms remain provider-boundary terminology only.
Out Of Scope
- New product features.
- Redesigning pages.
- Changing navigation IA unless a guard reveals an existing in-scope regression requiring a narrow fix.
- Changing Environment CTA behavior except to satisfy existing contract.
- Adding new Environment filters.
- Changing Alerts/Audit Log decisions from Spec 321.
- Refactoring all Filament pages.
- Adding a full visual-regression framework.
- Introducing Playwright MCP dependency.
- Requiring manual screenshots for every run.
- Adding flaky tests.
- Adding migrations, seeders, packages, env vars, queues, scheduler, storage, deployment assets, or compatibility layers.
Success Criteria
- SC-001:
coverage-manifest.mdexists and lists all required surfaces with coverage status and gaps. - SC-002: Feature/static guards cover classification, clean URLs, Environment CTA URLs, clear filter, cross-workspace rejection, legacy aliases,
/admin/t, Tenant panel provider absence, and provider Tenant allowlist. - SC-003: Browser guards cover clean workspace hub entry, filtered entry, clear/reload, back/forward, Environment-owned pages, workspace-owned analysis pages, workspace configuration pages, and Alerts/Audit Log contracts at the scope defined in
test-plan.md. - SC-004: Browser gaps, if any, are explicit and have deterministic non-browser guard coverage.
- SC-005: Targeted Feature/Unit and Browser commands pass, or failures are documented with exact blockers.
- SC-006:
git diff --checkpasses. - SC-007: No broad runtime/product change is introduced.
Assumptions
- Pest Browser is the preferred durable browser lane because the repo already uses it.
- Existing browser helpers and fixtures can be reused or lightly factored without adding runtime abstraction.
- Spec 321 runtime implementation is present in current branch history and may be guarded by Spec 322.
- Some optional surfaces may remain Feature-covered only if browser fixtures are not stable or routes are not reachable.
Open Questions
None blocking preparation.
Implementation may discover browser-only fixture gaps. Those should be documented in coverage-manifest.md and covered by deterministic Feature/Unit guards rather than silently skipped.
Follow-Up Spec Candidates
- Customer Review Workspace v1 polish / productization.
- Decision-Based Governance Inbox v1 polish.
- Localization v1 customer-facing surfaces.
- Cross-Tenant Compare & Promotion v1 productization.
- Commercial entitlements / billing-state maturity.
These are product lanes and are not part of Spec 322.
Required Final Report Shape
Implementation close-out must report:
- Changed behavior.
- Coverage added.
- Feature tests command and result.
- Browser tests command and result.
- Coverage manifest status.
- Known browser gaps.
- Remaining risks.
- Test files added/updated.
- Surfaces covered.
- Surfaces excluded with reason.
- Whether screenshots were saved.
- Whether full suite was run.
- Known unrelated residual failures.
- Confirmation that no migrations, seeders, packages, env vars, queues, scheduler, storage, deployment asset changes, backwards compatibility layer, or legacy query alias support were added.