TenantAtlas/specs/314-workspace-hub-navigation-context-contract/spec.md
ahmido d85ef4cc1c Spec 314: enforce workspace hub navigation context contract (#369)
## Summary
- add a shared workspace hub registry for canonical workspace-scoped navigation entry
- keep sidebar and global workspace hub URLs free of inherited environment query and filter state
- add focused feature and browser coverage for workspace hub shell and data-scope contracts

## Validation
- 54 focused feature tests passed (205 assertions)
- 1 browser smoke test passed (361 assertions)
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `git diff --check`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #369
2026-05-16 09:54:29 +00:00

37 KiB

Feature Specification: Workspace Hub Navigation Context Contract

Feature Branch: 314-workspace-hub-navigation-context-contract Created: 2026-05-16 Status: Draft Input: User-supplied Spec 314 draft plus Spec 313 audit results. Runtime posture: Hard cutover. No backwards compatibility layer. No legacy query alias support for sidebar/global workspace hub entry.

Spec Candidate Check (mandatory - SPEC-GATE-001)

  • Problem: Workspace-scoped admin hubs can inherit stale Managed Environment context from shell state, remembered environment state, query params, Filament tenant state, Livewire table state, and persisted filters.
  • Today's failure: Spec 313 browser evidence shows operators can see "No environment selected" or "All environments" while rows remain environment-filtered. Provider Connections, Finding Exceptions Queue, Customer Review Workspace, Operations, Review Register, Governance Inbox, and Decision Register are the highest-risk surfaces.
  • User-visible improvement: Sidebar/global navigation into workspace hubs becomes deterministic: selected Workspace remains active, active Managed Environment context is cleared, URLs are clean, and rows are workspace-wide by default.
  • Smallest enterprise-capable version: One canonical workspace hub contract used by sidebar/global navigation and the affected workspace hub pages to strip environment query state and neutralize environment-like persisted filters on workspace hub entry.
  • Explicit non-goals: No Environment Dashboard CTA contract, no universal clear-filter contract, no product IA redesign, no route alias compatibility, no data migration, no seed/backfill work, no broad environment-page conversion.
  • Permanent complexity imported: A narrow workspace hub registry/contract and focused Pest/Livewire/Browser coverage. No new persisted tables, models, enums, status families, OperationRun types, or asset bundles.
  • Why now: Spec 313 completed browser verification and explicitly recommends Spec 314 first because sidebar/global workspace hub entry must be safe before Environment CTA filters and clear-filter semantics are standardized.
  • Why not local: Page-by-page URL fixes would keep context ownership fragmented. The failure crosses navigation generation, shell resolution, query parameters, resource getUrl() overrides, and persisted Filament table filters.
  • Approval class: Core Enterprise.
  • Red flags triggered: New registry abstraction; provider-adjacent Provider Connections scope; broad surface count. Defense: the abstraction is narrow, current-release, and required for workspace isolation and navigation safety across more than two concrete surfaces.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
  • Decision: approve.

Spec Scope Fields (mandatory)

  • Scope: canonical-view.
  • Primary routes:
    • /admin
    • /admin/workspaces/{workspace}/overview
    • /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
    • /admin/workspaces/{workspace}/environments
  • Data ownership: No ownership model changes. Workspace-owned and tenant-owned records keep existing ownership. Workspace hub views must enforce workspace membership and managed-environment entitlement before revealing tenant-owned rows.
  • RBAC: Workspace membership remains required. Existing capability checks remain in force. Non-member workspace/environment access remains deny-as-not-found. Member-but-missing-capability remains 403 where the current policy/capability contract uses 403.

For canonical-view specs:

  • Default filter behavior when tenant-context is active: Sidebar/global workspace hub entry ignores active or remembered Managed Environment context and opens workspace-wide. Explicit Environment CTA filtering remains allowed only where already present and is standardized later in Spec 315.
  • Explicit entitlement checks preventing cross-tenant leakage: Workspace-wide data queries must include current workspace scope and must limit environment-bound rows to the Managed Environments the actor is entitled to access.

Summary

Implement the canonical Workspace Hub Navigation Context Contract for TenantPilot.

Workspace-scoped hubs must open workspace-wide when reached through sidebar/global navigation. They must not inherit Managed Environment context through route/query params, Filament tenant state, remembered environment state, Livewire mounted state, persisted Filament table filters, or page-specific URL builders.

Canonical behavior:

Sidebar / global navigation -> workspace-scoped hub -> workspace-wide state

Environment-specific filtering from Environment Dashboard CTAs is not productized in this spec. It belongs to Spec 315.

Product Context

TenantPilot is workspace-first. Workspace is the primary operating context. Managed Environment is a secondary operational context inside a Workspace.

Workspace hubs are portfolio/workspace surfaces. They may display tenant-owned rows, but their entry point is workspace-wide and entitlement-filtered, not environment-owned.

Environment pages remain environment-owned and are not converted by this spec.

Cross-Cutting / Shared Pattern Reuse (mandatory)

  • Cross-cutting feature?: yes.
  • Interaction class(es): navigation, shell/context state, table filter state, canonical links.
  • Systems touched: WorkspaceSidebarNavigation, AdminPanelProvider, TenantPageCategory, NavigationScope, OperateHubShell, WorkspaceContext, CanonicalAdminTenantFilterState, page/resource URL builders, and high-risk Filament pages/resources from Spec 313.
  • Existing pattern(s) to extend: existing workspace navigation builder, TenantPageCategory::WorkspaceWideSurface, NavigationScope, WorkspaceContext, and CanonicalAdminTenantFilterState.
  • Shared contract / presenter / builder / renderer to reuse: reuse existing navigation and shell/context helpers where safe; introduce one narrow WorkspaceHubRegistry only for workspace hub identity and environment-param/filter neutralization rules.
  • Why the existing shared path is sufficient or insufficient: existing paths know pieces of the contract but no single path answers whether a page is a workspace hub, whether environment params must be stripped, and whether environment-like persisted filters must be ignored on sidebar/global entry.
  • Allowed deviation and why: introduce a narrow registry because more than two concrete workspace hubs need the same decision and because isolation/navigation correctness is security-relevant current-release truth.
  • Consistency impact: all sidebar/global workspace hub URLs must use the same forbidden query-param list and the same remembered-environment bypass behavior.
  • Review focus: verify no page-specific getUrl() override or helper can inject environment params into sidebar/global workspace hub URLs.

OperationRun UX Impact (mandatory)

  • Touches OperationRun start/completion/link UX?: no OperationRun start, completion, queuing, dedupe, status, outcome, terminal notification, or run lifecycle semantics are changed.
  • Shared OperationRun UX contract/layer reused: OperationRunLinks::index() may be adjusted only for clean workspace hub navigation; OperationRun start UX is not in scope.
  • Delegated start/completion UX behaviors: N/A.
  • Local surface-owned behavior that remains: existing Operations list and operation detail behavior remain.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: N/A.
  • Exception required?: none.

Provider Boundary / Platform Core Check (mandatory)

  • Shared provider/platform boundary touched?: yes, Provider Connections and provider-adjacent links are in scope.
  • Boundary classification: mixed. Provider Connections records are provider-adjacent, but the navigation context contract is platform-core.
  • Seams affected: Provider Connection list URL generation, provider connection environment prefilter behavior, managed_environment_id query semantics, remembered environment fallback.
  • Neutral platform terms preserved or introduced: Workspace, Managed Environment, provider connection, workspace hub.
  • Provider-specific semantics retained and why: Microsoft-specific provider details remain inside existing provider connection records/actions. This spec must not introduce Microsoft-shaped platform navigation truth.
  • Why this does not deepen provider coupling accidentally: the contract removes hidden environment/provider-specific query inference from workspace hub navigation instead of adding a provider framework.
  • Follow-up path: Spec 315 standardizes explicit Environment CTA filtering; Spec 317 removes remaining legacy tenant/environment naming and alias drift.

UI / Surface Guardrail Impact (mandatory)

Surface / Change Operator-facing surface change? Native vs Custom Shared-Family Relevance State Layers Touched Exception Needed? Low-Impact / N/A Note
Workspace hub sidebar/global entry yes Native Filament navigation + existing shell navigation / shell / table filters shell, URL-query, page, session filters no State-contract hardening only; no redesign.
Provider Connections / Integrations yes Native Filament Resource navigation / provider connection list URL-query, table query, remembered env no Must open workspace-wide from sidebar/global entry.
Finding Exceptions Queue yes Native Filament Page navigation / queue URL-query, table filters, session filters no Sidebar/global entry must not use tenant.
Operations yes Native Filament Page monitoring state page URL-query, table filters, shell no Sidebar/global entry must not carry managed_environment_id.
Decision Register / Governance Inbox yes Native Filament Pages governance navigation URL-query, access check, filters no Clean workspace Decision Register URL must open for authorized users.
Customer Reviews / Reviews / Evidence yes Native Filament Pages reporting / evidence viewers URL-query, table filters, session filters no Sidebar/global entry must neutralize stale environment filters.

Decision-First Surface Role (mandatory when operator-facing surfaces are changed)

Surface Decision Role Human-in-the-loop Moment Immediately Visible for First Decision On-Demand Detail / Evidence Why This Is Primary or Why Not Workflow Alignment Attention-load Reduction
Workspace hub sidebar/global navigation Secondary Context Operator moves between workspace work areas Workspace selected, no environment selected, workspace-wide rows Existing page diagnostics Not a new decision surface; it ensures existing surfaces start from truthful scope Workspace-first navigation Removes hidden stale environment state from routine navigation.
Critical workspace hubs Existing role unchanged Existing per-page decisions remain Existing per-page content, now with correct default scope Existing page details Spec changes entry scope, not page purpose Workspace hubs remain workspace-wide Prevents operators from reconstructing hidden filters.

Audience-Aware Disclosure (mandatory when operator-facing surfaces are changed)

Surface Audience Modes In Scope Decision-First Default-Visible Content Operator Diagnostics Support / Raw Evidence One Dominant Next Action Hidden / Gated By Default Duplicate-Truth Prevention
Workspace hub entry state operator-MSP, support-platform Workspace selected; no environment selected; no hidden environment filter Existing filter controls and page diagnostics Existing support/raw areas unchanged Open selected workspace hub Raw query/table state is not surfaced as a product feature Shell and data scope must agree.

UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)

