18 KiB
Tasks: Canonical Tenant Context Resolution
Input: Design documents from /specs/135-canonical-tenant-context-resolution/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/context-resolution-matrix.yaml, quickstart.md
Tests: Tests are REQUIRED for this feature because it changes runtime behavior across existing Filament admin flows, filter persistence, direct-record access, and search safety.
Phase 1: Setup (Shared Infrastructure)
Purpose: Create the focused documentation and regression entry points used by the implementation slices.
- T001 Create the focused regression test entry points in
tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php,tests/Feature/Filament/EntraGroupAdminScopeTest.php,tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php, andtests/Feature/Guards/AdminTenantResolverGuardTest.php - T002 Create the durable architecture note and residual admin call-site inventory entry point in
docs/research/canonical-tenant-context-resolution.md - T003 [P] Align the verification references in
specs/135-canonical-tenant-context-resolution/quickstart.mdandspecs/135-canonical-tenant-context-resolution/contracts/context-resolution-matrix.yamlwith the final implementation slices
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Lock in the single public admin resolver rule, explicit per-surface no-context behavior, shared context display, and reusable admin reference pattern before story-specific remediation begins.
⚠️ CRITICAL: No user story work can begin until this phase is complete.
- T004 Define
app/Support/OperateHub/OperateHubShell.php::activeEntitledTenant(request())as the only public admin resolver, keep any helpers internal-only, and codify Filament-wins conflict precedence plus explicit no-context outcomes inapp/Support/OperateHub/OperateHubShell.phpandapp/Support/Workspaces/WorkspaceContext.php - T005 [P] Add remembered-only, Filament-only, conflict, and no-context resolver coverage in
tests/Feature/OpsUx/OperateHubShellTest.php - T006 [P] Align shared admin context display with the canonical resolver in
resources/views/filament/partials/context-bar.blade.phpandtests/Feature/Monitoring/HeaderContextBarTest.php - T007 [P] Document the admin-versus-tenant panel rule, exact no-context outcomes per in-scope surface, approved exception inventory, and residual admin call-site inventory in
docs/research/canonical-tenant-context-resolution.md - T008 Preserve
app/Filament/Resources/AlertDeliveryResource.phpandapp/Filament/Resources/AlertDeliveryResource/Pages/ListAlertDeliveries.phpas the non-regression admin reference pattern, extracting only the smallest reusable filter-persistence helper if a minimal extraction is necessary
Checkpoint: The canonical rule, shared resolver behavior, and reusable admin reference pattern are ready; user-story work can now begin.
Phase 3: User Story 1 - Trust The Visible Tenant Context (Priority: P1) 🎯 MVP
Goal: Make the workspace-admin operations shell, KPI widget, and related detail affordances resolve one tenant context per request.
Independent Test: Load the operations monitoring flow under remembered-only, Filament-only, conflict, and no-context request states and verify that the header, KPIs, table scope, and run-detail affordances all resolve the same tenant or the same safe bounded outcome.
Tests for User Story 1
- T009 [P] [US1] Extend operations-shell parity coverage in
tests/Feature/Spec085/OperationsIndexHeaderTest.phpandtests/Feature/Monitoring/OperationsTenantScopeTest.php, including the explicit workspace-scopedAll tenantsno-context state - T010 [P] [US1] Add KPI tenant-context coverage in
tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.phpandtests/Feature/078/KpiHeaderTenantlessTest.php - T011 [P] [US1] Extend run-detail context-affordance and authorization coverage in
tests/Feature/Spec085/RunDetailBackAffordanceTest.phpandtests/Feature/Monitoring/OperationsCanonicalUrlsTest.php, including positive access plus404for out-of-scope tenant-bound runs
Implementation for User Story 1
- T012 [US1] Update
app/Filament/Widgets/Operations/OperationsKpiHeader.phpto resolve tenant context only throughapp/Support/OperateHub/OperateHubShell.phpand keep polling safe when no canonical tenant exists - T013 [US1] Update
app/Filament/Pages/Monitoring/Operations.phpso header actions, scope labels, tab queries, table filter state, and the no-contextAll tenantsview all use the same canonical admin tenant contract - T014 [US1] Update
app/Filament/Pages/Operations/TenantlessOperationRunViewer.phpandapp/Filament/Resources/OperationRunResource.phpso run-detail affordances stay aligned with the canonical operations context and enforce the documented no-context detail rule
Checkpoint: User Story 1 is complete when the operations monitoring shell and its KPI widget no longer drift from each other across all four request states.
Phase 4: User Story 2 - Use Filters And Detail Links Safely (Priority: P1)
Goal: Keep tenant-sensitive filters, persisted filter state, direct record access, and global-search entry points within the same scope contract as the visible list.
Independent Test: Use the operations and Entra group flows from list pages, persisted filters, direct URLs, and search entry points while switching tenant context between requests, and verify that filters, records, and search results never exceed the current canonical scope.
Tests for User Story 2
- T015 [P] [US2] Add OperationRun filter default, filter-option, persisted-state, and positive or negative admin detail-authorization coverage in
tests/Feature/Filament/OperationRunListFiltersTest.phpandtests/Feature/Monitoring/OperationsCanonicalUrlsTest.php - T016 [P] [US2] Add Entra group admin list and detail scope coverage plus explicit
404versus403authorization coverage intests/Feature/Filament/EntraGroupAdminScopeTest.phpandtests/Feature/Filament/EntraGroupEnterpriseDetailPageTest.php - T017 [P] [US2] Add Entra group global-search parity coverage and non-member-safe no-result coverage in
tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.phpandtests/Feature/Filament/EntraGroupResolvedReferencePresentationTest.php
Implementation for User Story 2
- T018 [US2] Harden tenant-sensitive filter defaults, option builders, and workspace-bounded list queries in
app/Filament/Resources/OperationRunResource.php - T019 [US2] Apply the alert-delivery persisted-filter seeding pattern from
app/Filament/Resources/AlertDeliveryResource.phpandapp/Filament/Resources/AlertDeliveryResource/Pages/ListAlertDeliveries.phptoapp/Filament/Pages/Monitoring/Operations.phpandapp/Filament/Resources/OperationRunResource.php - T020 [US2] Align tenantless operation-run detail authorization and deep-link behavior in
app/Filament/Pages/Operations/TenantlessOperationRunViewer.phpandapp/Filament/Resources/OperationRunResource.php, using404for out-of-scope tenant-bound records and no broader no-context lookup path - T021 [US2] Harden admin list, direct-record, and view scoping in
app/Filament/Resources/EntraGroupResource.php,app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php, andapp/Filament/Resources/EntraGroupResource/Pages/ViewEntraGroup.php, with deny-as-not-found as the explicit admin no-context outcome - T022 [US2] Make Entra group global search tenant-safe or explicitly disable it in
app/Filament/Resources/EntraGroupResource.phpandapp/Filament/Concerns/ScopesGlobalSearchToTenant.php, returning no tenant-owned admin search results when no canonical admin tenant exists - T023 [US2] Preserve canonical related links after Entra group scope hardening in
app/Support/References/Resolvers/EntraGroupReferenceResolver.phpandapp/Support/OperationRunLinks.php
Checkpoint: User Story 2 is complete when OperationRun and Entra group list, detail, filter, and search paths all obey one bounded scope contract.
Phase 5: User Story 3 - Preserve Separate Panel Semantics (Priority: P2)
Goal: Keep tenant-panel-native behavior intact while enforcing the canonical admin resolver only in workspace-admin flows.
Independent Test: Verify that tenant-panel files continue to use panel-native tenant behavior while admin-panel flows use the canonical admin resolver, with no cross-plane mutation or hidden fallback semantics.
Tests for User Story 3
- T024 [P] [US3] Add panel-semantics non-regression coverage in
tests/Feature/Monitoring/HeaderContextBarTest.php,tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php, andtests/Feature/OpsUx/OperateHubShellTest.php
Implementation for User Story 3
- T025 [US3] Preserve tenant-panel-native selection and remember-last-tenant flows in
app/Filament/Pages/ChooseTenant.php,app/Http/Controllers/SelectTenantController.php, andapp/Support/Middleware/EnsureFilamentTenantSelected.php - T026 [US3] Preserve panel-aware Entra group navigation semantics in
app/Support/References/Resolvers/EntraGroupReferenceResolver.phpandapp/Support/OperationRunLinks.php - T027 [US3] Keep tenant-panel global-search and record-resolution semantics explicit while admin paths stay canonical in
app/Filament/Concerns/ScopesGlobalSearchToTenant.phpandapp/Filament/Resources/EntraGroupResource.php
Checkpoint: User Story 3 is complete when admin hardening no longer risks changing legitimate tenant-panel semantics.
Phase 6: User Story 4 - Prevent Regressions Cheaply (Priority: P3)
Goal: Add a lightweight architectural guard and a focused non-regression suite so new admin-panel code cannot quietly reintroduce raw tenant-panel-native tenant reads.
Independent Test: Run the new architecture guard plus the focused alert-delivery and operations regression suite and verify that disallowed admin-panel raw tenant reads fail with actionable output while approved tenant-panel exceptions stay allowed.
Tests for User Story 4
- T028 [P] [US4] Implement the raw admin-tenant-read guard in
tests/Feature/Guards/AdminTenantResolverGuardTest.phpforapp/Filament/Pages/Monitoring,app/Filament/Pages/Operations,app/Filament/Resources, andapp/Filament/Widgets/Operations - T029 [P] [US4] Add non-regression coverage for the alert-delivery reference pattern in
tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.phpandtests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php
Implementation for User Story 4
- T030 [US4] Maintain the executable allowlist and reviewer-facing exception notes in
tests/Feature/Guards/AdminTenantResolverGuardTest.phpso it stays aligned with the documented exception inventory
Checkpoint: User Story 4 is complete when new disallowed admin-panel tenant reads fail CI cheaply and the approved exception set stays explicit.
Phase 7: Polish & Cross-Cutting Concerns
Purpose: Finalize wording, run the focused verification pack, and format touched files.
- T031 [P] Reconcile operator-facing scope-label and safe-state copy in
app/Support/OperateHub/OperateHubShell.php,app/Filament/Pages/Monitoring/Operations.php, andresources/views/filament/partials/context-bar.blade.php - T032 Run the focused validation commands documented in
specs/135-canonical-tenant-context-resolution/quickstart.md - T033 Run formatting on touched files with
vendor/bin/sail bin pint --dirty --format agentfrom/Users/ahmeddarrazi/Documents/projects/TenantAtlas
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies; can start immediately.
- Foundational (Phase 2): Depends on Setup completion; blocks all user-story implementation.
- User Stories (Phases 3-6): Depend on Foundational completion.
- Polish (Phase 7): Depends on the desired user stories being complete.
User Story Dependencies
- User Story 1 (P1): Starts after Foundational and delivers the MVP by aligning the operations monitoring shell and KPI widget.
- User Story 2 (P1): Starts after Foundational and can run in parallel with US1, but it should land after T004-T008 so it reuses the canonical resolver and alert-delivery reference pattern.
- User Story 3 (P2): Starts after Foundational and should land before release so tenant-panel semantics remain explicitly protected.
- User Story 4 (P3): Depends on the in-scope remediation work from US1-US3 so the final guardrail can reflect the intended allowlist and forbidden admin paths.
Within Each User Story
- Write or update the story tests first and confirm they fail against pre-change behavior.
- Land shared resolver and scoping logic before adjusting page or resource affordances that consume it.
- Keep list, detail, deep-link, and global-search behavior aligned before closing the story.
- Finish story-level validation before moving to the next priority.
Parallel Opportunities
- T003 can run in parallel with T001-T002 once the feature directory exists.
- T005-T007 can run in parallel after T004, while T008 completes the reusable admin reference pattern.
- In US1, T009-T011 can run in parallel before T012-T014.
- In US2, T015-T017 can run in parallel before T018-T023.
- In US3, T024 can run before T025-T027, and T026 can run in parallel with T025 once the test expectations are fixed.
- In US4, T028 and T029 can run in parallel before T030.
- T031 can run in parallel with T032 after the story phases are complete.
Parallel Example: User Story 1
# Launch the US1 regression updates together:
Task: "Extend operations-shell parity coverage in tests/Feature/Spec085/OperationsIndexHeaderTest.php and tests/Feature/Monitoring/OperationsTenantScopeTest.php"
Task: "Add KPI tenant-context coverage in tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php and tests/Feature/078/KpiHeaderTenantlessTest.php"
Task: "Extend run-detail context-affordance coverage in tests/Feature/Spec085/RunDetailBackAffordanceTest.php and tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php"
Parallel Example: User Story 2
# Launch the US2 regression updates together:
Task: "Add OperationRun filter default, filter-option, and persisted-state coverage in tests/Feature/Filament/OperationRunListFiltersTest.php and tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php"
Task: "Add Entra group admin list and detail scope coverage in tests/Feature/Filament/EntraGroupAdminScopeTest.php and tests/Feature/Filament/EntraGroupEnterpriseDetailPageTest.php"
Task: "Add Entra group global-search parity coverage in tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php and tests/Feature/Filament/EntraGroupResolvedReferencePresentationTest.php"
Parallel Example: User Story 3
# Launch the US3 protection work together:
Task: "Add panel-semantics non-regression coverage in tests/Feature/Monitoring/HeaderContextBarTest.php, tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php, and tests/Feature/OpsUx/OperateHubShellTest.php"
Task: "Preserve tenant-panel-native selection and remember-last-tenant flows in app/Filament/Pages/ChooseTenant.php, app/Http/Controllers/SelectTenantController.php, and app/Support/Middleware/EnsureFilamentTenantSelected.php"
Task: "Preserve panel-aware Entra group navigation semantics in app/Support/References/Resolvers/EntraGroupReferenceResolver.php and app/Support/OperationRunLinks.php"
Parallel Example: User Story 4
# Launch the US4 guardrail work together:
Task: "Implement the raw admin-tenant-read guard in tests/Feature/Guards/AdminTenantResolverGuardTest.php for app/Filament/Pages/Monitoring, app/Filament/Pages/Operations, app/Filament/Resources, and app/Filament/Widgets/Operations"
Task: "Add non-regression coverage for the alert-delivery reference pattern in tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php and tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php"
Implementation Strategy
MVP First (User Story 1 Only)
- Complete Phase 1: Setup.
- Complete Phase 2: Foundational.
- Complete Phase 3: User Story 1.
- Validate the operations monitoring shell across remembered-only, Filament-only, conflict, and no-context states before moving on.
Incremental Delivery
- Finish Setup and Foundational shared resolver work.
- Deliver User Story 1 to establish canonical operations context parity.
- Deliver User Story 2 to harden filters, persisted state, direct record access, and global search.
- Deliver User Story 3 to preserve tenant-panel semantics while admin behavior is tightened.
- Deliver User Story 4 to lock in the lightweight guardrail.
- Finish with wording cleanup, focused validation, and formatting.
Parallel Team Strategy
- One contributor handles the support-layer resolver contract and shared context-bar behavior while another prepares the new regression files.
- After Foundation is ready, split US1 and US2 between monitoring-shell parity and resource-scope hardening.
- Reserve one contributor for tenant-panel non-regression and the guardrail so the exception inventory stays coherent while implementation lands.
Notes
[P]tasks touch different files and can be executed in parallel.- User-story labels map directly to the prioritized stories in
spec.md. - Tests are mandatory in this repo for every runtime change in the resulting implementation.
- The suggested MVP scope is Phase 3 only after Setup and Foundational are complete.