TenantAtlas/specs/322-browser-no-drift-regression-guard/spec.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

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_id query 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: tenant remains 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/Navigation or 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...SmokeTest and 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:

  1. Given an active remembered Environment, when Operations opens through its clean workspace URL, then no Environment query parameter, shell, or chip is present.
  2. 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:

  1. 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.
  2. 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:

  1. Given back returns to a URL containing environment_id, then the chip exists and shell remains Workspace-only.
  2. 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:

  1. Given Baseline Compare opens from Environment Dashboard, then its URL contains the Environment route segment and no workspace-hub environment_id query model.
  2. 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:

  1. Given Baseline Profiles opens from Environment Dashboard, then shell is Workspace-only and no Environment chip appears.
  2. 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:

  1. Given tenant, tenant_id, managed_environment_id, environment, tenant_scope, or tableFilters are present on a workspace hub URL, then no Environment filter state appears.
  2. Given /admin/t/... is requested, then it is not an active route and no Tenant panel provider is registered.

Edge Cases

  • Cross-workspace environment_id is 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_id and 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, and tableFilters.
  • FR-011: No active /admin/t route and no active TenantPanelProvider may 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-testid hooks 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 Spec322 prefixes.
  • 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.md exists 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 --check passes.
  • 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.