Surface Action Surface Class Surface Type Likely Next Operator Action Primary Inspect/Open Model Row Click Secondary Actions Placement Destructive Actions Placement Canonical Collection Route Canonical Detail Route Scope Signals Canonical Noun Critical Truth Visible by Default Exception Type / Justification
Workspace hub navigation contract Navigation / Context Workspace hub entry Open hub workspace-wide Existing page-defined model Existing behavior Existing page-defined placement Existing page-defined placement See registry table Existing page-defined routes Workspace active, Environment none Workspace hub No hidden environment filter from sidebar/global entry none

Operator Surface Contract (mandatory when operator-facing surfaces are changed)

Surface Primary Persona Decision / Operator Action Supported Surface Type Primary Operator Question Default-visible Information Diagnostics-only Information Status Dimensions Used Mutation Scope Primary Actions Dangerous Actions
Workspace hub entry state MSP operator Move from any page to a workspace hub without stale environment scope Navigation/context contract Which workspace context am I operating in? Current workspace, no selected environment, workspace-wide list state Existing page-specific diagnostics Scope only N/A Open hub None added or changed

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no persisted source of truth.
  • New persisted entity/table/artifact?: no.
  • New abstraction?: yes, a narrow workspace hub registry/contract.
  • New enum/state/reason family?: no.
  • New cross-domain UI framework/taxonomy?: no.
  • Current operator problem: sidebar/global navigation into workspace hubs can silently inherit stale environment context and show filtered rows under a workspace-wide shell.
  • Existing structure is insufficient because: page category, shell resolution, navigation builders, URL helpers, and table filter helpers each own partial state decisions; no single shared contract owns workspace hub identity and entry cleanup.
  • Narrowest correct implementation: one static/support registry listing workspace hub routes/pages and the environment-like query/filter keys to strip or ignore on sidebar/global entry.
  • Ownership cost: maintain hub membership when workspace hubs are added or reclassified; add contract tests that fail when a workspace hub URL leaks environment-like params.
  • Alternative intentionally rejected: page-by-page patches without a registry, because Spec 313 proves the same drift across Provider Connections, Operations, Finding Exceptions, Reviews, Evidence, Governance, Alerts, and Audit.
  • Release truth: current-release truth. Spec 313 browser evidence makes this a present safety issue, not future preparation.

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. Canonical replacement is preferred over preservation.

