# Tasks: Central Tenant Operability Policy **Input**: Design documents from `/specs/148-central-tenant-operability-policy/` **Prerequisites**: `plan.md` (required), `spec.md` (required for user stories), `research.md`, `data-model.md`, `contracts/`, `quickstart.md` **Tests**: Runtime behavior changes in this repo require Pest coverage. This feature changes runtime behavior across selector, shell, tenant-management, onboarding, and canonical-view surfaces, so tests are required for every user story. **Operations**: This feature does not introduce new long-running, remote, queued, or scheduled work. No new `OperationRun` creation or lifecycle changes are required. **RBAC**: This feature changes authorization-adjacent tenant semantics in the admin `/admin` plane. Tasks below preserve `404` for non-members or non-entitled actors and `403` for in-scope capability denial, require canonical capability-registry usage, and include positive and negative authorization regression coverage. **UI Naming**: Operability copy and action labels must preserve the distinction between `selected tenant`, `route tenant`, `run tenant`, `Archive`, `Restore`, and `Resume onboarding`, with no implementation-first wording in primary UI copy. **Filament UI Action Surfaces**: This feature modifies existing Filament resources and pages. Tasks below keep existing header, row, bulk, and empty-state inventories intact while moving their decision authority to the central operability layer. Destructive actions remain `->action(...)->requiresConfirmation()`. **Filament UI UX-001**: This feature is not a layout redesign. Tasks below keep existing layouts intact while hardening action visibility, discoverability, and mismatch messaging inside current screens. **Badges**: Existing centralized lifecycle presentation from Spec 146 must remain in use anywhere lifecycle or selector availability is shown. **Contract Artifact**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/148-central-tenant-operability-policy/contracts/tenant-operability-policy.openapi.yaml` is an internal design contract for the operability boundary and route semantics, not a requirement to add new public controller endpoints. **Organization**: Tasks are grouped by user story so each story can be implemented and tested independently. ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Prepare the regression targets and implementation touchpoints for central operability work. - [X] T001 [P] Create or extend the central operability unit test targets in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityServiceTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityOutcomeTest.php` - [X] T002 [P] Create or extend selector and remembered-context feature regression targets in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Workspaces/ChooseTenantPageTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Workspaces/SelectTenantControllerTest.php` - [X] T003 [P] Create or extend tenant-bound and canonical route regression targets in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Operations/TenantlessOperationRunViewerTest.php` - [X] T004 [P] Create or extend lifecycle-action and discoverability regression targets in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php` --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Build the central operability boundary that all user stories depend on. **⚠️ CRITICAL**: No user story work should begin until this phase is complete. - [X] T005 Create the new lane-aware support types in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantInteractionLane.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantOperabilityQuestion.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantOperabilityReasonCode.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantOperabilityContext.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantOperabilityOutcome.php` - [X] T006 Refactor `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantOperabilityDecision.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantLifecycle.php` to expose structured operability helpers and backward-compatible adapters for existing consumers - [X] T007 Implement the actor-aware, lane-aware central evaluation flow in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Tenants/TenantOperabilityService.php` - [X] T008 [P] Centralize remembered-context validation and page-category to lane mapping in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Workspaces/WorkspaceContext.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantPageCategory.php` - [X] T009 [P] Add foundational unit coverage for structured operability outcomes, reason codes, and lifecycle-lane combinations in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityServiceTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityOutcomeTest.php` **Checkpoint**: Foundation ready. The repo has one central operability boundary, and user stories can now adopt it independently. --- ## Phase 3: User Story 1 - Get One Authoritative Tenant Decision (Priority: P1) 🎯 MVP **Goal**: Make the product answer the same tenant-semantic question the same way across selectors, action surfaces, tenant pages, and onboarding-linked surfaces. **Independent Test**: Prepare `draft`, `onboarding`, `active`, and `archived` tenants and verify that selector eligibility, archive or restore availability, onboarding resume availability, and tenant-management visibility all resolve from the same central policy source. ### Tests for User Story 1 - [X] T010 [P] [US1] Add selector and lifecycle-action consistency coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Workspaces/ChooseTenantPageTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php` - [X] T011 [P] [US1] Add onboarding-versus-admin consistency coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php` - [X] T012 [P] [US1] Add capability-positive and capability-negative action-resolution coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantResourceAuthorizationTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php` ### Implementation for User Story 1 - [X] T013 [US1] Refactor `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/ChooseTenant.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Http/Controllers/SelectTenantController.php` to consume central selector and remembered-context operability outcomes - [X] T014 [US1] Refactor `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Tenants/TenantActionPolicySurface.php` to resolve archive, restore, resume-onboarding, and related discoverability decisions from the new operability boundary - [X] T015 [US1] Refactor `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource/Pages/ViewTenant.php` to use the same central answers for row actions, header actions, and administrative visibility - [X] T016 [US1] Align onboarding workflow consumers with the same operability questions in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Policies/TenantOnboardingSessionPolicy.php` **Checkpoint**: User Story 1 is complete when the same tenant-semantic question returns the same answer across selector, admin, and onboarding surfaces. --- ## Phase 4: User Story 2 - Keep Valid Records Viewable Without False Tenant Context Gates (Priority: P2) **Goal**: Preserve route-authoritative behavior for tenant-bound pages and canonical workspace viewers even when selected tenant context differs, is stale, or is empty. **Independent Test**: Open authorized `/admin/tenants/{tenant}` and `/admin/operations/{run}` routes with mismatched, stale, or empty selected tenant state and verify the pages still resolve while non-member and non-entitled cases remain `404`. ### Tests for User Story 2 - [X] T017 [P] [US2] Add tenant-bound route-authority and deny-as-not-found coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php` - [X] T018 [P] [US2] Add canonical viewer mismatch, empty-context, entitlement, and capability coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Operations/TenantlessOperationRunViewerTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/OpsUx/OperateHubShellTest.php` ### Implementation for User Story 2 - [X] T019 [US2] Refine `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/OperateHub/OperateHubShell.php` to ask the central operability boundary for tenant-bound, canonical-view, and administrative-lane decisions instead of reusing selector booleans - [X] T020 [US2] Remove selector-lane assumptions from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Middleware/EnsureFilamentTenantSelected.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/routes/web.php` so route legitimacy is driven by route subject plus policy - [X] T021 [US2] Update canonical run follow-up affordance gating and mismatch messaging in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/resources/views/filament/pages/operations/tenantless-operation-run-viewer.blade.php` - [X] T022 [US2] Align tenant-bound admin page context resolution with route-authoritative operability checks in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Concerns/ResolvesPanelTenantContext.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource/Pages/ViewTenant.php` **Checkpoint**: User Story 2 is complete when tenant-bound and canonical routes stay valid because the route subject is valid, not because selected tenant state matches. --- ## Phase 5: User Story 3 - Show Only Lifecycle-Safe Actions And Selections (Priority: P3) **Goal**: Separate standard selector eligibility from administrative discoverability and keep lifecycle-safe selections and actions honest across surfaces. **Independent Test**: Prepare tenants in each lifecycle state and verify that only active tenants are selectable in the standard selector, that non-active tenants remain administratively discoverable where intended, that tenant global search follows administrative discoverability rather than selector eligibility, and that archive, restore, resume-onboarding, and readiness affordances remain lifecycle-safe with capability-aware denials. ### Tests for User Story 3 - [X] T023 [P] [US3] Add selector-versus-discoverability regression coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php` - [X] T024 [P] [US3] Add capability-denied versus lifecycle-denied regression coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantResourceAuthorizationTest.php` - [X] T025 [P] [US3] Add tenant global-search, administrative-discoverability, onboarding-completion, and readiness-or-verification-affordance regression coverage in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/TenantResourceGlobalSearchTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php` ### Implementation for User Story 3 - [X] T026 [US3] Separate selector eligibility from administrative discoverability in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Tenants/TenantOperabilityService.php` - [X] T027 [US3] Update remembered-context invalidation and explicit clear flows in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Workspaces/WorkspaceContext.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Http/Controllers/ClearTenantContextController.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Http/Controllers/SelectTenantController.php` - [X] T028 [US3] Normalize lifecycle-safe action, onboarding-completion, and readiness-or-verification affordances in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Tenants/TenantActionPolicySurface.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource/Pages/EditTenant.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource/Pages/ListTenants.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` - [X] T029 [US3] Align selector and discoverability copy with central operability reasons in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/resources/views/filament/pages/choose-tenant.blade.php` and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/resources/views/filament/partials/context-bar.blade.php` **Checkpoint**: User Story 3 is complete when active-lane selection, administrative discoverability, and lifecycle-safe action availability no longer contradict each other. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Finalize regression coverage, formatting, and manual validation across all stories. - [X] T030 [P] Run the focused Pest suites from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/148-central-tenant-operability-policy/quickstart.md` covering `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityServiceTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityOutcomeTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Workspaces/ChooseTenantPageTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Workspaces/SelectTenantControllerTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Operations/TenantlessOperationRunViewerTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/OpsUx/OperateHubShellTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantResourceAuthorizationTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/TenantResourceGlobalSearchTest.php`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php`, and `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php` - [X] T031 Run formatting for touched files with `vendor/bin/sail bin pint --dirty --format agent` - [X] T032 [P] Validate the manual smoke checklist in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/148-central-tenant-operability-policy/quickstart.md` against `/admin/choose-tenant`, `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/admin/tenants`, `/admin/onboarding`, `/admin/onboarding/{onboardingDraft}`, and `/admin/operations/{run}` --- ## Dependencies & Execution Order ### Phase Dependencies - **Phase 1: Setup** has no dependencies and can start immediately. - **Phase 2: Foundational** depends on Phase 1 and blocks all user story work. - **Phase 3: User Story 1** depends on Phase 2 and delivers the MVP. - **Phase 4: User Story 2** depends on Phase 2 and is safest after User Story 1 because it reuses the same central operability boundary on route-authoritative surfaces. - **Phase 5: User Story 3** depends on Phase 2 and benefits from User Story 1’s shared action and selector adoption. - **Phase 6: Polish** depends on all desired user stories being complete. ### User Story Dependencies - **User Story 1 (P1)** can start immediately after the foundational phase and is the MVP slice. - **User Story 2 (P2)** depends on the foundational phase and reuses the operability boundary stabilized in User Story 1. - **User Story 3 (P3)** depends on the foundational phase and benefits from the selector and action adoption work from User Story 1. ### Within Each User Story - Write or extend tests first and confirm they fail before implementation. - Shared support-layer changes land before surface refactors. - Route and middleware behavior should stabilize before final copy or mismatch-messaging adjustments. - Story-level regression coverage should pass before moving to the next priority story. ### Parallel Opportunities - `T001`, `T002`, `T003`, and `T004` can run in parallel because they prepare separate regression targets. - `T008` and `T009` can run in parallel after `T005`, `T006`, and `T007` define the shared operability model. - `T010`, `T011`, and `T012` can run in parallel within User Story 1. - `T017` and `T018` can run in parallel within User Story 2. - `T023`, `T024`, and `T025` can run in parallel within User Story 3. - `T030` and `T032` can run in parallel after implementation is complete. --- ## Parallel Example: User Story 1 ```bash # Run the P1 regression additions together: Task: "Add selector and lifecycle-action consistency coverage in tests/Feature/Workspaces/ChooseTenantPageTest.php and tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php" Task: "Add onboarding-versus-admin consistency coverage in tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php and tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php" Task: "Add capability-positive and capability-negative action-resolution coverage in tests/Feature/Rbac/TenantResourceAuthorizationTest.php and tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php" ``` ## Parallel Example: User Story 2 ```bash # Split route-authority coverage by surface type: Task: "Add tenant-bound route-authority and deny-as-not-found coverage in tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php and tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php" Task: "Add canonical viewer mismatch, empty-context, entitlement, and capability coverage in tests/Feature/Operations/TenantlessOperationRunViewerTest.php and tests/Feature/OpsUx/OperateHubShellTest.php" ``` ## Parallel Example: User Story 3 ```bash # Split selector/discoverability and denial-reason coverage: Task: "Add selector-versus-discoverability regression coverage in tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php and tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php" Task: "Add capability-denied versus lifecycle-denied regression coverage in tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php and tests/Feature/Rbac/TenantResourceAuthorizationTest.php" Task: "Add tenant global-search, administrative-discoverability, onboarding-completion, and readiness-or-verification-affordance regression coverage in tests/Feature/Filament/TenantResourceGlobalSearchTest.php, tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php, and tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php" ``` --- ## Implementation Strategy ### MVP First 1. Complete Phase 1: Setup. 2. Complete Phase 2: Foundational. 3. Complete Phase 3: User Story 1. 4. **Stop and validate** that selector, action, and onboarding consumers now resolve the same tenant-semantic questions centrally. ### Incremental Delivery 1. Deliver User Story 1 to establish one authoritative operability answer across the highest-risk surfaces. 2. Deliver User Story 2 to harden route-authoritative tenant-bound and canonical viewers. 3. Deliver User Story 3 to eliminate selector-versus-discoverability drift and finalize lifecycle-safe visibility. 4. Finish with Phase 6 regression and manual validation. ### Team Strategy 1. One engineer owns the foundational support-layer work in `app/Support/Tenants`, `app/Services/Tenants`, and `app/Support/Workspaces`. 2. A second engineer can prepare the User Story 1 regression coverage in parallel once the support-layer contracts are clear. 3. Route-authority hardening for canonical and tenant-bound pages can proceed as a separate stream after the foundation lands. --- ## Notes - `[P]` tasks touch separate files and can be executed in parallel. - Each user story remains independently testable after the foundational phase. - This feature does not add schema changes, Graph calls, new assets, or new operations workflows. - Keep route legitimacy tied to route subject plus authorization, never to raw remembered tenant session state.