## 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
288 lines
18 KiB
Markdown
288 lines
18 KiB
Markdown
# 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](/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/320-workspace-owned-analysis-surface-registration-shell-cutover/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:
|
|
|
|
```text
|
|
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)
|
|
|
|
```text
|
|
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)
|
|
|
|
```text
|
|
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.
|
|
|
|
### Phase 3 - Page / Link / Copy Alignment
|
|
|
|
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:
|
|
|
|
```text
|
|
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.
|