No legacy tenant, tenant_id, managed_environment_id, environment_id, tenant_scope, or tableFilters behavior is preserved for sidebar/global workspace hub entry.

Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)

  • Test purpose / classification: Feature, Filament/Livewire, and Browser.
  • Validation lane(s): confidence for focused Feature/Livewire tests; browser for critical user flows; git diff --check; focused route/navigation tests.
  • Why this classification and these lanes are sufficient: URL generation and shell/data scope can be proven with Feature and Livewire tests; browser verification is required because Spec 313 showed persisted Filament table state, reload, and back/forward behavior can drift after hydration.
  • New or expanded test families: bounded Spec 314 navigation context tests and one focused browser smoke. No broad suite rebaseline.
  • Fixture / helper cost impact: tests may need explicit workspace, two Managed Environments, memberships, and rows for the covered pages. Helpers must stay feature-local or opt-in.
  • Heavy-family visibility / justification: Browser coverage is explicit and limited to critical flows inherited from Spec 313.
  • Special surface test profile: global-context-shell + monitoring-state-page + exception-coded-surface.
  • Standard-native relief or required special coverage: no styling/layout verification; special state-contract coverage required.
  • Reviewer handoff: reviewers must confirm lane fit, no hidden heavy helper defaults, and no broad browser family beyond the named Spec 314 smoke.
  • Budget / baseline / trend impact: none expected; document if browser lane expands materially.
  • Escalation needed: document-in-feature.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=WorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=ProviderConnectionsWorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=FindingExceptionsQueueWorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=OperationsWorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=DecisionRegisterWorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=CustomerReviewWorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=EvidenceOverviewWorkspaceHub
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec314WorkspaceHubNavigationContextSmoke
    • git diff --check

