# 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.