TenantAtlas/specs/320-workspace-owned-analysis-surface-registration-shell-cutover/plan.md
ahmido ec9649897a feat: cut over workspace-owned analysis shell context (#375)
## Summary
- cut over workspace-owned analysis and library surfaces to workspace shell ownership instead of inheriting remembered environment shell context
- update the affected findings pages, scope resolution, navigation helpers, and related Blade views to keep environment focus explicit instead of implicit
- add and update Spec 320 artifacts plus focused regression coverage for findings navigation context, workspace hub registration, and admin surface scope behavior

## Guardrails
- Filament remains on v5 with Livewire v4 compliance unchanged
- provider registration remains in apps/platform/bootstrap/providers.php
- no new globally searchable resources were introduced or changed
- no new destructive actions were introduced or changed
- no Filament assets were added or changed, so the deploy requirement for filament:assets is unchanged

## Testing
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php tests/Feature/Findings/FindingsIntakeQueueNavigationContextTest.php tests/Feature/Findings/FindingsIntakeQueueTest.php tests/Feature/Findings/MyFindingsInboxNavigationContextTest.php tests/Feature/Findings/MyWorkInboxTest.php tests/Feature/Navigation/WorkspaceHubRegistryTest.php tests/Unit/Support/OperateHub/OperateHubShellResolutionTest.php tests/Unit/Tenants/AdminSurfaceScopeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #375
2026-05-16 23:16:53 +00:00

18 KiB

Implementation Plan: Workspace-Owned Analysis Surface Registration & Shell Cutover

Branch: 320-workspace-owned-analysis-surface-registration-shell-cutover | Date: 2026-05-16 | Spec: spec.md Input: Feature specification from /specs/320-workspace-owned-analysis-surface-registration-shell-cutover/spec.md

Preparation status: Specification artifacts only. No runtime implementation has been performed by this preparation step.

Summary

Spec 320 hard-cuts workspace-owned analysis/library pages away from remembered Environment shell inheritance:

Workspace-owned analysis surface
-> clean workspace route
-> Workspace shell only
-> no active Environment shell
-> no remembered Environment fallback
-> optional Environment filter only through canonical environment_id + visible chip

The implementation must classify the audited workspace-owned analysis surfaces from Spec 318, especially Baselines/Baseline Profiles, Baseline Snapshots, Baseline Compare Matrix, My Findings, Findings Intake, Findings Hygiene, and Cross-environment Compare. Baseline Compare remains Environment-owned from Spec 319. Alerts/Audit Log filter decisions remain Spec 321.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12.52.0 Primary Dependencies: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, Laravel Sail Storage: PostgreSQL; no schema changes planned Testing: Pest 4 / PHPUnit 12, Filament/Livewire tests, focused browser smoke Validation Lanes: fast-feedback, confidence, browser Target Platform: apps/platform Laravel/Filament admin panel, local Sail, staging/production through Dokploy Project Type: Web application Performance Goals: No material performance change. Classification and shell resolution must remain cheap request-time logic. Constraints: No migrations, seeders, packages, env vars, queues, scheduler, storage, deployment assets, compatibility routes, redirects, or legacy query alias support. Scale/Scope: Focused shell/context classification for workspace-owned analysis surfaces plus targeted regressions for Specs 314-319.

UI / Surface Guardrail Plan

  • Guardrail scope: route/shell/query/copy/navigation behavior for existing operator-facing workspace-owned analysis pages.
  • Native vs custom classification summary: Existing Filament Resources/Pages and Blade views. No styling redesign.
  • Shared-family relevance: navigation, shell context, breadcrumbs, filter chips, clear actions, OperationRun links.
  • State layers in scope: shell, page, record/detail, URL query, Filament table filter state, Livewire referer classification.
  • Audience modes in scope: operator-MSP and support-platform.
  • Decision/diagnostic/raw hierarchy plan: Workspace ownership must be default-visible; Environment context may appear as data/filter state only.
  • Raw/support gating plan: no raw/support evidence exposure change.
  • One-primary-action / duplicate-truth control: The shell is the single ownership signal; page filters/selectors do not become shell ownership.
  • Handling modes by drift class or surface: hard-stop for remembered Environment shell on in-scope clean URLs; review-mandatory for any newly discovered workspace analysis route.
  • Repository-signal treatment: Spec 318 M2/M4 are implementation inputs; pages outside those findings are inspect-only unless repo evidence proves same mismatch.
  • Special surface test profiles: global-context-shell.
  • Required tests or manual smoke: classifier tests, URL/query tests, Livewire/Feature render tests, browser smoke for workspace origin, Environment origin, reload, and back/forward.
  • Exception path and spread control: A distinct workspace-owned analysis classifier is allowed only if WorkspaceHubRegistry would overstate hub/filter behavior. Document the choice in implementation close-out.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes.
  • Systems touched: AdminSurfaceScope, WorkspaceHubRegistry, WorkspaceSidebarNavigation, WorkspaceHubEnvironmentFilter, WorkspaceHubFilterStateResetter, WorkspaceScopedEnvironmentRoutes, ManagedEnvironmentLinks, OperateHubShell, baseline resources/pages, findings analysis pages, cross-environment compare page, tests, browser smoke artifacts.
  • Shared abstractions reused: existing workspace hub shell contract, AdminSurfaceScope, WorkspaceHubRegistry query cleaning, WorkspaceHubEnvironmentFilter, CanonicalAdminEnvironmentFilterState, and current route/link helpers.
  • New abstraction introduced? why?: none preferred. If necessary, add the narrowest possible AdminSurfaceScope classification for workspace-owned analysis surfaces to force environmentless shell without implying full workspace-hub behavior.
  • Why the existing abstraction was sufficient or insufficient: WorkspaceHubRegistry works for registered hubs; generic WorkspaceScoped is insufficient because it allows remembered Environment restore.
  • Bounded deviation / spread control: Do not introduce a general surface taxonomy beyond the audited route list. Do not register pages as hubs unless they truly satisfy hub/filter/clear behavior.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes, as regression only for existing baseline capture/compare actions.
  • Central contract reused: OperationUxPresenter, OpsUxBrowserEvents, OperationRunLinks, current services/jobs.
  • Delegated UX behaviors: existing queued toast, run link, browser event, authorization, and audit behavior remain unchanged.
  • Surface-owned behavior kept local: existing initiation inputs/actions on Baseline Profile and Baseline Compare Matrix.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: Existing central lifecycle only.
  • Exception path: none.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes.
  • Provider-owned seams: Microsoft/Intune baseline content, provider IDs, Graph-backed snapshot evidence, compare strategy internals.
  • Platform-core seams: Workspace/Environment route ownership, shell classification, query key semantics, navigation ownership language.
  • Neutral platform terms / contracts preserved: Workspace, Environment, workspace-owned analysis surface, workspace hub, filtered workspace hub, Environment-owned page.
  • Retained provider-specific semantics and why: Baseline content remains Microsoft/Intune-shaped because it is current provider implementation truth.
  • Bounded extraction or follow-up path: Spec 321 and Spec 322 remain follow-ups; no provider abstraction work here.

Constitution Check

GATE: Must pass before implementation. Re-check after runtime changes.

  • Inventory-first: no inventory/snapshot truth change. Baseline snapshots remain immutable evidence/artifacts.
  • Read/write separation: no new write behavior. Existing capture/compare/preflight actions keep confirmation, authorization, audit, and OperationRun semantics.
  • Graph contract path: no new Graph calls; page render must remain DB-only.
  • Deterministic capabilities: existing capability checks remain; route/shell classification must be testable.
  • RBAC-UX: non-member / not entitled Workspace or Environment access remains deny-as-not-found where applicable; member missing capability follows existing behavior.
  • Workspace isolation: current Workspace remains the primary shell and authorization boundary.
  • Tenant/Environment isolation: Environment-owned rows remain scoped by accessible environments; optional filters must resolve only inside current Workspace and entitlement.
  • Run observability: existing baseline operation runs remain observable; no new operation type.
  • Test governance: lane purpose, heavy/browser visibility, fixture cost, and reviewer handoff are explicit.
  • Proportionality: possible classifier addition is justified by current browser-proven shell mismatch and bounded route list.
  • No premature abstraction: prefer extending existing classifier/registry paths over a new framework.
  • Persisted truth: no tables/entities/artifacts added.
  • Behavioral state: no new business state/status/reason family.
  • UI semantics: no new badge/status taxonomy; direct shell/page/filter truth only.
  • Shared pattern first: reuse workspace hub and shell resolution contracts.
  • Provider boundary: no provider tenant ID alias or fallback becomes platform shell truth.
  • V1 explicitness / few layers: hard cutover, no compatibility layer.
  • Filament-native UI: no ad-hoc styling or published internals.
  • Filament v5 / Livewire v4: Livewire 4.1.4 satisfies Filament v5 requirement; no Livewire v3 APIs.
  • Provider registration: Laravel 12 panel providers remain in apps/platform/bootstrap/providers.php; no provider registration work planned.
  • Global search: no global search behavior should change. Baseline Profile and Baseline Snapshot global search remain disabled unless implementation explicitly verifies a safe View/Edit route and updates tests.
  • Destructive/high-impact actions: no new destructive action. Existing archive/capture/compare/preflight actions must keep ->action(...), confirmation where required, authorization, audit, notifications, and tests.
  • Asset strategy: no Filament assets planned; no new filament:assets deployment requirement.

Test Governance Check

  • Test purpose / classification by changed surface: Unit for classifier/registry; Feature/Livewire for shell/access/filter behavior; Browser for integrated shell/sidebar/reload/history.
  • Affected validation lanes: fast-feedback, confidence, browser.
  • Why this lane mix is the narrowest sufficient proof: The defect is both classification logic and browser-visible shell drift.
  • Narrowest proving command(s):
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=AdminSurfaceScope
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=WorkspaceHubRegistry
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=WorkspaceOwnedAnalysis
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=BaselineCompareEnvironmentRouteContract
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=WorkspaceHubEnvironmentFilterContract
    • focused Spec 320 browser smoke.
  • Fixture / helper / factory / seed / context cost risks: workspace/environment/member plus small baseline/finding fixtures; keep any full browser fixture explicit and named.
  • Expensive defaults or shared helper growth introduced?: no. If a helper is needed, make expensive setup opt-in.
  • Heavy-family additions, promotions, or visibility changes: explicit browser smoke only; no broad discovery guard in this spec.
  • Surface-class relief / special coverage rule: global-context-shell.
  • Closing validation and reviewer handoff: prove clean URLs, filtered URLs, legacy aliases, remembered fallback rejection, Baseline Compare regression, Decision Register regression, and browser screenshots.
  • Budget / baseline / trend follow-up: none expected; document if browser smoke runtime grows materially.
  • Review-stop questions: Are any workspace-owned analysis URLs still generic WorkspaceScoped with remembered restore? Did any page get registered as a hub without supporting hub/filter/clear behavior? Did legacy aliases return?
  • Escalation path: document-in-feature.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
  • Why no dedicated follow-up spec is needed: This is the dedicated follow-up for Spec 318 M2/M4. Alerts/Audit and durable browser guard already have 321/322.

Project Structure

Documentation (this feature)

specs/320-workspace-owned-analysis-surface-registration-shell-cutover/
+-- spec.md
+-- plan.md
+-- tasks.md
+-- checklists/
    +-- requirements.md

Source Code (likely affected during later implementation)

apps/platform/app/
+-- Support/Navigation/
|   +-- AdminSurfaceScope.php
|   +-- WorkspaceHubRegistry.php
|   +-- WorkspaceSidebarNavigation.php
+-- Support/OperateHub/OperateHubShell.php
+-- Support/ManagedEnvironmentLinks.php
+-- Filament/Resources/
|   +-- BaselineProfileResource.php
|   +-- BaselineSnapshotResource.php
+-- Filament/Pages/
|   +-- BaselineCompareMatrix.php
|   +-- CrossEnvironmentComparePage.php
|   +-- Findings/
|       +-- MyFindingsInbox.php
|       +-- FindingsIntakeQueue.php
|       +-- FindingsHygieneReport.php
+-- Filament/Concerns/WorkspaceScopedEnvironmentRoutes.php

apps/platform/tests/
+-- Unit/Tenants/AdminSurfaceScopeTest.php
+-- Unit/Support/OperateHub/OperateHubShellResolutionTest.php
+-- Feature/Navigation/WorkspaceHubRegistryTest.php
+-- Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php
+-- Feature/Filament/
|   +-- BaselineCompareEnvironmentRouteContractTest.php
|   +-- BaselineProfile*.php
|   +-- BaselineSnapshot*.php
+-- Feature/Findings/
|   +-- MyFindingsInboxNavigationContextTest.php
|   +-- FindingsIntakeQueueNavigationContextTest.php
+-- Browser/
    +-- Spec320WorkspaceOwnedAnalysisSurfaceSmokeTest.php

Structure Decision: Use existing Laravel/Filament app structure. Do not create new base folders. Add test files only where the existing test families already live, or extend existing focused files when lower churn is clearer.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
Possible new AdminSurfaceScope value Generic WorkspaceScoped allows remembered Environment restore; workspace hubs already force environmentless shell but not every analysis page is a hub Blindly adding every page to WorkspaceHubRegistry could falsely imply hub/filter/clear behavior

Proportionality Review

  • Current operator problem: Workspace-owned pages can appear Environment-owned in the shell with no filter chip or route ownership.
  • Existing structure is insufficient because: WorkspaceScoped restores remembered Environment; WorkspaceHubRegistry is reserved for hub-like surfaces.
  • Narrowest correct implementation: Classify a route list or narrow scope category as workspace-owned analysis and make it force environmentless shell.
  • Ownership cost created: Focused classifier tests, URL/filter tests, browser smoke, and implementation close-out documentation.
  • Alternative intentionally rejected: Keep generic fallback, add legacy aliases, or add all pages to workspace hub registry regardless of actual hub behavior.
  • Release truth: Current-release cleanup before production.

Implementation Phases

Phase 0 - Repo Verification

Re-read Spec 318 artifacts and current code paths. Confirm the final in-scope list before runtime edits:

  • Baselines/Baseline Profiles.
  • Baseline Profile view/edit/create if applicable.
  • Baseline Compare Matrix.
  • Baseline Snapshots.
  • My Findings, Findings Intake, Findings Hygiene.
  • Cross-environment Compare.
  • Any other Spec 318 unregistered workspace analysis surface still present in routes/navigation.

Phase 1 - Tests First

Add focused tests that fail on current remembered Environment inheritance:

  • AdminSurfaceScope classification for in-scope paths.
  • Shell resolution with remembered Environment present.
  • Clean URL opens without active Environment.
  • Legacy alias rejection.
  • Optional environment_id filter behavior where supported.
  • Baseline Compare and Decision Register regressions.

Phase 2 - Classification / Registry Cutover

Implement the narrowest classifier mechanism:

  • Prefer existing registry/classifier extensions.
  • Add a distinct workspace-owned analysis surface classification only if needed.
  • Ensure forcesEnvironmentlessShellContext() returns true for these paths.
  • Ensure allowsRememberedEnvironmentRestore() is false for these paths.
  • Preserve Workspace state and authorization.

Update only in-scope surfaces:

  • Sidebar/global/workspace links emit clean workspace URLs unless explicit environment_id filter is supported.
  • Environment-origin links do not carry active Environment shell ownership.
  • Headers, breadcrumbs, empty states, and copy use workspace/library/work-queue wording.
  • Existing Environment columns, selectors, badges, and filters remain data/filter state.

Phase 4 - Regression and Browser Proof

Run focused tests and browser smoke:

  • Baselines workspace origin, environment origin, reload.
  • Baseline Snapshots workspace origin, environment origin, reload.
  • Baseline Compare Matrix direct/reload/back-forward.
  • My Findings/Intake/Hygiene and Cross-environment Compare direct/from Environment context.
  • Baseline Compare Environment-owned regression.
  • Decision Register workspace hub/filtered hub regression.

Save screenshots under:

specs/320-workspace-owned-analysis-surface-registration-shell-cutover/artifacts/screenshots/

Phase 5 - Close-Out

Document:

  • classification outcomes for Baselines/Baseline Snapshots.
  • unregistered workspace analysis pages fixed or excluded.
  • whether any page was reclassified Environment-owned.
  • how remembered Environment inheritance was prevented.
  • tests and browser verification.
  • no migrations/packages/env vars/queues/scheduler/storage/assets.
  • no backwards compatibility or legacy alias support.

Rollout Considerations

  • No database migration or data backfill.
  • No production compatibility burden because pre-production hard cutover is the standing policy.
  • No Dokploy runtime change.
  • No new filament:assets deployment step.
  • Staging validation should run focused tests and browser smoke before promotion.

Risk Controls

  • Keep route list explicit and tested.
  • Do not generalize classifier beyond audited need.
  • Do not add Environment filter feature work unless a page already has product need and visible chip/clear behavior can be proven.
  • Replace old tests that assert broken remembered fallback; do not keep them as compatibility coverage.
  • Keep Spec 321 and Spec 322 out of scope.