User Scenarios & Testing (mandatory)

User Story 1 - Sidebar workspace hubs always open workspace-wide (Priority: P1)

As an MSP operator working inside an active Managed Environment, I can click a workspace-scoped hub in the sidebar/global navigation and land on a workspace-wide version of that hub without hidden environment filters.

Why this priority: This removes the most dangerous Spec 313 mismatch: shell says no environment selected while page data is still environment-filtered.

Independent Test: From an Environment Dashboard state with a remembered environment, generate/open each registry workspace hub sidebar URL and assert it has no forbidden environment query params and renders with no active environment shell context.

Acceptance Scenarios:

  1. Given a selected Workspace and remembered Managed Environment, When the operator opens Provider Connections through sidebar/global navigation, Then the URL is clean and provider connection rows are workspace-wide across entitled environments.
  2. Given a selected Workspace and active Environment Dashboard state, When the operator opens Finding Exceptions Queue, Operations, Decision Register, Customer Reviews, Reviews, Evidence, Governance Inbox, Audit Log, Alerts, Workspace Settings, or Manage Workspaces through sidebar/global navigation, Then no environment query params or environment-like table filters define the default scope.

User Story 2 - Remembered environment is not a workspace hub data boundary (Priority: P1)

As an MSP operator, my last used Managed Environment may still help the switcher, but it must not silently filter workspace hubs.

