# Data Model: Tenant-Owned Query Canon and Wrong-Tenant Guards ## 1. TenantOwnedModelFamily - Purpose: Defines which data families are mandatory consumers of the canonical tenant-owned query rule. - Fields: - `name`: stable family name such as `Policy`, `PolicyVersion`, `BackupSet`, `BackupSchedule`, `RestoreRun`, `Finding`, `InventoryItem`, `EntraGroup` - `table`: underlying tenant-owned table name - `owns_tenant_scope`: always `true` for in-scope families - `primary_surface`: Filament resource or page that exposes the family - `search_posture`: `scoped`, `disabled`, or `not_applicable` - `action_surface_status`: `declared` or `baseline_exemption` - `action_surface_reason`: why the Action Surface Contract is declared directly or why an exemption remains temporary - `notes`: documented exceptions or rollout deferments - Relationships: - One `TenantOwnedModelFamily` has many `TenantOwnedAccessPath` entries - One `TenantOwnedModelFamily` has many `WrongTenantGuardScenario` entries ## 2. TenantOwnedAccessPath - Purpose: Represents every way an operator can reach or act on a tenant-owned record. - Fields: - `family_name`: owning `TenantOwnedModelFamily` - `path_type`: one of `index`, `detail`, `row_action`, `bulk_action`, `relation_manager`, `global_search`, `canonical_viewer` - `scope_anchor`: `route_tenant`, `owner_record`, or `explicit_record_lookup` - `entitlement_rule`: `workspace_and_tenant_required` - `capability_rule`: `capability_after_scope` - `not_entitled_result`: always `404` - `missing_capability_result`: always `403` for protected actions after scope is established - `record_lookup_behavior`: `same_as_list_scope` or `explicit_exception` - State transitions: - `accessible` when workspace membership, tenant entitlement, and lookup congruence are all satisfied - `not_found` when workspace or tenant scope fails or when the record belongs to a foreign tenant - `forbidden` when scope passes but the protected action capability fails ## 3. CanonicalTenantOwnedQueryRule - Purpose: The conceptual contract that all in-scope surfaces must use to obtain records. - Fields: - `family_name`: target model family - `tenant_source`: `route_tenant`, `panel_tenant`, or `explicit_record_owner` - `workspace_source`: current workspace context - `query_shape`: constrained family query that cannot widen beyond the owning tenant - `action_target_check`: boolean flag requiring congruence between submitted record IDs and the resolved tenant scope - `search_rule`: `scoped_only` or `disabled` - Invariants: - Must never widen from one tenant to another within the same request path - Must fail closed when tenant context is missing for a tenant-bound surface - Must preserve explicit record-owner entitlement checks for canonical viewers ## 4. WrongTenantGuardScenario - Purpose: Captures the test matrix that proves the canon works across representative surfaces. - Fields: - `family_name`: target model family - `scenario_type`: `positive_scope`, `wrong_tenant_index`, `wrong_tenant_detail`, `wrong_tenant_row_action`, `wrong_tenant_bulk_action`, `wrong_tenant_relation_manager`, `safe_search` - `expected_outcome`: `200`, `403`, `404`, or `hidden_or_disabled_without_side_effect` - `surface_class`: route test, Livewire table test, relation-manager test, or guard test - `notes`: explanation of any Filament-specific behavior such as hidden actions not returning literal 404 ## 5. ScopeException - Purpose: Documents legitimate cases that touch tenant data but are not treated as ordinary tenant-owned surfaces. - Fields: - `surface_name`: human-readable surface name - `exception_kind`: `workspace_admin_canonical_viewer`, `workspace_owned_reference_surface`, or `deferred_family` - `why_excepted`: concise reason the canonical tenant-bound list rule does not apply directly - `still_required_checks`: explicit list of remaining workspace, tenant, and capability checks ## 6. ResidualRolloutInventoryEntry - Purpose: Tracks tenant-owned tables that remain outside the first-slice family map so future rollout work stays explicit instead of rediscovered ad hoc. - Fields: - `name`: stable residual family name - `table`: underlying tenant-owned table name - `likely_surface`: current relation-manager, reporting surface, or diagnostics entry point that still touches the table - `why_not_in_first_slice`: concise reason this table is not yet a first-slice primary family ## Initial Rollout Family Map | Family | Table | Primary Surface | Access Paths In First Slice | Search Posture | Action Surface Contract | |---|---|---|---|---|---| | Policy | `policies` | `PolicyResource` | index, detail, row action, bulk action, relation manager linkage | disabled until parity is guaranteed | declared | | PolicyVersion | `policy_versions` | `PolicyVersionResource` | index, detail, row action, bulk action, relation manager | disabled until parity is guaranteed | declared | | BackupSchedule | `backup_schedules` | `BackupScheduleResource` | index, detail, row action, bulk action | not applicable | declared | | BackupSet | `backup_sets` | `BackupSetResource` | index, detail, row action, bulk action, relation manager | not applicable | declared | | RestoreRun | `restore_runs` | `RestoreRunResource` | index, detail, row action, bulk action | not applicable | baseline exemption until restore-track retrofit lands | | Finding | `findings` | `FindingResource` | index, detail, row action, bulk action | not applicable | declared | | InventoryItem | `inventory_items` | `InventoryItemResource` | index, detail, row action, bulk action | not applicable | declared | | EntraGroup | `entra_groups` | `EntraGroupResource` | index, detail, global search, canonical viewer | scoped | declared | ## Residual Rollout Inventory | Family | Table | Likely Surface | Why Not In First Slice | |---|---|---|---| | BackupItem | `backup_items` | `BackupSetResource::BackupItemsRelationManager` | Covered through the backup-set relation manager rather than a standalone primary resource. | | InventoryLink | `inventory_links` | `InventoryItemResource` related-links affordances | Inventory links remain subordinate navigation metadata and inherit tenant scope through inventory items. | | EntraRoleDefinition | `entra_role_definitions` | Entra admin-role reporting and findings reference flows | Direct tenant-owned resource parity is deferred while read paths remain indirect. | | TenantPermission | `tenant_permissions` | Permissions and onboarding diagnostics surfaces | Permission posture is enforced through dedicated diagnostics and onboarding flows, not a first-slice primary resource. | ## Explicit Exceptions In First Slice - `ProviderConnectionResource`: tenant-owned data with a workspace-admin tenant-default surface. It is a useful reference but not the primary implementation slice for the tenant-bound canon. - `OperationRunResource`: workspace-owned canonical monitoring surface. It remains relevant only when it deep-links into tenant-owned records. - `AlertDeliveryResource`: mixed workspace-owned and tenant-bound semantics, therefore outside the mandatory tenant-owned family set for this slice.