TenantAtlas/specs/216-provider-dispatch-gate/tasks.md
ahmido a089350f98
Some checks failed
Main Confidence / confidence (push) Failing after 49s
feat: unify provider-backed action dispatch gating (#255)
## Summary
- unify provider-backed action starts behind the shared provider dispatch gate and shared start-result presenter
- align tenant, onboarding, provider-connection, restore, directory, and monitoring surfaces with the same blocked, deduped, scope-busy, and accepted semantics
- include the spec kit artifacts for spec 216 and the regression fixes that brought the full suite back to green

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RestoreRunIdempotencyTest.php tests/Feature/ExecuteRestoreRunJobTest.php tests/Feature/Restore/RestoreRunProviderStartTest.php tests/Feature/Hardening/ExecuteRestoreRunJobGateTest.php tests/Feature/Hardening/BlockedWriteAuditLogTest.php tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec177InventoryCoverageTruthSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact`

## Notes
- branch: `216-provider-dispatch-gate`
- commit: `34230be7`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #255
2026-04-20 06:52:38 +00:00

242 lines
21 KiB
Markdown

# Tasks: Provider-Backed Action Preflight and Dispatch Gate Unification
**Input**: Design documents from `/specs/216-provider-dispatch-gate/`
**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 keeps proof in the `fast-feedback` and `confidence` lanes with one supporting unit seam and focused feature coverage on the existing Filament and Livewire action hosts.
## Phase 1: Setup (Shared Gate Scaffolding)
**Purpose**: Introduce the bounded shared testing and presentation seams needed before touching operator-facing start hosts.
- [x] T001 [P] Add failing unit coverage for newly covered operation types, explicit `provider_connection_id` binding, and onboarding bootstrap protected-scope admission in `apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php`
- [x] T002 [P] Add failing unit coverage for shared accepted, deduped, scope busy, and blocked presentation behavior in `apps/platform/tests/Unit/Providers/ProviderOperationStartResultPresenterTest.php`
- [x] T003 [P] Create the bounded shared presenter for provider-backed start outcomes in `apps/platform/app/Support/OpsUx/ProviderOperationStartResultPresenter.php`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Extend the canonical gate, reason translation, and shared Ops UX wiring that every user story depends on.
**Critical**: No user story work should begin until this phase is complete.
- [x] T004 Expand first-slice provider-backed operation definitions and dispatch callbacks in `apps/platform/app/Services/Providers/ProviderOperationRegistry.php`
- [x] T005 Update canonical gate and result plumbing for explicit `provider_connection_id`, protected-scope conflict handling, and blocked-start truth in `apps/platform/app/Services/Providers/ProviderOperationStartGate.php` and `apps/platform/app/Services/Providers/ProviderOperationStartResult.php`
- [x] T006 [P] Extend provider blocker translation and next-step mapping for the shared start contract in `apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php` and `apps/platform/app/Support/ReasonTranslation/ReasonPresenter.php`
- [x] T007 [P] Wire the shared presenter into existing toast and canonical run-link primitives in `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, `apps/platform/app/Support/OpsUx/ProviderOperationStartResultPresenter.php`, and `apps/platform/app/Support/OperationRunLinks.php`
- [x] T008 [P] Keep capability and alias-aware operation metadata aligned for the covered start types in `apps/platform/app/Support/Operations/OperationRunCapabilityResolver.php` and `apps/platform/app/Support/OperationCatalog.php`
**Checkpoint**: The canonical gate, presenter seam, and shared reason vocabulary are ready; user story work can now proceed.
---
## Phase 3: User Story 1 - Block Before Queue (Priority: P1)
**Goal**: Every covered operator-triggered provider-backed start resolves blocked, deduped, and scope busy outcomes before queue admission.
**Independent Test**: Trigger covered starts under missing-connection, unusable-access, same-operation active-run, and conflicting active-run conditions and verify the operator gets an immediate blocked, deduped, or scope busy result before any background work is accepted.
### Tests for User Story 1
- [x] T009 [P] [US1] Add covered tenant and provider-connection gate-admission coverage for blocked, deduped, scope busy, and accepted starts in `apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php` and `apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php`
- [x] T010 [P] [US1] Add restore and directory gate-admission coverage for explicit connection pinning and no-queue-on-block behavior in `apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php` and `apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php`
- [x] T011 [P] [US1] Add onboarding verification and bootstrap gate-admission coverage, including protected-scope serialization, in `apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php`
### Implementation for User Story 1
- [x] T012 [P] [US1] Migrate restore execute to canonical gate admission and explicit connection-aware queued execution in `apps/platform/app/Filament/Resources/RestoreRunResource.php` and `apps/platform/app/Jobs/ExecuteRestoreRunJob.php`
- [x] T013 [P] [US1] Migrate directory sync action hosts and queued jobs to canonical gate admission and explicit connection-aware execution in `apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php`, `apps/platform/app/Filament/Resources/TenantResource.php`, `apps/platform/app/Services/Directory/EntraGroupSyncService.php`, `apps/platform/app/Services/Directory/RoleDefinitionsSyncService.php`, `apps/platform/app/Jobs/EntraGroupSyncJob.php`, and `apps/platform/app/Jobs/SyncRoleDefinitionsJob.php`
- [x] T014 [P] [US1] Migrate onboarding bootstrap to canonical gate admission and sequential protected-scope execution in `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`
- [x] T015 [US1] Verify existing gated tenant and provider-connection starts keep explicit connection context and no-queue-on-block behavior in `apps/platform/app/Services/Verification/StartVerification.php`, `apps/platform/app/Filament/Resources/TenantResource.php`, `apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php`, and `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`
- [x] T016 [US1] Run the US1 focused verification flow documented in `specs/216-provider-dispatch-gate/quickstart.md`
**Checkpoint**: User Story 1 is independently deliverable as the core block-before-queue hardening slice.
---
## Phase 4: User Story 2 - Same Start Semantics on Every Covered Surface (Priority: P2)
**Goal**: Covered tenant, provider-connection, restore, directory, and onboarding surfaces use one shared public start vocabulary and next-step structure.
**Independent Test**: Trigger the same blocked and accepted scenarios from tenant surfaces, provider-connection surfaces, onboarding, restore, and directory starts and verify all of them render the same queued, already running, scope busy, and blocked wording with the same run-link and next-step pattern.
### Tests for User Story 2
- [x] T017 [P] [US2] Add cross-surface queued, already running, scope busy, and blocked vocabulary parity assertions for tenant and provider-connection hosts in `apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php` and `apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php`
- [x] T018 [P] [US2] Add onboarding, restore, and directory shared-language plus 404 and 403 assertions in `apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php`, `apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php`, `apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php`, `apps/platform/tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php`, and `apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php`
- [x] T019 [P] [US2] Update Filament action-surface contract coverage for the affected start hosts in `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`
### Implementation for User Story 2
- [x] T020 [US2] Replace tenant and provider-connection local start-result branching with the shared presenter and public queued or already running vocabulary in `apps/platform/app/Services/Verification/StartVerification.php`, `apps/platform/app/Filament/Resources/TenantResource.php`, `apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, and `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php`
- [x] T021 [P] [US2] Apply the shared presenter and safe continuation wording to onboarding verification and bootstrap surfaces in `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`
- [x] T022 [US2] Apply the shared presenter and aligned `Verb + Object` copy plus queued or already running wording to restore and directory start surfaces in `apps/platform/app/Filament/Resources/RestoreRunResource.php`, `apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php`, and `apps/platform/app/Filament/Resources/TenantResource.php`
- [x] T023 [US2] Run the US2 cross-surface verification flow documented in `specs/216-provider-dispatch-gate/quickstart.md`
**Checkpoint**: User Stories 1 and 2 both work independently, with start gating and operator copy fully aligned across the covered action hosts.
---
## Phase 5: User Story 3 - Keep Monitoring Truthful After Accepted Work (Priority: P3)
**Goal**: Accepted provider-backed work preserves the same translated problem and next-step direction in Monitoring and terminal notifications without turning prevented starts into ordinary execution failures.
**Independent Test**: Accept covered provider-backed work, let it finish in successful or failed terminal states, and verify canonical run detail and terminal notifications stay aligned with the start contract while blocked starts remain distinguishable from executed work.
### Tests for User Story 3
- [x] T024 [P] [US3] Add provider-backed run-detail reason-alignment, canonical view-run-link coverage, and scheduled or system-run shared-vocabulary compatibility assertions in `apps/platform/tests/Feature/Operations/ProviderBackedRunReasonAlignmentTest.php` and `apps/platform/tests/Feature/OpsUx/CanonicalViewRunLinksTest.php`
- [x] T025 [P] [US3] Add blocked-vs-executed monitoring truth, initiator-only no-queued-db-notification, and non-initiator compatibility assertions in `apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php`, `apps/platform/tests/Feature/OpsUx/Constitution/JobDbNotificationGuardTest.php`, and `apps/platform/tests/Feature/OpsUx/NoQueuedDbNotificationsTest.php`
### Implementation for User Story 3
- [x] T026 [P] [US3] Align terminal notification translation, initiator-only delivery, and canonical view-run actions with the shared start contract in `apps/platform/app/Notifications/OperationRunCompleted.php`, `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, and `apps/platform/app/Support/OperationRunLinks.php`
- [x] T027 [P] [US3] Align canonical Monitoring run detail with accepted provider-backed start semantics and scheduled or system-run shared reason reuse in `apps/platform/app/Filament/Resources/OperationRunResource.php` and `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`
- [x] T028 [P] [US3] Keep provider-backed jobs on service-owned lifecycle transitions and flat summary-count discipline in `apps/platform/app/Jobs/ExecuteRestoreRunJob.php`, `apps/platform/app/Jobs/EntraGroupSyncJob.php`, `apps/platform/app/Jobs/SyncRoleDefinitionsJob.php`, and `apps/platform/app/Services/OperationRunService.php`
- [x] T029 [US3] Run the US3 monitoring and notification verification flow documented in `specs/216-provider-dispatch-gate/quickstart.md`
**Checkpoint**: All user stories are independently functional and monitoring truth stays aligned with the accepted-start contract.
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Finalize lane metadata, contract notes, and close-out proof across all stories.
- [x] T030 [P] Add and register a route-bounded first-slice direct-dispatch bypass guard in `apps/platform/tests/Feature/Guards/ProviderDispatchGateCoverageTest.php`, `apps/platform/tests/Support/TestLaneManifest.php`, and `apps/platform/tests/Feature/Guards/TestLaneManifestTest.php`
- [x] T031 [P] Refresh the logical start contract and verification steps after implementation in `specs/216-provider-dispatch-gate/contracts/provider-dispatch-gate.logical.openapi.yaml` and `specs/216-provider-dispatch-gate/quickstart.md`
- [x] T032 Run formatting and the final focused Pest command set documented in `specs/216-provider-dispatch-gate/quickstart.md`
- [x] T033 Record the final lane outcome, route-bounded covered-surface audit, guardrail close-out, and `document-in-feature` test-governance disposition in `specs/216-provider-dispatch-gate/plan.md`
---
## Test Governance Checklist
- [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- [x] New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
- [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
- [x] Planned validation commands cover the change without pulling in unrelated lane cost.
- [x] The declared surface test profile or `standard-native-filament` relief is explicit.
- [x] Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies; can start immediately.
- **Foundational (Phase 2)**: Depends on Setup completion and blocks all user stories.
- **User Story 1 (Phase 3)**: Depends on Foundational completion.
- **User Story 2 (Phase 4)**: Depends on Foundational completion and should follow the stable gate adoption from User Story 1 on shared action hosts.
- **User Story 3 (Phase 5)**: Depends on Foundational completion and on the shared start vocabulary being stable enough for Monitoring parity.
- **Polish (Phase 6)**: Depends on all desired user stories being complete.
### User Story Dependencies
- **User Story 1 (P1)**: This is the MVP and should ship first.
- **User Story 2 (P2)**: Conceptually independent after Phase 2, but it reuses the shared presenter and touches some of the same action hosts stabilized in User Story 1.
- **User Story 3 (P3)**: Conceptually independent after Phase 2, but it must preserve parity with the accepted-start contract implemented by User Stories 1 and 2.
### Within Each User Story
- Tests should be written and fail before the corresponding implementation tasks.
- Shared gate and presenter changes must land before any surface-specific adoption task uses them.
- For shared files such as `apps/platform/app/Filament/Resources/TenantResource.php` and `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, serialize edits even when the surrounding story tasks are otherwise parallelizable.
- Finish each story's verification task before moving to the next priority when working sequentially.
### Parallel Opportunities
- **Setup**: `T001`, `T002`, and `T003` can run in parallel.
- **Foundational**: `T006`, `T007`, and `T008` can run in parallel after `T004` and `T005` settle the canonical gate contract.
- **US1 tests**: `T009`, `T010`, and `T011` can run in parallel.
- **US1 implementation**: `T012`, `T013`, and `T014` can run in parallel; `T015` should follow once the legacy-start migrations are in place.
- **US2 tests**: `T017`, `T018`, and `T019` can run in parallel.
- **US2 implementation**: `T021` can run in parallel with `T020` or `T022`, but `T020` and `T022` should serialize because both touch `apps/platform/app/Filament/Resources/TenantResource.php`.
- **US3**: `T024` and `T025` can run in parallel, and `T026`, `T027`, and `T028` can run in parallel once the test expectations are fixed.
- **Polish**: `T030` and `T031` can run in parallel before `T032` and `T033`.
---
## Parallel Example: User Story 1
```bash
# Run US1 coverage in parallel:
T009 apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php and apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php
T010 apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php and apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php
T011 apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php
# Then split the non-overlapping legacy start migrations:
T012 apps/platform/app/Filament/Resources/RestoreRunResource.php and apps/platform/app/Jobs/ExecuteRestoreRunJob.php
T013 apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php, apps/platform/app/Services/Directory/EntraGroupSyncService.php, apps/platform/app/Services/Directory/RoleDefinitionsSyncService.php, apps/platform/app/Jobs/EntraGroupSyncJob.php, and apps/platform/app/Jobs/SyncRoleDefinitionsJob.php
T014 apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
```
---
## Parallel Example: User Story 2
```bash
# Run US2 parity and contract assertions in parallel:
T017 apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php and apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php
T018 apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php, apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php, apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php, apps/platform/tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php, and apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php
T019 apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php
# Then split presenter adoption where files do not overlap:
T020 apps/platform/app/Services/Verification/StartVerification.php, apps/platform/app/Filament/Resources/TenantResource.php, apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php, apps/platform/app/Filament/Resources/ProviderConnectionResource.php, and apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php
T021 apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
```
---
## Parallel Example: User Story 3
```bash
# Run US3 monitoring and notification assertions in parallel:
T024 apps/platform/tests/Feature/Operations/ProviderBackedRunReasonAlignmentTest.php and apps/platform/tests/Feature/OpsUx/CanonicalViewRunLinksTest.php
T025 apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php, apps/platform/tests/Feature/OpsUx/Constitution/JobDbNotificationGuardTest.php, and apps/platform/tests/Feature/OpsUx/NoQueuedDbNotificationsTest.php
# Then split the non-overlapping Monitoring and notification implementation:
T026 apps/platform/app/Notifications/OperationRunCompleted.php, apps/platform/app/Support/OpsUx/OperationUxPresenter.php, and apps/platform/app/Support/OperationRunLinks.php
T027 apps/platform/app/Filament/Resources/OperationRunResource.php and apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
T028 apps/platform/app/Jobs/ExecuteRestoreRunJob.php, apps/platform/app/Jobs/EntraGroupSyncJob.php, apps/platform/app/Jobs/SyncRoleDefinitionsJob.php, and apps/platform/app/Services/OperationRunService.php
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup.
2. Complete Phase 2: Foundational.
3. Complete Phase 3: User Story 1.
4. Stop and validate with `T016`.
5. Demo or ship the block-before-queue hardening before layering shared copy and Monitoring parity on top.
### Incremental Delivery
1. Setup and Foundational establish the canonical gate, presenter seam, and shared blocker vocabulary.
2. Add User Story 1 and validate legacy start migration and protected-scope admission.
3. Add User Story 2 and validate cross-surface copy, next-step, and authorization consistency.
4. Add User Story 3 and validate Monitoring and terminal notification parity.
5. Finish with lane metadata, quickstart and contract refresh, formatting, and close-out proof.
### Parallel Team Strategy
With multiple developers:
1. Complete Setup and Foundational together.
2. After Phase 2:
- Developer A: restore and directory start migration in `apps/platform/app/Filament/Resources/RestoreRunResource.php`, `apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php`, and related jobs.
- Developer B: onboarding migration and shared presenter adoption in `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`.
- Developer C: tenant and provider-connection shared presenter adoption plus Monitoring parity in `apps/platform/app/Filament/Resources/TenantResource.php`, `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, and `apps/platform/app/Filament/Resources/OperationRunResource.php`.
3. Serialize edits in `apps/platform/app/Filament/Resources/TenantResource.php` and `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` because multiple stories touch those files.
---
## Notes
- `[P]` marks tasks that can run in parallel once their prerequisites are satisfied and the files do not overlap.
- `[US1]`, `[US2]`, and `[US3]` map directly to the spec's independently testable user stories.
- The narrowest proving lane remains `fast-feedback` plus `confidence`; do not widen into browser or heavy-governance without explicit follow-up justification.
- Keep new fixtures and helpers opt-in so provider, workspace, membership, active-run, and onboarding draft context do not become expensive test defaults.