Why this priority: Spec 313 shows remembered environment state can leak into links and shell decisions.

Independent Test: Seed two environments in one workspace, remember Environment A, then open workspace hub URLs and assert Environment A is not used as a URL param, shell context, default table filter, or data query boundary.

Acceptance Scenarios:

  1. Given Environment A is remembered for a workspace, When sidebar/global Provider Connections URL is generated, Then it does not include managed_environment_id.
  2. Given Environment A is remembered and rows exist for Environment A and B, When a workspace hub opens from sidebar/global navigation, Then entitled rows are not filtered to Environment A.

User Story 3 - Persisted environment filters cannot override sidebar intent (Priority: P2)

As an operator returning to a workspace hub after previous filtering, sidebar/global entry must be workspace-wide even if a page persisted an environment-like table filter earlier.

Why this priority: Spec 313 found reload and back/forward behavior can revive stale filters.

Independent Test: Persist an environment table filter for Customer Reviews, Finding Exceptions Queue, Evidence, Provider Connections, and Operations where applicable; navigate away; then enter through sidebar/global clean URL and assert environment-like persisted filters are absent or ignored.

Acceptance Scenarios:

  1. Given Customer Reviews was filtered to Environment A, When the operator enters Customer Reviews through sidebar/global navigation, Then the page opens workspace-wide and reload remains workspace-wide.
  2. Given Evidence Overview or Finding Exceptions Queue had a persisted environment-like table filter, When the operator enters through workspace hub navigation, Then that filter does not define the default row scope.

User Story 4 - Decision Register clean workspace URL is a valid workspace hub entry (Priority: P2)

As an authorized workspace user, I can open Decision Register through its clean workspace URL without needing an environment filter.

Why this priority: Spec 313 found the clean Decision Register route returned 403 while a filtered URL opened.

Independent Test: Seed a workspace user with decision visibility and open /admin/governance/decisions without environment query params; assert it is not forbidden and does not require a Managed Environment query.

Acceptance Scenarios:

  1. Given an authorized workspace user with visible decision register access, When they open the clean Decision Register URL, Then the page opens without managed_environment_id.
  2. Given no open decisions exist but the user is authorized to the workspace register, When they open the clean Decision Register URL, Then the page shows a truthful empty workspace state rather than requiring an environment filter.

Edge Cases

  • A workspace hub direct URL is opened with forbidden query params. The page may still support explicit CTA filters until Spec 315, but sidebar/global navigation must not generate those params.
  • Browser back returns to an old filtered URL. This spec verifies sidebar/global re-entry and focused back/forward behavior; full universal clear-filter behavior belongs to Spec 316.
  • A page is actually environment-owned. It must not be put in the workspace hub registry; environment pages remain outside this spec.
  • A user lacks workspace membership. Existing deny-as-not-found behavior remains.
  • A user is a workspace member but lacks a capability needed for a hub. Existing capability semantics remain; this spec must not bypass authorization.

Requirements (mandatory)

