# Admin Canonical Tenant Rollout ## Purpose Spec 136 completes the workspace-admin canonical tenant rule across admin-visible and admin-reachable shared surfaces. Workspace-admin requests under `/admin/...` resolve tenant context through `App\Support\OperateHub\OperateHubShell::activeEntitledTenant(request())`. Tenant-panel requests under `/admin/t/{tenant}/...` keep panel-native tenant semantics. ## Rollout Manifest ### Type A: Hard tenant-sensitive - `app/Filament/Resources/PolicyResource.php` - `app/Filament/Resources/BackupScheduleResource.php` - `app/Filament/Resources/BackupSetResource.php` - `app/Filament/Resources/FindingResource.php` - `app/Filament/Pages/BaselineCompareLanding.php` - `app/Filament/Resources/RestoreRunResource.php` - `app/Filament/Resources/InventoryItemResource.php` - `app/Filament/Resources/PolicyVersionResource.php` - `app/Filament/Pages/TenantDiagnostics.php` - `app/Filament/Pages/InventoryCoverage.php` - `app/Filament/Widgets/Inventory/InventoryKpiHeader.php` ### Type B: Workspace-wide with tenant-default behavior - `app/Filament/Resources/ProviderConnectionResource.php` - `app/Filament/Pages/Monitoring/AuditLog.php` - `app/Filament/Resources/EntraGroupResource.php` - `app/Filament/Resources/AlertDeliveryResource.php` ### Type C: Workspace-only non-regression references - `app/Filament/Resources/AlertRuleResource.php` - `app/Filament/Resources/BaselineProfileResource.php` - `app/Filament/Resources/BaselineSnapshotResource.php` - `app/Filament/Resources/TenantResource.php` ## Persisted Filter Sync Apply `App\Support\Filament\CanonicalAdminTenantFilterState::sync()` on admin list surfaces that persist filters in session. - `app/Filament/Resources/AlertDeliveryResource/Pages/ListAlertDeliveries.php` - `app/Filament/Pages/Monitoring/AuditLog.php` - `app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php` - `app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php` - `app/Filament/Resources/FindingResource/Pages/ListFindings.php` - `app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php` - `app/Filament/Resources/PolicyVersionResource/Pages/ListPolicyVersions.php` - `app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php` - `app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php` ## Guarded Files These files must not introduce raw admin-path `Tenant::current()` or `Filament::getTenant()` reads: - `app/Filament/Pages/BaselineCompareLanding.php` - `app/Filament/Pages/TenantDiagnostics.php` - `app/Filament/Pages/InventoryCoverage.php` - `app/Filament/Widgets/Inventory/InventoryKpiHeader.php` - `app/Filament/Resources/PolicyResource.php` - `app/Filament/Resources/BackupScheduleResource.php` - `app/Filament/Resources/InventoryItemResource.php` - `app/Filament/Resources/PolicyVersionResource.php` - `app/Filament/Resources/ProviderConnectionResource.php` - `app/Filament/Resources/AlertDeliveryResource.php` - `app/Filament/Resources/AlertDeliveryResource/Pages/ListAlertDeliveries.php` - `app/Filament/Pages/Monitoring/AuditLog.php` - `app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php` ## Exception Inventory Approved tenant-panel-native or bootstrapping exceptions: - `app/Filament/Pages/ChooseTenant.php` - `app/Http/Controllers/SelectTenantController.php` - `app/Support/Middleware/EnsureFilamentTenantSelected.php` - `app/Filament/Concerns/ResolvesPanelTenantContext.php` `app/Filament/Concerns/ResolvesPanelTenantContext.php` is the only shared internal delegation wrapper allowed for this rollout. It is not a new public resolver. Admin semantics still come from `OperateHubShell`. ## Global Search - `PolicyResource`: global search disabled explicitly. - `PolicyVersionResource`: global search disabled explicitly. - `EntraGroupResource`: global search remains enabled and uses admin-aware scoping with a View page. ## Future-Surface Rule Any new admin-visible or admin-reachable tenant-sensitive Filament surface must: - resolve workspace-admin tenant context through `OperateHubShell` or the internal `ResolvesPanelTenantContext` helper - route tenant-owned list/detail resolution through the shared `InteractsWithTenantOwnedRecords` helper where the surface is tenant-owned - keep tenant-panel requests panel-native - synchronize persisted tenant-derived filters before render when `persistFiltersInSession()` is used - disable global search unless list, detail, and search parity are explicitly tenant-safe - keep destructive actions on `->action(...)` with `->requiresConfirmation()` and server-side authorization ## Verification Log ### Wave 1 - 2026-03-11: automated parity coverage added for representative tenant-sensitive resources and admin list scoping. - 2026-03-12: manual tenant-switch verification completed on `/admin/findings` with `Phoenicon (DEV)` and `YPTW2 (DEV)`. - 2026-03-12: the admin shell changed visible finding rows and row-action tenant IDs together after switching tenants, confirming header context, list queries, and deep links stayed aligned. ### Wave 2 - 2026-03-11: automated stale-filter and tenant-default coverage added for persisted filter surfaces. - 2026-03-12: manual verification completed on `/admin/inventory/inventory-coverage` after fixing remembered-canonical-tenant handling in `EnsureFilamentTenantSelected`. - 2026-03-12: switching from `YPTW2 (DEV)` to `Phoenicon (DEV)` changed tenant-driven KPI values while the shared support-matrix table remained available, confirming page-widget parity and the expected safe no-data state. - 2026-03-12: tenant-panel navigation under `/admin/t/{tenant}/...` remained route-bound and required explicit tenant switching through the chooser flow instead of reusing remembered admin context. ### Wave 3 - 2026-03-11: guard inventory and shared-surface panel-split coverage updated for the canonical rollout. - 2026-03-12: manual verification completed on `/admin/provider-connections` and confirmed the base dataset stays workspace-wide while the default tenant filter follows the active canonical admin tenant. - 2026-03-12: clearing the tenant filter exposed workspace-wide provider connections, while switching back to another tenant reseeded the tenant-default pill and `tenant_id` deep links for the newly selected tenant. - 2026-03-12: admin search safety remained unchanged from the rollout contract: `PolicyResource` and `PolicyVersionResource` stay disabled for global search, and `EntraGroupResource` keeps admin-aware global search with a View page.