## Summary - cut over the admin runtime to the workspace-first environment and operations routes from spec 280 - retarget governance artifact resources, related navigation, and operation drillthroughs to the surviving admin panel contract from spec 282 - add focused feature and browser coverage plus spec close-out updates for the shipped 280/282 slice ## Validation - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/WorkspaceFoundation tests/Feature/Workspaces tests/Feature/ManagedEnvironment tests/Feature/RequiredPermissions tests/Feature/Operations tests/Feature/MonitoringOperationsTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec280WorkspaceTenancyEnvironmentRoutingSmokeTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactAdminPanelRegistrationTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactEnvironmentContextTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactDeepLinkContractTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactLegacyTenantPanelGuardTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec282GovernanceArtifactRetargetingSmokeTest.php` ## Notes - provider registration remains in `apps/platform/bootstrap/providers.php` - Filament stays on v5 with Livewire v4 semantics - touched searchable governance surfaces remain truthful or disabled in the same slice Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #341
272 lines
22 KiB
Markdown
272 lines
22 KiB
Markdown
# Implementation Plan: Governance Artifact Retargeting to ManagedEnvironment
|
|
|
|
**Branch**: `282-governance-artifact-retargeting` | **Date**: 2026-05-07 | **Spec**: [spec.md](./spec.md)
|
|
**Input**: Feature specification from `specs/282-governance-artifact-retargeting/spec.md`
|
|
|
|
## Summary
|
|
|
|
Prepare the third reserved managed-environment cutover slice by moving the existing governance artifact surface families onto the workspace-first admin runtime. The narrow implementation path reuses the existing artifact models, Filament resources, artifact presenters, `ResolvesPanelTenantContext`, `InteractsWithTenantOwnedRecords`, `OperateHubShell`, `RelatedNavigationResolver`, `CanonicalNavigationContext`, `OperationRunLinks`, and the workspace-first route shell prepared by Spec `280`, while explicitly deferring lifecycle, stored-report productization, provider-capability, taxonomy, RBAC, copy, and quality-gate follow-through to Specs `267`, `277`, and `283` through `287`.
|
|
|
|
This plan is intentionally bounded. Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, no schema or persistence change is introduced, no artifact naming or lifecycle rewrite is introduced, and no compatibility panel or route fallback is allowed.
|
|
|
|
This package is not independently executable on current repo truth. Implementation is blocked until the workspace-first environment route shell from Spec `280` is already merged or otherwise present on the implementation branch.
|
|
|
|
## Inherited Baseline / Explicit Delta
|
|
|
|
### Inherited baseline
|
|
|
|
- Spec `279` already moved the core governance artifact models onto `managed_environment_id` plus `workspace_id`, and many models now derive `workspace_id` through `DerivesWorkspaceIdFromTenant` or equivalent seams.
|
|
- Spec `280` already defines the workspace-first environment route shell and surviving admin-panel ownership as the adjacent cutover baseline, and `282` is only executable once that shell is already present on the implementation branch.
|
|
- Spec `281` already prepares the provider-boundary extraction so `282` can treat provider seams as adjacent context, not new scope.
|
|
- Current repo truth still shows tenant-panel registration or admin-hidden behavior on several governance artifact resources through `shouldRegisterNavigation()` checks against `Filament::getCurrentPanel()?->getId() === 'admin'`.
|
|
- Current repo truth also shows environment resolution and authorization on read-only artifact resources such as `ReviewPackResource`, `EvidenceSnapshotResource`, and `StoredReportResource` still relying on `ManagedEnvironment::current()` or mixed fallback chains that assume the tenant panel remains active.
|
|
- `OperationRunLinks` already owns the canonical operations link language; `282` only needs artifact surfaces to reuse that contract.
|
|
- Existing prepared packages already cover adjacent lifecycle and artifact productization gaps: Spec `267` for artifact lifecycle and Spec `277` for stored reports.
|
|
|
|
### Explicit delta in this plan
|
|
|
|
- Register the touched governance artifact resource families on the workspace-first admin runtime instead of hiding them from the admin panel or depending on the tenant panel.
|
|
- Align collection and detail route ownership for those resource families to `/admin/workspaces/{workspace}/environments/{environment}/...`.
|
|
- Align environment-context resolution for those resources and their related pages so the admin panel can resolve the current managed environment without the tenant panel.
|
|
- Retarget related navigation, record URLs, and operation drillthroughs emitted by the touched artifact surfaces to the workspace-first environment and operations contracts.
|
|
- Preserve each resource's existing action hierarchy, read-only or mutation semantics, capability model, and artifact presenters.
|
|
- Explicitly defer lifecycle semantics, stored-report surface expansion, provider-capability or taxonomy work, RBAC redesign, copy-neutralization, and broader no-legacy enforcement.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4.15, Laravel 12.52
|
|
**Primary Dependencies**: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, existing Filament resources and shared navigation/context helpers
|
|
**Storage**: PostgreSQL, no new persistence or schema change
|
|
**Testing**: Pest feature tests, one Pest browser smoke, focused legacy-panel guard coverage
|
|
**Validation Lanes**: fast-feedback, confidence, browser
|
|
**Target Platform**: Laravel monolith in `apps/platform`
|
|
**Project Type**: web application
|
|
**Performance Goals**: preserve current resource responsiveness and viewer behavior while changing only panel registration, route ownership, environment resolution, and deep links
|
|
**Constraints**: no schema migration, no compatibility routes, no dual-panel ownership, no naming or lifecycle rewrite, no RBAC redesign, provider registration remains in `apps/platform/bootstrap/providers.php`, and Filament remains v5 on Livewire v4
|
|
**Scale/Scope**: one route and registration contract over the existing environment-owned governance artifact resource families plus their related drillthrough links
|
|
|
|
## Likely Affected Repo Surfaces
|
|
|
|
- `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php`
|
|
- `apps/platform/app/Filament/Concerns/InteractsWithTenantOwnedRecords.php`
|
|
- `apps/platform/app/Filament/Resources/InventoryItemResource.php`
|
|
- `apps/platform/app/Filament/Resources/PolicyResource.php`
|
|
- `apps/platform/app/Filament/Resources/PolicyVersionResource.php`
|
|
- `apps/platform/app/Filament/Resources/BackupScheduleResource.php`
|
|
- `apps/platform/app/Filament/Resources/BackupSetResource.php`
|
|
- `apps/platform/app/Filament/Resources/RestoreRunResource.php`
|
|
- `apps/platform/app/Filament/Resources/FindingResource.php`
|
|
- `apps/platform/app/Filament/Resources/FindingExceptionResource.php`
|
|
- `apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php`
|
|
- `apps/platform/app/Filament/Resources/TenantReviewResource.php`
|
|
- `apps/platform/app/Filament/Resources/ReviewPackResource.php`
|
|
- `apps/platform/app/Filament/Resources/StoredReportResource.php`
|
|
- `apps/platform/app/Support/Navigation/RelatedNavigationResolver.php`
|
|
- `apps/platform/app/Support/Navigation/CanonicalNavigationContext.php`
|
|
- `apps/platform/app/Support/OperationRunLinks.php`
|
|
- `apps/platform/app/Support/OperateHub/OperateHubShell.php`
|
|
- representative feature and browser coverage under `apps/platform/tests/Feature/Filament/GovernanceArtifacts/` and `apps/platform/tests/Browser/`
|
|
|
|
## Filament v5 / Panel Notes
|
|
|
|
- **Livewire v4.0+ compliance**: this slice keeps Filament v5 on Livewire v4 and changes only resource registration, route ownership, context resolution, and related links.
|
|
- **Provider registration location**: any provider registration context remains in `apps/platform/bootstrap/providers.php`; nothing moves to `bootstrap/app.php`.
|
|
- **Global search rule**: `282` does not enable global search on new artifact resources. Any touched resource that is already searchable must keep a valid View or Edit destination or be disabled in the same slice.
|
|
- **Destructive actions**: no new destructive actions are introduced. Existing destructive or high-impact actions touched by the route retarget must preserve `->requiresConfirmation()` plus current server authorization.
|
|
- **Asset strategy**: no new asset registration or deployment step is planned.
|
|
|
|
## Governance Artifact Route Ownership Fit
|
|
|
|
- Treat the current environment-owned governance artifact resources as the primary unit of change, not the underlying models or lifecycle semantics.
|
|
- Reuse the workspace-first environment route shell from Spec `280` instead of inventing a parallel artifact route family.
|
|
- Reuse `ResolvesPanelTenantContext` as the shared environment-resolution seam, but make the admin-panel route contract its authoritative source for the touched artifact families.
|
|
- Reuse each resource's current action-surface declaration and local UI semantics; only route ownership, admin registration, and related URLs move.
|
|
- Reuse `OperationRunLinks` and `RelatedNavigationResolver` for artifact-origin operation or related-resource drillthroughs rather than per-resource URL composition.
|
|
- Do not preserve `ManagedEnvironment::current()` as a surviving runtime fallback for touched surfaces. The final shipped contract must resolve the current environment from the workspace-first admin route or operate-hub context only.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: changed surfaces
|
|
- **Native vs custom classification summary**: native Filament
|
|
- **Shared-family relevance**: environment-scoped resources, related navigation, artifact presenters, operation links
|
|
- **State layers in scope**: shell, page, detail, URL-query
|
|
- **Audience modes in scope**: operator-MSP, support-platform, customer-safe read-only where already supported by current surfaces
|
|
- **Decision/diagnostic/raw hierarchy plan**: keep environment scope and primary inspect action visible first; keep diagnostics or raw/support detail secondary on the destination surface
|
|
- **Raw/support gating plan**: unchanged existing gating; this slice does not widen raw evidence disclosure
|
|
- **One-primary-action / duplicate-truth control**: preserve each resource's current inspect model and existing primary action; add no new redundant inspect or navigation affordance
|
|
- **Handling modes by drift class or surface**: review-mandatory
|
|
- **Repository-signal treatment**: review-mandatory until guard coverage proves the touched artifact families no longer depend on the tenant panel
|
|
- **Special surface test profiles**: standard-native-filament, global-context-shell
|
|
- **Required tests or manual smoke**: functional-core, state-contract, manual-smoke
|
|
- **Exception path and spread control**: none; the goal is convergence on the admin-panel route contract
|
|
- **Active feature PR close-out entry**: Guardrail
|
|
|
|
## Shared Pattern & System Fit
|
|
|
|
- **Cross-cutting feature marker**: yes
|
|
- **Systems touched**: environment-owned resources, shared environment-context helpers, related navigation, operation links, artifact presenters, admin-panel route shell
|
|
- **Shared abstractions reused**: `ResolvesPanelTenantContext`, `InteractsWithTenantOwnedRecords`, `RelatedNavigationResolver`, `CanonicalNavigationContext`, `OperationRunLinks`, `ArtifactTruthPresenter`, existing `ActionSurfaceDeclaration`s
|
|
- **New abstraction introduced? why?**: none planned; the existing shared seams are sufficient
|
|
- **Why the existing abstraction was sufficient or insufficient**: the abstractions already express the right ownership and presentation model; they are insufficient only because the tenant panel still leaks into registration and route-generation behavior
|
|
- **Bounded deviation / spread control**: none; if a local escape hatch appears, the work is out of scope and should split
|
|
|
|
## OperationRun UX Impact
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: yes, link semantics only
|
|
- **Central contract reused**: `OperationRunLinks`, `RelatedNavigationResolver`, and the workspace-first operations routes from Spec `280`
|
|
- **Delegated UX behaviors**: artifact-origin operation links, explicit environment-filter continuity, and destination-safe route ownership
|
|
- **Surface-owned behavior kept local**: source resources decide whether a related operation link exists; they do not own the operations URL contract
|
|
- **Queued DB-notification policy**: `N/A`
|
|
- **Terminal notification path**: `N/A`
|
|
- **Exception path**: none
|
|
|
|
## Provider Boundary & Portability Fit
|
|
|
|
N/A - `282` does not alter shared provider identity or capability seams directly. Those remain with Specs `281`, `283`, and `284`.
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before implementation begins and again after design artifacts are complete.*
|
|
|
|
- Inventory-first / snapshot truth: PASS. Artifact persistence truth stays unchanged.
|
|
- Read/write separation: PASS. No new remote-write or lifecycle workflow is introduced.
|
|
- Graph contract path: PASS. No Graph contract change is introduced.
|
|
- Deterministic capabilities: PASS. Existing capability checks stay unchanged.
|
|
- RBAC-UX plane separation: PASS. `/admin` and `/system` remain separate.
|
|
- Workspace isolation: PASS. Workspace membership remains the first route boundary.
|
|
- Managed-environment isolation: PASS. Managed-environment access remains the second route boundary.
|
|
- Destructive action discipline: PASS by non-expansion. Existing confirmation and server authorization remain intact.
|
|
- Global search safety: PASS with implementation condition. Touched searchable surfaces must keep valid destinations or be disabled.
|
|
- OperationRun / Ops-UX: PASS. Only existing operation link semantics move.
|
|
- Data minimization: PASS. No new data or raw disclosure is introduced.
|
|
- Test governance: PASS. Proof stays bounded to focused feature and browser coverage.
|
|
- Proportionality / no premature abstraction: PASS. The plan changes route ownership only.
|
|
- Persisted truth / behavioral state: PASS. No new persistence, state family, or taxonomy is introduced.
|
|
- UI semantics / shared pattern first / Filament-native UI: PASS. Existing native resources and presenters remain the first path.
|
|
- Provider boundary: PASS by non-expansion.
|
|
|
|
**Gate evaluation**: PASS.
|
|
|
|
**Post-design re-check**: PASS while `research.md`, `data-model.md`, `quickstart.md`, `contracts/governance-artifact-retargeting.logical.openapi.yaml`, and `checklists/requirements.md` remain aligned and keep Specs `267`, `277`, and `283` through `287` deferred.
|
|
|
|
## Test Governance Check
|
|
|
|
- **Test purpose / classification by changed surface**: Feature, Browser
|
|
- **Affected validation lanes**: fast-feedback, confidence, browser
|
|
- **Why this lane mix is the narrowest sufficient proof**: the cutover changes resource registration, route ownership, context resolution, and deep-link behavior on existing surfaces. Feature tests prove those contracts; one browser smoke proves the real shell and one representative artifact path.
|
|
- **Narrowest proving command(s)**:
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactAdminPanelRegistrationTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactEnvironmentContextTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactDeepLinkContractTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactLegacyTenantPanelGuardTest.php)`
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec282GovernanceArtifactRetargetingSmokeTest.php)`
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)`
|
|
- **Fixture / helper / factory / seed / context cost risks**: moderate because proof needs workspace membership, managed-environment membership, and representative artifact fixtures across more than one family
|
|
- **Expensive defaults or shared helper growth introduced?**: no; keep new fixtures opt-in and bounded to the governance-artifact family
|
|
- **Heavy-family additions, promotions, or visibility changes**: none
|
|
- **Surface-class relief / special coverage rule**: standard-native-filament relief for most resources; one browser smoke still required for the real shell and route contract
|
|
- **Closing validation and reviewer handoff**: rerun the exact commands above, confirm the touched governance artifact families register on the admin panel, confirm resource URLs and related links no longer emit tenant-panel destinations, confirm environment resolution on the admin panel no longer depends on tenant-panel-only state, confirm touched searchable resources keep truthful destinations or stay disabled, confirm destructive actions still require confirmation, and confirm no new asset or deployment step appears
|
|
- **Budget / baseline / trend follow-up**: contained feature-local increase only
|
|
- **Review-stop questions**: did the implementation leave any touched artifact family admin-hidden, did any touched resource still rely on `panel: 'tenant'` or `tenant:` URLs, did any read-only artifact surface still require `ManagedEnvironment::current()` as the only source of truth, did the slice absorb lifecycle or copy work from adjacent specs
|
|
- **Escalation path**: `reject-or-split` if the implementation introduces schema work, compatibility fallbacks, or adjacent lifecycle or RBAC scope
|
|
- **Active feature PR close-out entry**: Guardrail
|
|
- **Why no dedicated follow-up spec is needed**: the remaining adjacent work already exists as Specs `267`, `277`, and `283` through `287`; route and registration proof stays inside this feature
|
|
|
|
## Review Checklist Status
|
|
|
|
- **Review checklist artifact**: `checklists/requirements.md`
|
|
- **Review outcome class**: `blocked-by-prerequisite`
|
|
- **Workflow outcome**: `keep`
|
|
- **Test-governance outcome**: `keep`
|
|
- **Escalation rule**: if implementation starts without Spec `280` present, leaves touched artifact families tenant-panel-bound, introduces schema or lifecycle work, or widens into adjacent specs, flip the workflow outcome to `split` or `reject-or-split`
|
|
|
|
## Rollout Considerations
|
|
|
|
- Land the touched governance artifact resource families and the shared environment-context helper changes as one bounded slice so admin registration, route ownership, and authorization move together.
|
|
- Do not begin runtime implementation until Spec `280` is merged or otherwise available on the implementation branch.
|
|
- Update shared route and context seams before polishing individual resources so each resource can inherit the same final contract.
|
|
- Keep read-only artifact surfaces in the same slice because they are the most likely place for hidden tenant-panel fallbacks to survive.
|
|
- Keep operation drillthrough retargeting inside the same slice so artifact truth and execution truth stay aligned.
|
|
|
|
## Risk Controls
|
|
|
|
- Reject any implementation that reopens schema, lifecycle, or naming work instead of limiting itself to route ownership and context resolution.
|
|
- Reject any implementation that leaves a touched artifact family hidden from the admin panel or still emitting tenant-panel URLs.
|
|
- Reject any implementation that adds a second local route helper pattern instead of reusing the shared navigation and context seams.
|
|
- Reject any implementation that widens searchable exposure without keeping a truthful destination.
|
|
|
|
## Research & Design Outputs
|
|
|
|
- `research.md` records the candidate deviations, route-ownership decision, touched resource inventory, and deferrals.
|
|
- `data-model.md` captures the route-context and authorization contracts for the environment-owned artifact families.
|
|
- `quickstart.md` gives reviewers the bounded proof flow and exact commands.
|
|
- `contracts/governance-artifact-retargeting.logical.openapi.yaml` records the logical route contract for the touched artifact families and their operation drillthroughs.
|
|
- `checklists/requirements.md` records package readiness, boundedness, and outcome state.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/282-governance-artifact-retargeting/
|
|
├── checklists/
|
|
│ └── requirements.md
|
|
├── contracts/
|
|
│ └── governance-artifact-retargeting.logical.openapi.yaml
|
|
├── data-model.md
|
|
├── plan.md
|
|
├── quickstart.md
|
|
├── research.md
|
|
├── spec.md
|
|
└── tasks.md
|
|
```
|
|
|
|
### Source Code (expected implementation surfaces)
|
|
|
|
```text
|
|
apps/platform/
|
|
├── app/
|
|
│ ├── Filament/
|
|
│ │ ├── Concerns/
|
|
│ │ │ ├── InteractsWithTenantOwnedRecords.php
|
|
│ │ │ └── ResolvesPanelTenantContext.php
|
|
│ │ └── Resources/
|
|
│ │ ├── BackupScheduleResource.php
|
|
│ │ ├── BackupSetResource.php
|
|
│ │ ├── EvidenceSnapshotResource.php
|
|
│ │ ├── FindingExceptionResource.php
|
|
│ │ ├── FindingResource.php
|
|
│ │ ├── InventoryItemResource.php
|
|
│ │ ├── PolicyResource.php
|
|
│ │ ├── PolicyVersionResource.php
|
|
│ │ ├── RestoreRunResource.php
|
|
│ │ ├── ReviewPackResource.php
|
|
│ │ ├── StoredReportResource.php
|
|
│ │ └── TenantReviewResource.php
|
|
│ └── Support/
|
|
│ ├── Navigation/
|
|
│ │ ├── CanonicalNavigationContext.php
|
|
│ │ └── RelatedNavigationResolver.php
|
|
│ ├── OperateHub/
|
|
│ │ └── OperateHubShell.php
|
|
│ └── OperationRunLinks.php
|
|
└── tests/
|
|
├── Browser/
|
|
│ └── Spec282GovernanceArtifactRetargetingSmokeTest.php
|
|
└── Feature/
|
|
└── Filament/
|
|
└── GovernanceArtifacts/
|
|
├── GovernanceArtifactAdminPanelRegistrationTest.php
|
|
├── GovernanceArtifactDeepLinkContractTest.php
|
|
├── GovernanceArtifactEnvironmentContextTest.php
|
|
└── GovernanceArtifactLegacyTenantPanelGuardTest.php
|
|
```
|
|
|
|
**Structure Decision**: Laravel monolith under `apps/platform` with one bounded documentation package under `specs/282-governance-artifact-retargeting/`, no new runtime top-level folders, and no adjacent-page retargeting in this slice.
|
|
|
|
## Deferred Follow-Ups / Non-Goals
|
|
|
|
- Spec `267` artifact lifecycle and retention contract work
|
|
- Spec `277` stored-reports browse and detail productization beyond route ownership
|
|
- Spec `283` provider capability registry
|
|
- Spec `284` provider-neutral artifact taxonomy
|
|
- Spec `285` workspace-first RBAC and environment access scoping redesign
|
|
- Spec `286` UI copy and localization neutralization
|
|
- Spec `287` cutover-wide no-legacy enforcement |