Functional Requirements

  • FR-001: The implementation MUST create or formalize one canonical workspace hub registry/contract.
  • FR-002: The registry MUST identify whether a route/page is a workspace-scoped hub.
  • FR-003: The registry MUST identify whether sidebar/global navigation must clear active Managed Environment shell context for that hub.
  • FR-004: The registry MUST provide the forbidden sidebar/global query-param list: tenant, tenant_id, managed_environment_id, environment_id, tenant_scope, and tableFilters.
  • FR-005: The registry MUST provide the environment-like persisted filter keys to neutralize for workspace hub entry: tenant, tenant_id, managed_environment_id, environment_id, environment, and tenant_scope.
  • FR-006: Sidebar/global URLs for every registry workspace hub MUST be clean and MUST NOT include forbidden environment query params.
  • FR-007: Sidebar/global workspace hub entry MUST clear or bypass active Managed Environment shell context while preserving selected Workspace context.
  • FR-008: Remembered Managed Environment state MUST NOT be used as sidebar URL input, workspace hub default data filter, workspace hub authorization boundary, shell context, or fallback route parameter.
  • FR-009: Workspace hubs MUST NOT use Filament::getTenant() or remembered environment as a hidden default data boundary on sidebar/global entry.
  • FR-010: Environment-like persisted Filament table filters MUST NOT override sidebar/global workspace hub intent.
  • FR-011: Provider Connections sidebar/global entry MUST be workspace-wide and MUST NOT inject managed_environment_id from remembered context.
  • FR-012: Finding Exceptions Queue sidebar/global entry MUST be workspace-wide and MUST NOT use tenant query for sidebar/global entry.
  • FR-013: Operations sidebar/global entry MUST be workspace-wide and MUST NOT carry managed_environment_id, tenant_scope, or tableFilters.
  • FR-014: Decision Register clean workspace URL MUST open for authorized workspace users and MUST NOT require an environment filter.
  • FR-015: Customer Reviews, Reviews, Evidence, Governance Inbox, Audit Log, Alerts, Workspace Settings, Manage Workspaces, and Workspace Overview MUST honor the workspace-wide sidebar/global entry contract.
  • FR-016: Existing Environment Dashboard CTAs may keep explicit environment filters only where already present; this spec MUST NOT standardize CTA query naming or visible filter chips.
  • FR-017: Environment-owned pages MUST remain environment-owned and MUST NOT be forced workspace-wide by the registry.
  • FR-018: No legacy compatibility layer, alias adapter, dual query mapping, migration shim, backfill, or seeder change may be introduced for this contract.

Workspace Hub Registry Contents

Registry entry Route/page identity Status in Spec 314
Workspace Overview /admin, /admin/workspaces/{workspace}/overview include
Operations /admin/workspaces/{workspace}/operations include
Provider Connections / Integrations /admin/provider-connections include
Finding Exceptions Queue /admin/finding-exceptions/queue include
Evidence Overview /admin/evidence/overview include
Review Register /admin/reviews include
Customer Review Workspace /admin/reviews/workspace include
Governance Inbox /admin/governance/inbox include
Decision Register /admin/governance/decisions include
Audit Log /admin/audit-log include
Alerts landing /admin/alerts include
Alert Deliveries /admin/alerts/alert-deliveries include
Alert Rules /admin/alerts/alert-rules include
Alert Destinations /admin/alerts/alert-destinations include
Workspace Settings /admin/settings/workspace include
Manage Workspaces /admin/workspaces include
Managed Environments Landing /admin/workspaces/{workspace}/environments include as workspace environment catalog, not environment-owned dashboard
Stored Reports /admin/workspaces/{workspace}/environments/{environment}/stored-reports exclude; Spec 313 found no workspace-wide reports hub
Support Request action modal/action only exclude; no workspace-owned list route discovered in Spec 313
Environment Dashboard and child routes /admin/workspaces/{workspace}/environments/{environment}... exclude; environment-owned

Non-Functional Requirements

  • NFR-001: The implementation MUST preserve workspace isolation and managed-environment entitlement checks for every workspace-wide query.
  • NFR-002: The implementation MUST not introduce Graph calls, queued work, remote calls, or OperationRun lifecycle changes.
  • NFR-003: The implementation MUST use Laravel 12, Filament 5.2.1, Livewire 4.1.4, and Pest 4 conventions.
  • NFR-004: The implementation MUST prefer direct replacement over legacy compatibility, consistent with LEAN-001.
  • NFR-005: Browser verification MUST cover the critical Spec 313 flows after runtime changes.
  • NFR-006: Tests MUST stay focused and must not rebaseline broad navigation or browser suites.

