# Feature Specification: Governance Artifact Retargeting to ManagedEnvironment **Feature Branch**: `282-governance-artifact-retargeting` **Created**: 2026-05-07 **Status**: Prepared - blocked by Spec `280` runtime prerequisite **Input**: User description: "Continue with reserved slot `282 - Governance Artifact Retargeting to ManagedEnvironment` as the next preparation-only package. Work repo-based, create spec, plan, and tasks, and do not implement application code." ## Spec Candidate Check - **Problem**: Repo truth already moved the core governance artifact models onto `managed_environment_id` plus `workspace_id`, but many operator-facing artifact resources and drillthroughs still behave like tenant-panel surfaces. They either hide from the admin panel, depend on `ManagedEnvironment::current()` or `panel: 'tenant'` assumptions, or still emit tenant-panel routes from related links and action URLs. - **Today's failure**: Operators can hold correct managed-environment-scoped data in `Finding`, `Policy`, `BackupSet`, `EvidenceSnapshot`, `ReviewPack`, `StoredReport`, `TenantReview`, `RestoreRun`, and adjacent artifacts, but the UI ownership and deep-link contract are still split between the surviving admin panel and the temporary tenant-panel semantics. After Spec `280`, these surfaces would either disappear, keep stale `/admin/t` assumptions, or present the same environment-owned artifact truth through inconsistent route and context rules. - **User-visible improvement**: Operators open governance artifact registers and detail surfaces for the current managed environment entirely inside the workspace-first admin runtime, with one consistent environment-aware route, one consistent breadcrumb shell, and one consistent deep-link contract into related evidence, reviews, reports, and operations. - **Smallest enterprise-capable version**: Reuse the existing models, resources, pages, action surfaces, artifact presenters, and authorization capabilities; re-home the environment-owned governance artifact resource families onto the admin panel under the workspace-first environment route family; centralize environment resolution through the existing panel-context helpers; retarget related links and operation drillthroughs; and keep lifecycle semantics, report-family semantics, copy-neutralization, capability-registry work, and RBAC redesign explicitly deferred. - **Explicit non-goals**: No new schema cutover, no `tenant_id` compatibility alias, no lifecycle-contract work from Spec `267`, no stored-report product-surface expansion beyond the already prepared Spec `277`, no provider capability registry, no provider-neutral artifact taxonomy, no workspace-RBAC redesign, no broader tenant-to-managed-environment copy renaming, no customer-portal change, no route-compatibility fallback, and no dual-panel ownership. - **Permanent complexity imported**: One admin-panel route and registration contract for the existing governance artifact surface families, one bounded environment-context resolution pattern over the existing helper seams, and focused feature and browser coverage. No new table, registry, state family, or meta-framework is introduced. - **Why now**: Spec `279` already completed the model-level managed-environment cutover and Spec `280` prepares the workspace-first routing shell. The next reserved blocker is the resource and link layer: once the `280` route shell is present on the implementation branch, `282` removes the tenant-panel assumptions that still survive on the artifact surfaces operators actually use. - **Why not local**: The hotspot repeats across many resources, page links, and authorization checks. Local page-by-page patches would preserve the underlying split between resource registration, route ownership, context resolution, and deep-link behavior. - **Approval class**: Core Enterprise - **Red flags triggered**: Many operator-facing surfaces, adjacency to lifecycle/reporting specs, and temptation to widen into naming or RBAC work. Defense: the slice is explicitly limited to route ownership, resource registration, shared context resolution, and related-link truth over already-correct persistence. - **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 1 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 10/12** - **Decision**: approve ## Spec Scope Fields - **Scope**: workspace - **Primary Routes**: - `/admin/workspaces/{workspace}/environments/{environment}/inventory` - `/admin/workspaces/{workspace}/environments/{environment}/policies` - `/admin/workspaces/{workspace}/environments/{environment}/policy-versions` - `/admin/workspaces/{workspace}/environments/{environment}/backup-schedules` - `/admin/workspaces/{workspace}/environments/{environment}/backups` - `/admin/workspaces/{workspace}/environments/{environment}/restore-runs` - `/admin/workspaces/{workspace}/environments/{environment}/findings` - `/admin/workspaces/{workspace}/environments/{environment}/finding-exceptions` - `/admin/workspaces/{workspace}/environments/{environment}/evidence` - `/admin/workspaces/{workspace}/environments/{environment}/reviews` - `/admin/workspaces/{workspace}/environments/{environment}/review-packs` - `/admin/workspaces/{workspace}/environments/{environment}/stored-reports` - the existing workspace-first operations routes from Spec `280` remain the only operation drillthrough targets for touched artifact links - **Data Ownership**: - environment-owned governance artifact records already remain anchored by `workspace_id` plus `managed_environment_id`, including `InventoryItem`, `Policy`, `PolicyVersion`, `BackupSchedule`, `BackupSet`, `RestoreRun`, `Finding`, `FindingException`, `EvidenceSnapshot`, `TenantReview`, `ReviewPack`, and `StoredReport` - `OperationRun` remains workspace-owned execution truth with optional `managed_environment_id`; this slice only changes artifact links into that truth - no new artifact super-table, lifecycle table, or workspace-owned mirror is introduced - **RBAC**: - workspace membership remains the first isolation boundary - managed-environment entitlement remains the second isolation boundary - non-members or wrong-workspace or wrong-environment access remain `404` - in-scope actors missing current artifact capabilities remain `403` - current destructive or high-impact actions keep their existing server authorization and confirmation rules ## Cross-Cutting / Shared Pattern Reuse - **Cross-cutting feature?**: yes - **Interaction class(es)**: navigation entry points, related-context drillthroughs, evidence and report viewers, artifact detail surfaces, and operation links from artifact surfaces - **Systems touched**: `ResolvesPanelTenantContext`, `InteractsWithTenantOwnedRecords`, `OperateHubShell`, environment-scoped Filament resources, `RelatedNavigationResolver`, `CanonicalNavigationContext`, `OperationRunLinks`, existing artifact presenters, and the workspace-first environment route contract prepared by Spec `280` - **Existing pattern(s) to extend**: the current workspace-first environment route family, current artifact truth presenters, current resource action-surface declarations, and the shared environment-context helper path - **Shared contract / presenter / builder / renderer to reuse**: `ResolvesPanelTenantContext`, `InteractsWithTenantOwnedRecords`, `RelatedNavigationResolver`, `CanonicalNavigationContext`, `OperationRunLinks`, `ArtifactTruthPresenter`, and each resource's existing `ActionSurfaceDeclaration` - **Why the existing shared path is sufficient or insufficient**: the repo already has the right ownership and presenter seams. What is insufficient is the lingering tenant-panel registration and `ManagedEnvironment::current()` or `tenant:` route assumption in those seams. - **Allowed deviation and why**: none. The slice should converge on the existing shared path instead of adding another per-resource route helper. - **Consistency impact**: environment identity, artifact breadcrumbs, detail routes, related links, and operation drillthroughs must all speak the same workspace-first route language and the same environment context truth. - **Review focus**: reviewers must verify that touched resources reuse the shared context and link helpers, that no targeted artifact surface still requires the tenant panel, and that no new local route-generation pattern appears. ## OperationRun UX Impact - **Touches OperationRun start/completion/link UX?**: yes, link semantics only - **Shared OperationRun UX contract/layer reused**: `OperationRunLinks`, `RelatedNavigationResolver`, and the workspace-first operations surfaces prepared by Spec `280` - **Delegated start/completion UX behaviors**: artifact-origin drillthrough to workspace-first operations index or detail, explicit environment filter continuity, and environment-safe back-navigation context - **Local surface-owned behavior that remains**: artifact resources continue to decide when to expose an operation or review drillthrough; they do not own a second operation URL contract - **Queued DB-notification policy**: `N/A` - **Terminal notification path**: `N/A` - **Exception required?**: none ## Provider Boundary / Platform Core Check N/A - no shared provider or platform-core identity boundary is changed directly in this slice. Provider-profile extraction remains Spec `281`, and broader copy neutralization remains Spec `286`. ## UI / Surface Guardrail Impact | Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note | |---|---|---|---|---|---|---| | Governance register family (`inventory`, `policies`, `policy versions`, `findings`, `finding exceptions`) | yes | Native Filament resources | navigation, related links, environment context, table/detail routes | page, detail, URL-query | no | Reuses current resources and action surfaces; route ownership and admin registration change only | | Recovery and backup family (`backup schedules`, `backup sets`, `restore runs`) | yes | Native Filament resources | operation links, related links, environment context | page, detail, modal, URL-query | no | Existing high-impact action hierarchy remains intact | | Evidence, review, and reporting family (`evidence`, `reviews`, `review packs`, `stored reports`) | yes | Native Filament resources plus existing artifact presenters | evidence/report viewers, related-context drillthroughs, operation links | page, detail, URL-query | no | Existing read-only and reporting semantics stay intact | | Environment-to-artifact drillthroughs and artifact-to-operations links | yes | Native Filament pages plus shared navigation helpers | navigation entry points, operation links, breadcrumb shell | shell, page, URL-query | no | Reuses workspace-first environment and operations contracts rather than adding local redirects | ## Decision-First Surface Role | 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 | |---|---|---|---|---|---|---|---| | Governance register family | Secondary Context Surface | Operator has already chosen the environment and now decides which governed object or exception to inspect | environment-scoped list truth, core status, next inspect action | raw evidence, payloads, or deep diagnostics stay progressive | Secondary because the workspace and environment dashboards remain the initial scope-selection surfaces | Continues existing environment-scoped governance work without a second panel | Removes route and context reconstruction before domain work can start | | Recovery and backup family | Secondary Context Surface | Operator is already in one environment and needs to inspect or continue recovery-safe work | backup or restore state, safe next action, environment scope | detailed run history, related dependencies, and diagnostics stay secondary | Secondary because the decision to work on that environment already happened upstream | Keeps recovery workflows environment-first and workspace-safe | Removes panel hopping for backup or restore follow-up | | Evidence, review, and reporting family | Secondary Context Surface | Operator is already in one environment and needs to inspect retained evidence or reporting truth | artifact status, current or historical truth, environment scope | viewer detail, operation drillthroughs, and report specifics remain secondary | Secondary because these are downstream artifact consumers, not new top-level decision queues | Reuses current artifact viewers and presenters under truthful route ownership | Removes hidden tenant-panel dependencies from calm read-only surfaces | | Environment-to-artifact and artifact-to-operations drillthroughs | Secondary Context Surface | Operator moves from one context into the next without losing environment scope | current environment and target destination only | deeper artifact or operation detail remains on the destination page | Secondary because these links support the already chosen workflow | Keeps navigation aligned to environment work rather than storage structure | Eliminates duplicate route languages and manual scope reconstruction | ## Audience-Aware Disclosure | 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 | |---|---|---|---|---|---|---|---| | Governance register family | operator-MSP, support-platform | environment-scoped register truth and inspect affordance | per-record diagnostics stay on detail views | raw payloads stay in dedicated sections or related viewers | `Open` or existing primary inspect action | raw JSON, low-level identifiers, and support-only detail remain secondary | route shell adds scope once instead of duplicating record summaries | | Recovery and backup family | operator-MSP, support-platform | current environment scope, current safe action, current lifecycle | run history and dependency detail remain secondary | support-only evidence stays gated or downstream | existing primary safe action or inspect action | raw failure context and support detail stay secondary | scope shell does not repeat run or backup outcome text already shown in the page body | | Evidence, review, and reporting family | operator-MSP, support-platform, customer-safe read-only where already supported | artifact truth, environment scope, current or historical status | related operation, review, or evidence diagnostics remain secondary | raw evidence or support detail remains gated by existing capabilities | existing inspect or download action where already allowed | raw/support detail stays hidden by default | environment context moves into the shell instead of being restated in each artifact summary | | Environment-to-artifact and artifact-to-operations drillthroughs | operator-MSP, support-platform | destination context and the one next step | none beyond explicit destination labels | none | `Open` or `View operation` | debug route or context detail stays hidden | link labels state scope once and delegate detail to the destination | ## UI/UX Surface Classification | 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 | |---|---|---|---|---|---|---|---|---|---|---|---|---|---| | Governance register family | List / Table / Resource family | CRUD or registry resources | Open one environment-owned record | preserve each resource's existing inspect model | preserve current contract | preserve current contract | preserve current contract | `/admin/workspaces/{workspace}/environments/{environment}/{domain}` | `/admin/workspaces/{workspace}/environments/{environment}/{domain}/{record}` | workspace plus managed environment | existing domain noun | active workspace and environment scope plus resource-local truth | none | | Recovery and backup family | List / Table / Resource family | action-bearing operational resources | Inspect or continue one backup or restore flow | preserve each resource's existing inspect model | preserve current contract | preserve current contract | preserve current contract | `/admin/workspaces/{workspace}/environments/{environment}/{domain}` | `/admin/workspaces/{workspace}/environments/{environment}/{domain}/{record}` | workspace plus managed environment | existing domain noun | active workspace and environment scope plus operational state | none | | Evidence, review, and reporting family | List / Table / Read-only resource family | read-only registry and detail resources | Open one artifact viewer or report | preserve each resource's existing inspect model | preserve current contract | preserve current contract | preserve current contract | `/admin/workspaces/{workspace}/environments/{environment}/{domain}` | `/admin/workspaces/{workspace}/environments/{environment}/{domain}/{record}` | workspace plus managed environment | existing domain noun | active workspace and environment scope plus artifact truth | none | | Environment-to-artifact and artifact-to-operations drillthroughs | Related Context / Navigation / Deep links | workflow navigation | Open the next relevant domain or operation page | explicit link or row affordance already owned by the source surface | preserve current contract | none beyond source-surface rules | none | source environment page or artifact page | workspace-first environment or operations destination | current workspace and environment | existing domain noun | destination scope and current context | none | ## Operator Surface Contract | 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 | |---|---|---|---|---|---|---|---|---|---|---| | Governance register family | Environment operator | Decide which governed record or exception to inspect next | Environment-scoped resource family | Which record in this environment needs inspection now? | environment scope, table truth, current record status | record-local diagnostics and related evidence | resource-local state families | preserve current semantics | preserve current primary inspect action | preserve current dangerous actions | | Recovery and backup family | Environment operator | Decide whether backup or restore work needs follow-up | Environment-scoped operational resource family | Which recovery-safe item or run needs follow-up? | environment scope, lifecycle, and safe next action | deeper run diagnostics or dependency detail | lifecycle, execution state, readiness | preserve current semantics | preserve current primary inspect or continue action | preserve current dangerous actions | | Evidence, review, and reporting family | Environment operator or reviewer | Decide which retained artifact to open and consume | Environment-scoped read-only resource family | Which artifact represents the truth I need to inspect now? | environment scope, artifact truth, current or historical posture | deeper viewer detail, report family detail, related operations | artifact truth, readiness, lifecycle where already present | preserve current semantics | preserve current inspect or download action | preserve current dangerous actions where already defined | | Environment-to-artifact and artifact-to-operations drillthroughs | Environment operator | Move safely into the next relevant page without losing scope | Navigation and related-context paths | Am I opening the right destination for this environment? | destination label plus current scope | none | none beyond current scope | none | `Open` or `View operation` | none | ## Proportionality Review - **New source of truth?**: no - **New persisted entity/table/artifact?**: no - **New abstraction?**: no - **New enum/state/reason family?**: no - **New cross-domain UI framework/taxonomy?**: no - **Current operator problem**: environment-owned governance artifacts already persist correctly, but their admin ownership, route language, and context resolution still depend on a temporary tenant-panel model. - **Existing structure is insufficient because**: the route and registration split repeats across many existing resources and link builders. Keeping those assumptions local would preserve the broken contract after the workspace-first panel cutover. - **Narrowest correct implementation**: reuse the current resources and shared helpers, move only the surface ownership and link contract, and keep all lifecycle, naming, capability, and taxonomy follow-up work out of scope. - **Ownership cost**: focused updates across resource registration, context resolution, route generation, and proof coverage for the touched artifact families. - **Alternative intentionally rejected**: local redirects, per-resource admin fallbacks, or widening the slice into lifecycle, naming, or RBAC work. Those options either preserve drift or inflate scope. - **Release truth**: current-release truth ### External implementation prerequisite Spec `280` must already be merged or otherwise present on the implementation branch before `282` runtime work begins. This package is prep-complete only when read as the bounded artifact-surface slice that reuses the `280` workspace-first environment route shell. ### Compatibility posture This feature assumes a pre-production environment. Backward compatibility, route aliases, tenant-panel shims, dual registration, and compatibility-specific tests are out of scope unless explicitly required by this spec. Canonical replacement is preferred over preservation. ## Testing / Lane / Runtime Impact - **Test purpose / classification**: Feature, Browser - **Validation lane(s)**: fast-feedback, confidence, browser - **Why this classification and these lanes are sufficient**: this slice changes resource registration, route ownership, context resolution, authorization boundaries, and drillthrough links across existing Filament resources. Focused feature coverage proves route and entitlement truth; one browser smoke proves the surviving environment-to-artifact flow in the real admin shell. - **New or expanded test families**: one governance-artifact resource-registration family, one environment-context and authorization family, one deep-link contract family, one legacy-tenant-panel guard family, and one narrow browser smoke - **Fixture / helper cost impact**: moderate. Proof needs workspace membership, managed-environment membership, representative artifact fixtures, and one real browser path. No new global fixture defaults should be introduced. - **Heavy-family visibility / justification**: one browser smoke only. No heavy-governance family is justified. - **Special surface test profile**: standard-native-filament, global-context-shell - **Standard-native relief or required special coverage**: ordinary feature coverage is sufficient for the resource families; one browser smoke is required because the cutover spans route shell plus multiple resource families. - **Reviewer handoff**: reviewers must confirm Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, touched artifact resources either remain non-globally-searchable or keep a valid view/edit destination, destructive actions touched by the retarget continue to require confirmation plus authorization, no new asset registration appears, and the planned proof commands stay aligned across `spec.md`, `plan.md`, and `quickstart.md`. - **Budget / baseline / trend impact**: moderate feature-local increase only - **Escalation needed**: none - **Active feature PR close-out entry**: Guardrail - **Planned validation commands**: - `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)` ## Scope Boundaries ### In Scope - document the verified candidate deviation that governance artifact persistence is already `managed_environment_id` plus `workspace_id` based in repo truth - register the current environment-owned governance artifact resource families on the surviving admin panel and workspace-first environment routes - retarget environment context resolution for those artifact families so admin-panel requests no longer depend on the tenant panel or `ManagedEnvironment::current()` as the only source of truth - retarget related navigation and operation drillthrough links from the touched artifact families to the workspace-first route contract prepared by Spec `280` - keep existing capability and action-surface semantics intact while moving route ownership and registration into the workspace-first shell - keep `TenantReview`, `StoredReport`, `ReviewPack`, and evidence viewers environment-aware on the admin panel without widening into copy or lifecycle rewrites ### Non-Goals - any new schema move for `managed_environment_id`, `workspace_id`, or `tenant_id` - lifecycle, retention, hold, delete-request, or export governance contract work from Spec `267` - broader stored-report browse and presentation work beyond the already prepared Spec `277` - provider capability registry, provider-neutral artifact taxonomy, or provider-boundary extraction work reserved for Specs `281`, `283`, and `284` - workspace-first RBAC redesign or environment-access model changes reserved for Spec `285` - broad tenant-to-managed-environment copy, naming, or localization changes reserved for Spec `286` - cutover quality-gate hardening beyond the feature-local proof for this slice, reserved for Spec `287` - compatibility routes, redirects, local route shims, or hidden tenant-panel fallbacks ## Assumptions - Spec `279` already completed the model-level `managed_environment_id` cutover and remains historical prerequisite context only. - Spec `280` prepares the workspace-first route shell and remains a blocking runtime prerequisite; `282` must reuse that contract rather than redefine it. - Spec `281` remains the provider-boundary package; `282` should inherit its provider-neutral seams when implementation begins, not absorb them during prep. - The existing artifact presenters, resource classes, and context helpers are the correct extension points for this slice. - Most touched governance artifact resources already remain non-globally-searchable or have existing view pages; `282` should not widen global search. ## Risks - Some resources may appear superficially admin-safe because they already use `ResolvesPanelTenantContext`, while still hiding from admin navigation or emitting stale `tenant:` URLs from action closures. - Read-only artifact surfaces such as review packs and stored reports may still rely on `ManagedEnvironment::current()` in subtle fallbacks that break after the tenant panel is removed. - Recovery-safe surfaces may carry many action URLs and related-resource links; if those links are not retargeted through shared helpers, the slice could leave a half-migrated admin experience. - The slice could sprawl into lifecycle semantics, stored-report productization, copy-neutralization, or RBAC redesign if the boundaries against Specs `267`, `277`, and `283` through `287` are not kept explicit. ## Candidate Selection Gate Summary - **Selected candidate**: `282 - Governance Artifact Retargeting to ManagedEnvironment` - **Source locations**: - `docs/product/spec-candidates.md` under the reserved workspace-first managed-environment cutover pack - `docs/product/roadmap.md` under the same cutover ordering - **Why selected now**: the user explicitly directed work toward slot `282`, and repo truth confirms it is the next reserved cutover slice that still lacks a spec directory. After `279` moved persistence and `280` and `281` prepare the shell and provider seams, the real remaining blocker is the governance artifact surface layer. - **Why close alternatives were deferred**: - `283` belongs to capability-registry follow-through and would widen the slice beyond route and context retargeting - `284` belongs to provider-neutral artifact taxonomy and would add new cross-domain semantics before the current surfaces finish moving - `285` belongs to RBAC redesign and capability-model follow-through, not current route ownership - `286` belongs to copy and localization neutralization, not current artifact registration and link truth - `287` belongs to cutover-wide no-legacy enforcement after the current reserved slices exist - `267` and `277` are already prepared packages for artifact lifecycle and stored-report surface work and must remain separate - **Smallest viable implementation slice**: move the existing environment-owned governance artifact resource families onto the workspace-first admin runtime, unify environment-context resolution there, and retarget their related links and operation drillthroughs without changing persistence or naming. - **Documented deviations from raw candidate wording**: - the raw candidate still sounds like a model or schema retarget of artifact tables, but repo truth already completed that move through `managed_environment_id` plus `workspace_id` - the raw candidate mentions renaming review concepts and removing remaining `/admin/t` links broadly; this package narrows that to the touched governance artifact surface families and explicitly defers broader copy or no-legacy work to Specs `286` and `287` - the raw candidate's `operation_runs` retarget is already satisfied at the persistence layer by Spec `279`; `282` only retargets artifact-origin links into the existing workspace-first operations routes prepared by Spec `280` - the raw candidate's `backup items` concern remains nested under existing backup-set or restore-run surfaces and does not create a separate top-level route family in `282` ## Completed-Spec Guardrail Result - `specs/279-workspace-managed-environment-core/` already exists with implementation-close-out history and remains historical prerequisite context only - `specs/280-workspace-tenancy-environment-routing/` already exists with `Status: Ready` and remains adjacent prepared context only - `specs/281-provider-connection-scope/` already exists with `Status: Ready` and remains adjacent prepared context only - `specs/267-artifact-lifecycle-retention/` already exists with `Status: Ready for implementation` and remains a separate lifecycle package - `specs/277-stored-reports-surface/` already exists with `Status: Ready for implementation` and remains a separate stored-report package - the target package `specs/282-governance-artifact-retargeting/` did not exist before this prep run and is the sole new package created here ## Deferred Adjacent Candidates - `283 - Provider Capability Registry v1` - `284 - Provider-neutral Artifact Source Taxonomy v1` - `285 - Workspace-first RBAC & Environment Access Scoping` - `286 - UI Copy, IA & Localization Neutralization` - `287 - Cutover Quality Gates & No-Legacy Enforcement` ## User Scenarios & Testing ### User Story 1 - Open governance resources for one environment inside the admin panel (Priority: P1) As an operator, I want the core governance resource families for one managed environment to open under the workspace-first admin routes so I can inspect records without crossing into the removed tenant panel. **Why this priority**: this is the central artifact-retargeting outcome. If these resources still hide from the admin panel or rely on `panel: 'tenant'`, the reserved cutover slot is not complete. **Independent Test**: select a workspace and managed environment, then open representative governance resources such as findings, policies, inventory, or backups and confirm they resolve under the workspace-first environment route family. **Acceptance Scenarios**: 1. **Given** an operator is in one workspace and managed environment, **When** they open a touched governance register, **Then** the destination stays on `/admin/workspaces/{workspace}/environments/{environment}/...` and lists only that environment's records. 2. **Given** an operator requests a governance resource under a mismatched workspace or environment pair, **When** the route resolves, **Then** the app returns `404` and reveals no artifact data. --- ### User Story 2 - Read retained evidence and reporting artifacts with the same environment context (Priority: P1) As an operator, I want evidence, reviews, review packs, and stored reports to stay environment-aware on the surviving admin panel so I can consume retained artifact truth without depending on `ManagedEnvironment::current()` from the tenant panel. **Why this priority**: these resource families are the calmest artifact consumers and are the easiest place for hidden panel-context fallbacks to survive. **Independent Test**: open evidence, one review-pack or review detail, and one stored-report detail from the current environment and confirm each surface renders under the workspace-first environment shell with the correct environment scope. **Acceptance Scenarios**: 1. **Given** an operator opens an evidence or reporting artifact from one managed environment, **When** the page renders, **Then** the surface resolves the current environment through the admin-panel route context and not only through the old tenant panel. 2. **Given** an artifact row belongs to a different managed environment than the current route context, **When** the operator tries to open it directly, **Then** access is denied as `404`. --- ### User Story 3 - Follow artifact drillthroughs into operations without stale tenant-panel links (Priority: P2) As an operator, I want artifact-origin links such as restore-run follow-up or review-pack operation drillthroughs to open the workspace-first operations surfaces so I do not lose environment scope while tracing what produced the artifact. **Why this priority**: artifact truth is only trustworthy if its related operation and navigation links stay on the same workspace-first contract. **Independent Test**: open a touched artifact surface with an operation drillthrough, follow `View operation`, and confirm the destination is the workspace-first operations route with environment-safe context. **Acceptance Scenarios**: 1. **Given** an artifact surface exposes a related operation, **When** the operator opens that drillthrough, **Then** the destination is the workspace-first operations collection or detail route rather than a tenant-panel URL. 2. **Given** the related operation belongs to the current workspace but not the current environment, **When** the destination resolves, **Then** the link either narrows safely to the correct environment context or denies access without leaking scope. --- ### User Story 4 - Keep authorization, search, and no-legacy expectations truthful (Priority: P3) As an operator, I want direct URLs and any touched searchable surfaces to stay truthful after the retarget so the admin panel does not leak stale tenant-panel hints or broken destinations. **Why this priority**: route and registration work often leaves behind silent search drift or compatibility fallbacks unless the spec pins them down. **Independent Test**: open touched direct URLs and any touched searchable destinations, then confirm authorized routes resolve under the workspace-first environment contract and no touched artifact surface still depends on the tenant panel. **Acceptance Scenarios**: 1. **Given** a touched artifact surface remains reachable from search or related navigation, **When** the operator opens it, **Then** the destination is a valid workspace-first environment route. 2. **Given** a touched artifact surface cannot keep a truthful destination under the new route contract, **When** the cutover ships, **Then** that surface is hidden from search or related entry points in the same slice. ### Edge Cases - A request that carries a remembered or explicit environment from another workspace must clear or deny that context before any touched artifact surface loads. - A touched resource that already uses `ResolvesPanelTenantContext` may still fail if it also hides from admin registration or emits `tenant:` URLs from actions or related links; both sides of the contract must move together. - Read-only artifact surfaces that fall back to `ManagedEnvironment::current()` must continue to work on the admin panel when the tenant panel is gone. - Restore and backup surfaces with many action closures must not leave a single stale tenant-panel URL behind when the rest of the resource is retargeted. - If a touched resource remains globally searchable or reachable from related navigation, its destination must stay valid under the workspace-first route family or be disabled in the same slice. ## Requirements **Constitution alignment (required):** This slice changes route ownership, environment-context resolution, navigation, related links, and admin registration for existing governance artifact surfaces. It does not introduce new persistence, new Microsoft Graph calls, new long-running workflow types, or a new artifact lifecycle contract. **Constitution alignment (XCUT-001 / UI-FIL-001):** The slice must reuse the existing resource classes, artifact presenters, navigation helpers, and workspace-first environment route shell. It must not create a second artifact workbench, local route helper framework, or ad hoc UI system. **Constitution alignment (RBAC-UX):** Workspace membership remains the first boundary and managed-environment access remains the second boundary. Non-members remain `404`, in-scope capability denials remain `403`, and touched destructive or high-impact actions retain existing confirmation plus server authorization. **Constitution alignment (TEST-GOV-001):** Proof stays bounded to focused feature coverage, one narrow browser smoke, and a legacy-tenant-panel guard test. No heavy-governance family is introduced. ### Functional Requirements - **FR-001**: `workspace_id` plus `managed_environment_id` remain the canonical ownership anchors for the touched governance artifact models, and the implementation MUST NOT reintroduce `tenant_id` aliases or dual relations. - **FR-002**: The current environment-owned governance artifact resources that are still tenant-panel-bound or admin-hidden MUST register and resolve under the workspace-first admin panel and environment route family. - **FR-003**: The touched governance artifact surface families include, at minimum, the current resources for inventory, policies, policy versions, backup schedules, backup sets, restore runs, findings, finding exceptions, evidence snapshots, tenant reviews, review packs, and stored reports. - **FR-004**: The touched resources MUST scope collection and detail queries to the current workspace and managed environment through the surviving admin-panel context rather than through tenant-panel ownership. - **FR-005**: `ResolvesPanelTenantContext` and any cooperating helper seams MUST resolve the current managed environment on the admin panel through the workspace-first route or current operate-hub context rather than relying on the tenant panel as the only source of truth. - **FR-006**: Resource families that currently hide from admin navigation through `shouldRegisterNavigation()` or equivalent tenant-panel checks MUST stop doing so once their workspace-first environment route contract is available. - **FR-007**: Touched artifact resources and pages MUST emit workspace-first environment URLs from list actions, header actions, related links, and record URLs, and MUST NOT emit `tenant:` or `panel: 'tenant'` destinations. - **FR-008**: Evidence, reviews, review packs, and stored reports MUST remain read-only or action-equivalent to current repo truth; `282` retargets route and context ownership, not lifecycle or publish semantics. - **FR-009**: Restore, backup, policy, and finding surfaces MUST preserve their current action hierarchy and confirmation behavior while changing only route ownership, context resolution, and related drillthrough URLs. - **FR-010**: Artifact-origin operation drillthroughs MUST use the workspace-first operations routes and preserve managed-environment context where the current workflow already expects it. - **FR-011**: Touched artifact surfaces MUST present breadcrumb and context-shell ordering consistent with the workspace-first environment contract from Spec `280`. - **FR-012**: `TenantReview` naming, review-language neutralization, and other broader copy changes remain out of scope for `282` and reserved for later specs. - **FR-013**: The slice MUST NOT absorb lifecycle work from Spec `267`, stored-report product-surface expansion from Spec `277`, or reserved follow-up work from Specs `283` through `287`. - **FR-014**: Any touched resource that remains searchable or reachable from shared navigation MUST keep a truthful destination under the workspace-first route contract or be disabled in the same slice. ### Authorization and Safety Requirements - **AR-001**: Workspace membership MUST remain the first access boundary for all touched artifact routes. - **AR-002**: Managed-environment entitlement MUST remain the second access boundary for touched artifact routes and drillthroughs. - **AR-003**: A mismatched workspace and managed environment pair MUST resolve as `404`, even if the actor can access one side individually. - **AR-004**: Explicit hostile environment hints or record URLs outside the current workspace or environment MUST resolve as `404`, not as widened scope. - **AR-005**: Existing destructive or high-impact actions on touched resources MUST stay server-authorized and continue to require confirmation where current repo truth already requires it. ### Non-Functional Requirements - **NFR-001**: Filament remains v5 on Livewire v4. - **NFR-002**: Provider registration remains in `apps/platform/bootstrap/providers.php`; nothing moves to `bootstrap/app.php`. - **NFR-003**: Existing admin theme and asset strategy remain unchanged, and no new asset registration or deploy step is introduced. - **NFR-004**: Touched artifact resources either remain non-globally-searchable or keep a valid view or edit destination under the new route contract. - **NFR-005**: The slice must remain reviewable as one bounded artifact-surface package and must not silently absorb lifecycle, provider, RBAC, copy, or cutover-quality work from adjacent specs. ## UI Action Matrix | Surface | Location | Header Actions | Inspect Affordance (List or Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create or Edit Save+Cancel | Audit log? | Notes / Exemptions | |---|---|---|---|---|---|---|---|---|---|---| | Governance register family | touched governance resources under `/admin/workspaces/{workspace}/environments/{environment}/{domain}` | preserve current resource-local header actions | preserve each resource's existing inspect model | preserve current contract | preserve current contract | preserve current contract | preserve current contract | preserve current contract | preserve current behavior | `282` changes route ownership and registration only | | Recovery and backup family | backup and restore resources under the same route shell | preserve current resource-local header actions | preserve each resource's existing inspect model | preserve current contract | preserve current contract | preserve current contract | preserve current contract | preserve current contract | preserve current behavior | confirmation and safety flow remain unchanged | | Evidence, review, and reporting family | evidence, reviews, review packs, stored reports | preserve current resource-local header actions | preserve each resource's existing inspect model | preserve current contract | preserve current contract | preserve current contract | preserve current contract | `N/A` where read-only already applies | preserve current behavior | read-only and download semantics stay unchanged | All other touched related-context links keep their existing local action contracts. This slice changes only route ownership, admin registration, environment-context resolution, and deep-link truth. ### Key Entities - **Workspace Context**: the first isolation boundary and current admin-panel tenant context. - **Managed Environment Context**: the nested environment scope that owns the touched governance artifact records. - **Governance Artifact Record**: an existing environment-owned record such as `Finding`, `Policy`, `BackupSet`, `EvidenceSnapshot`, `ReviewPack`, `TenantReview`, or `StoredReport` that already persists `managed_environment_id` plus `workspace_id`. - **Artifact Route Context**: the workspace-first route ownership for those records under `/admin/workspaces/{workspace}/environments/{environment}/...`. - **Artifact Operation Drillthrough**: the related link from one touched artifact surface into the workspace-first operations routes. ## Success Criteria ### Measurable Outcomes - **SC-001**: Representative governance artifact resources open under the workspace-first environment route family with no operator-visible dependency on `/admin/t` on touched surfaces. - **SC-002**: Touched evidence, review, and reporting resources resolve the current environment correctly on the admin panel without relying on tenant-panel-only context. - **SC-003**: Artifact-origin operation drillthroughs open the workspace-first operations routes with truthful environment context. - **SC-004**: Wrong-workspace or wrong-environment direct access to touched artifact routes reveals no data and resolves as `404`.