TenantAtlas/specs/135-canonical-tenant-context-resolution/contracts/context-resolution-matrix.yaml
ahmido cc93329672 feat: canonical tenant context resolution (#164)
## Summary
- introduce a canonical admin tenant filter-state helper and route all in-scope workspace-admin tenant resolution through `OperateHubShell::activeEntitledTenant()`
- align operations monitoring, operation-run deep links, Entra group admin list/view/search behavior, and shared context-bar rendering with the documented scope contract
- add the Spec 135 design artifacts, architecture note, focused guardrail coverage, and non-regression tests for filter persistence, direct-record access, and global search safety

## Validation
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php tests/Feature/Spec085/OperationsIndexHeaderTest.php tests/Feature/Spec085/RunDetailBackAffordanceTest.php tests/Feature/Filament/OperationRunListFiltersTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/DirectoryGroups/BrowseGroupsTest.php tests/Feature/Filament/EntraGroupEnterpriseDetailPageTest.php tests/Feature/Filament/PolicyVersionResolvedReferenceLinksTest.php tests/Feature/Filament/EntraGroupResolvedReferencePresentationTest.php tests/Feature/Guards/AdminTenantResolverGuardTest.php tests/Feature/OpsUx/OperateHubShellTest.php tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/TableStatePersistenceTest.php tests/Feature/Filament/TenantScopingTest.php tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php tests/Unit/Support/References/CapabilityAwareReferenceResolverTest.php`

## Notes
- Filament v5 remains on Livewire v4.0+ compliant surfaces only.
- No provider registration changes were needed; Laravel 12 provider registration remains in `bootstrap/providers.php`.
- Entra group global search remains enabled and is now scoped to the canonical admin tenant contract.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #164
2026-03-11 21:24:28 +00:00

121 lines
4.2 KiB
YAML

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