RBAC / Security Requirements

  • SEC-001: Workspace non-members remain deny-as-not-found.
  • SEC-002: Missing capability remains forbidden after workspace membership is established where current policies use 403.
  • SEC-003: UI visibility must not replace server-side authorization.
  • SEC-004: Provider Connections credential-adjacent actions are not changed, weakened, or newly exposed.
  • SEC-005: Workspace-wide pages must never reveal tenant-owned rows from environments outside the actor's entitlement.

Auditability / Observability Requirements

  • AUD-001: No new audit events are required because this spec changes read/navigation context only.
  • AUD-002: Existing audit behavior for mutating actions must remain unchanged.
  • AUD-003: Implementation close-out must record exact tests, browser verification, and any remaining follow-up for Specs 315/316/317.

Data / Truth Requirements

  • DATA-001: No migrations, seeders, data backfills, or persisted compatibility fields are in scope.
  • DATA-002: The registry is code truth for workspace hub identity, not database truth.
  • DATA-003: Environment-like persisted filter state is UI/session state only; it must not become a domain model.

Out of Scope

  • Environment CTA explicit filter contract.
  • Universal clear-filter behavior.
  • Standardizing filter chips or visible scope chips.
  • Route alias compatibility.
  • Legacy tenant/tenant_id cleanup outside sidebar/global workspace hub entry.
  • Reclassifying all ambiguous pages.
  • Product IA redesign.
  • Application data migration, seed data, or backfill work.
  • New provider abstraction, provider registry, or multi-provider framework.
  • New destructive actions or mutating workflows.

Acceptance Criteria

Workspace Hub Registry

  • There is one canonical workspace hub registry/contract.
  • All workspace hubs from Spec 313 are represented or explicitly excluded with reason.
  • Registry distinguishes workspace hubs from environment-scoped pages.
  • Registry is used by sidebar/global navigation or the equivalent central contract.

Sidebar URL Contract

  • Workspace hub sidebar/global URLs contain no tenant.
  • Workspace hub sidebar/global URLs contain no tenant_id.
  • Workspace hub sidebar/global URLs contain no managed_environment_id.
  • Workspace hub sidebar/global URLs contain no environment_id.
  • Workspace hub sidebar/global URLs contain no tenant_scope.
  • Workspace hub sidebar/global URLs contain no tableFilters.
  • Provider Connections no longer injects Environment query params from remembered context.
  • Finding Exceptions Queue no longer uses tenant query for sidebar/global entry.

Shell / Data Scope Contract

  • Sidebar/global entry into workspace hubs clears active shell Managed Environment context.
  • Selected Workspace remains active.
  • Workspace hubs open workspace-wide by default.
  • Shell and data scope do not diverge on critical pages.
  • Remembered Environment is not used as workspace hub data scope.
  • Filament::getTenant() is not used as a hidden workspace hub default filter source.

Persisted Filter Safety

  • Environment-like persisted table filters do not override sidebar/global workspace hub intent.
  • Customer Reviews sidebar/global entry does not restore stale Environment filter.
  • Finding Exceptions Queue sidebar/global entry does not restore stale Environment filter.
  • Evidence sidebar/global entry does not restore stale Environment filter.
  • Provider Connections sidebar/global entry does not restore stale Environment filter.

Critical Page Fixes

  • Provider Connections workspace hub sidebar/global entry is workspace-wide.
  • Finding Exceptions Queue workspace hub sidebar/global entry is workspace-wide.
  • Operations sidebar/global entry is workspace-wide and does not carry managed_environment_id.
  • Decision Register clean workspace URL opens for authorized workspace users.
  • Customer Reviews sidebar/global entry no longer reload-restores stale Environment filter.
  • Evidence sidebar/global entry no longer silently uses stale Environment filter.

