# Data Model: Governance Artifact Retargeting to ManagedEnvironment ## Purpose Describe the route-context and ownership contract that `282` will implement over existing governance artifact records. This package does not add new persisted entities. ## Core Context Objects ### WorkspaceContext | Field | Type | Source | Notes | |---|---|---|---| | `workspace_id` | integer | route or current admin context | first isolation boundary | | `workspace_slug` | string | route | route-readable workspace identity | ### ManagedEnvironmentContext | Field | Type | Source | Notes | |---|---|---|---| | `managed_environment_id` | integer | route or operate-hub context | second isolation boundary | | `environment_slug` | string | route | route-readable environment identity | | `workspace_id` | integer | route + record invariant | must match the active workspace context | ### ArtifactRouteContext | Field | Type | Source | Notes | |---|---|---|---| | `workspace` | route parameter | workspace-first admin shell | required | | `environment` | route parameter | workspace-first admin shell | required for all touched artifact families | | `domain_slug` | static resource slug | resource family | for example `findings`, `backups`, `evidence`, `review-packs` | | `record_id` | route parameter | detail route | optional on collection routes | ## Existing Artifact Families Covered By 282 | Family | Representative model(s) | Ownership invariant | Surface outcome in 282 | |---|---|---|---| | Governance registers | `InventoryItem`, `Policy`, `PolicyVersion`, `Finding`, `FindingException` | `workspace_id` + `managed_environment_id` | register and detail surfaces live on workspace-first environment routes | | Recovery and backup | `BackupSchedule`, `BackupSet`, `RestoreRun` | `workspace_id` + `managed_environment_id` | action-bearing resources keep their current semantics on workspace-first environment routes | | Evidence and reporting | `EvidenceSnapshot`, `TenantReview`, `ReviewPack`, `StoredReport` | `workspace_id` + `managed_environment_id` | read-only or current action semantics continue on workspace-first environment routes | ## Shared Invariants - A touched artifact record may only render when the route `workspace_id` matches the record `workspace_id`. - A touched artifact record may only render when the route `managed_environment_id` matches the record `managed_environment_id`. - Resource collection queries must filter to both the active workspace and the active managed environment. - Related navigation and operation drillthroughs must preserve the same workspace and managed-environment context. - Any touched surface that cannot satisfy those invariants must deny as `404` rather than widen scope. ## Authorization Contract | Check | Expected result | |---|---| | Actor lacks workspace membership | `404` | | Actor has workspace membership but lacks environment entitlement | `404` | | Actor has correct scope but lacks resource capability | `403` | | Actor opens a record from another environment in the same workspace | `404` | | Actor opens a record from another workspace | `404` | ## Operation Drillthrough Contract | Field | Meaning | |---|---| | `workspace_id` | operation route remains inside the active workspace | | `managed_environment_id` | operation list or detail opens with truthful environment context where applicable | | `origin_surface` | optional navigation/back-link hint only; not persisted truth | `282` does not change `OperationRun` persistence. It only requires touched artifact surfaces to link into the workspace-first operations contract from Spec `280`. ## Out Of Scope Shapes - No new artifact super-entity - No new lifecycle state family - No new provider-capability or taxonomy fields - No renaming of `TenantReview` or other tenant-shaped class names - No compatibility `tenant_id` aliases or dual relations - No adjacent-page route retargeting in `282` - No standalone `backup items` route family in `282`