version: 1 feature: 135-canonical-tenant-context-resolution title: Canonical Tenant Context Resolution Matrix type: internal-behavior-contract canonical_rules: tenant_panel: source_of_truth: Filament::getTenant() fallback_behavior: none notes: - Tenant-panel-native routes keep panel semantics. - Remembered admin tenant state must not override tenant-panel context. workspace_admin: source_of_truth: App\Support\OperateHub\OperateHubShell::activeEntitledTenant priority_order: - entitled_filament_tenant - entitled_remembered_workspace_tenant - none no_context_outcome_by_surface: operations_monitoring_index: workspace_scoped_all_tenants_state_with_no_tenant_default_filter_and_no_tenant_only_kpis tenantless_operation_run_detail: render_only_if_workspace_scope_and_tenant_entitlement_still_pass_otherwise_not_found admin_entra_group_list_and_view: not_found admin_entra_group_global_search: no_results_for_tenant_owned_records request_states: remembered_only: filament_tenant: null remembered_tenant: entitled resolved_source: remembered filament_only: filament_tenant: entitled remembered_tenant: null resolved_source: filament conflict: filament_tenant: entitled remembered_tenant: entitled_and_different resolved_source: filament no_context: filament_tenant: null_or_not_entitled remembered_tenant: null_or_not_entitled resolved_source: none surfaces: - name: operations_monitoring_index route: /admin/operations panel: admin expectations: - header_scope_label_matches_resolved_tenant - kpi_cards_match_resolved_tenant - table_query_matches_resolved_tenant - filter_defaults_match_resolved_tenant - no_context_renders_workspace_scoped_all_tenants_state - no_context_clears_tenant_default_filters - no_context_hides_tenant_only_kpi_behavior - name: tenantless_operation_run_detail route: /admin/operations/{run} panel: admin expectations: - authorization_uses_workspace_and_tenant_entitlement - detail_visibility_is_not_broader_than_index_scope - navigation_labels_use_same_resolved_tenant_as_admin_shell - no_context_renders_only_when_workspace_scope_and_tenant_entitlement_still_pass - no_context_otherwise_returns_not_found - name: operation_run_filters route: /admin/operations with persisted table filters panel: admin expectations: - tenant_filter_options_do_not_exceed_list_scope - tenant_filter_default_uses_resolved_tenant - persisted_tenant_sensitive_values_are_revalidated_per_request - name: entra_group_list_and_view route: /admin/.../groups and /admin/.../groups/{record} panel: mixed expectations: - tenant_panel_routes_use_panel_native_tenant - admin_sensitive_access_paths_use_explicit_scope_rule - direct_record_resolution_matches_list_scope - admin_no_context_returns_not_found - out_of_scope_access_returns_not_found - name: entra_group_global_search route: global-search panel: mixed expectations: - search_results_follow_same_scope_as_list_and_detail - non_members_receive_no_hints - admin_no_context_returns_no_tenant_owned_results - resource_search_is_disabled_if_scope_parity_cannot_be_guaranteed - name: alert_delivery_reference_pattern route: /admin/alert-deliveries panel: admin expectations: - existing_admin_query_and_filter_alignment_is_preserved - resource_remains_non_regression_reference authorization_contract: non_member_or_out_of_scope: response: not_found member_missing_capability: response: forbidden guardrail: purpose: prevent_new_admin_panel_raw_panel_native_tenant_reads forbidden_patterns: - Filament::getTenant() - Tenant::current() enforced_in: - app/Filament/Pages/Monitoring - app/Filament/Pages/Operations - app/Filament/Resources - app/Filament/Widgets/Operations allowed_exceptions: - app/Filament/Pages/ChooseTenant.php - app/Http/Controllers/SelectTenantController.php - app/Support/Middleware/EnsureFilamentTenantSelected.php - app/Filament/Resources/EntraGroupResource.php