Tests

  • Required tests added.
  • Existing relevant tests updated only if they asserted old broken behavior.
  • No broad test rebaseline.
  • Tests prove sidebar/global navigation contract.
  • Tests prove remembered Environment does not affect workspace hub sidebar/global URLs.
  • Tests prove persisted Environment filters do not override sidebar/global intent.

Browser Verification

  • Focused browser verification performed for critical pages.
  • Screenshots saved for critical before/after flows where useful.
  • Reload behavior verified.
  • Back/forward behavior checked for high-risk pages.
  • Remaining mismatch documented as follow-up for Spec 315/316/317.

Filament v5 Output Contract

  1. Livewire v4.0+ compliance: The app uses Livewire 4.1.4 with Filament 5.2.1. Implementation must not introduce Livewire v3 references or APIs.
  2. Provider registration location: Admin panel provider remains registered through apps/platform/bootstrap/providers.php; do not register providers in bootstrap/app.php.
  3. Global search: Workspace hub registry work must not enable global search. Changed resources must keep existing global-search posture; Provider Connections currently disables global search.
  4. Destructive actions: No destructive actions are added or changed. Any existing destructive action must retain ->action(...), ->requiresConfirmation(), server-side authorization, audit logging, and tests.
  5. Asset strategy: No new assets are expected. If implementation unexpectedly registers Filament assets, deployment must include cd apps/platform && php artisan filament:assets.
  6. Testing plan: Feature/Livewire tests for URL/shell/data scope; focused browser smoke for critical flows; no broad UI restyling tests.

Risks

  • Decision Register currently has data-dependent access behavior; the implementation must make clean workspace URL behavior truthful without hiding real authorization failures.
  • Persisted Filament filters may have page-specific session keys; implementation must avoid fragile one-off clearing where a shared helper can express the contract.
  • Provider Connections currently uses managed_environment_id as external id/slug in some paths and database id elsewhere; sidebar/global entry must not preserve this ambiguity.
  • Existing Environment CTA links may still pass explicit filters; implementation must not accidentally remove all CTA filtering before Spec 315.
  • Browser back/forward may revive old filtered URLs; this spec covers critical re-entry and high-risk flows, while full clear-filter semantics belong to Spec 316.

Assumptions

  • Spec 313 is completed audit context and is the source of truth for page inventory and critical findings.
  • Specs 311 and 312 are completed historical dependencies and must not be rewritten.
  • There is no production data or production environment to preserve.
  • Workspace remains primary context; Managed Environment remains secondary context.
  • Provider Connections is workspace/provider-level for sidebar/global entry.
  • Decision Register is a workspace hub and clean workspace URL behavior is required.

Follow-Up Spec Candidates

  • 315 - Environment CTA Explicit Filter Contract: canonical environment filter query key, identifier type, visible scope chips, CTA behavior, and distinction from sidebar/global entry.
  • 316 - Workspace Hub Clear Filter Contract: clear visible chip, query params, Livewire properties, Filament table filters, deferred filters, persisted/session state, reload safety.
  • 317 - Legacy Tenant / Environment Context Cleanup: old tenant aliases, hidden Filament::getTenant() workspace hub usage, remembered environment as data boundary, stale tenant naming.
  • 318 - Browser Regression Coverage / No-Drift Guard: durable browser/regression guard coverage for this context contract.

Required Final Report

When implementation completes, report:

Spec 314 completed.

Changed behavior:
...

Files changed:
...

Workspace hub registry contents:
...

Tests:
- command:
- result:

Browser verification:
...

Remaining follow-ups:
- 315:
- 316:
- 317:

Runtime files were changed: yes/no.
No migrations were created.
No seeders were changed.
No backwards compatibility layer was introduced.
No legacy query alias support was preserved for workspace hub sidebar/global entry.