# Tasks: Operations UI Operator Actions & Regression Gate **Input**: Design documents from `/specs/365-operations-ui-operator-actions-regression-gate/` **Prerequisites**: [plan.md](./plan.md), [spec.md](./spec.md), [artifacts/spec365-action-eligibility-matrix.md](./artifacts/spec365-action-eligibility-matrix.md), [artifacts/spec365-regression-gate-matrix.md](./artifacts/spec365-regression-gate-matrix.md) **Tests**: Required. Runtime changes must use Pest 4 unit/feature/browser coverage. ## Repository State Captured During Prep - **Branch**: `365-operations-ui-operator-actions-regression-gate` - **HEAD**: `3ce1cae7 feat: implement restore high risk operation reconciliation (#435)` - **git status at prep start**: clean on `platform-dev` before branch creation; after Spec Kit branch creation only `specs/365-operations-ui-operator-actions-regression-gate/` was untracked. - **Spec 364 baseline status**: treated as completed immediate predecessor; implementation must keep Spec364 restore/high-risk tests green. - **Relevant Operations UI / action files**: - `apps/platform/app/Filament/Pages/Monitoring/Operations.php` - `apps/platform/app/Filament/Resources/OperationRunResource.php` - `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php` - `apps/platform/app/Support/OpsUx/OperationUxPresenter.php` - `apps/platform/app/Support/OpsUx/OperationRunProgressContract.php` - `apps/platform/app/Support/OperationRunLinks.php` - `apps/platform/app/Support/Navigation/RelatedNavigationResolver.php` - `apps/platform/app/Support/Navigation/RelatedActionLabelCatalog.php` - `apps/platform/app/Policies/OperationRunPolicy.php` - `apps/platform/app/Support/OperationRunCapabilityResolver.php` - `apps/platform/app/Support/Auth/Capabilities.php` - `apps/platform/app/Services/AdapterRunReconciler.php` - `apps/platform/app/Support/Operations/Reconciliation/OperationRunReconciliationRegistry.php` - `apps/platform/app/Services/OperationRunService.php` ## Implementation Decisions to Record During Close-Out - **Implemented actions**: Reconcile for eligible stale adapter-backed OperationRuns; safe related navigation for review, evidence snapshot, review pack/report, inventory affected-family/details, backup details, and restore details; support diagnostics remains secondary/capability-gated. - **Deferred actions**: generic Retry for all families because no repo-verified generic safe retry/start seam was found; OperationRun Acknowledge because no clean existing acknowledge/note seam exists. - **Unsupported/forbidden actions**: Force Complete, Mark Succeeded, Retry Restore, Re-execute Restore, Delete, Purge. - **Coverage artifact decision**: updated `docs/ui-ux-enterprise-audit/page-reports/ui-003-operations.md` because the existing Operations strategic surface gained visible safe-next-action hierarchy. - **Spec 358-364 regression result**: targeted Spec359/Spec360 browser/Spec364 plus OperationRun viewer/link/monitoring/resource presentation regressions passed locally; final filter sweep recorded under Phase 13. - **Mutation scope disclosure result**: Reconcile confirmation discloses TenantPilot-only OperationRun/action metadata and explicitly states no Microsoft tenant retry/change. Retry was not implemented. ## 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 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 (`monitoring-state-page`, `shared-detail-family`) is explicit. - [x] Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR. ## Format: `[ID] [P?] [Story] Description` - **[P]**: Can run in parallel after prerequisites. - **[Story]**: US1, US2, US3, US4, US5, US6. ## Phase 1: Setup and Audit (Shared) **Purpose**: Confirm repo seams, docs, capabilities, and existing UI before implementation. - [x] T001 [P] Re-read `specs/365-operations-ui-operator-actions-regression-gate/spec.md`, `plan.md`, both matrix artifacts, and `.specify/memory/constitution.md` before code changes. - [x] T002 [P] Audit current OperationRun UI/action code in `apps/platform/app/Filament/Pages/Monitoring/Operations.php`, `apps/platform/app/Filament/Resources/OperationRunResource.php`, and `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`. - [x] T003 [P] Audit current shared OperationRun UX/link seams in `OperationUxPresenter`, `OperationRunProgressContract`, `OperationRunLinks`, `RelatedNavigationResolver`, and `RelatedActionLabelCatalog`. - [x] T004 [P] Audit action authorization seams in `OperationRunPolicy`, `OperationRunCapabilityResolver`, and `Capabilities` to decide whether existing capabilities cover reconcile/retry/diagnostics. - [x] T005 [P] Audit existing audit/action metadata seams in `AuditRecorder`, `WorkspaceAuditLogger`, and OperationRun context writes to decide whether `context.operator_actions` is needed. - [x] T006 [P] Audit safe retry/resume/start seams, including `TenantlessOperationRunViewer::resumeCaptureAction()` and any operation-family start services; record unsupported families in the close-out section above. ## Phase 2: Foundational Resolver and Contracts (Blocking) **Purpose**: Add the single action decision path before UI wiring. - [x] T007 [US1] Add a narrow resolver such as `apps/platform/app/Support/Operations/OperationRunActionEligibility.php` that derives primary/secondary/disabled actions from canonical OperationRun truth, user, workspace, and environment scope. - [x] T008 [US1] Add a small derived result object or array contract for `primary_action`, `secondary_actions`, `disabled_actions`, `disabled_reasons`, and `attention_reason`; keep it non-persisted and avoid new status/outcome enums. - [x] T009 [US1] Ensure resolver reads canonical `context.dispatch`, `context.reconciliation`, `context.results`, `context.coverage`, and `context.restore` only; do not add new legacy fallback paths. - [x] T010 [US3] Encode high-risk classification for restore/tenant mutation/destructive/unknown operations so retry/re-execute/force-success always fail closed. - [x] T011 [US2] Encode reconcile eligibility through `OperationRunReconciliationRegistry` support and current run state/freshness/proof rules. - [x] T012 [US4] Encode retry eligibility as unavailable by default unless a repo-verified safe non-high-risk retry/start seam exists for the operation family. - [x] T013 [US5] Encode related action eligibility using canonical related metadata and existing link/navigation resolvers. - [x] T014 [US6] Encode diagnostics visibility through existing support/operator capability checks. ## Phase 3: Unit Tests First (Resolver, Presenter, Guard) **Purpose**: Lock action decisions before Filament UI changes. - [x] T015 [P] [US1] Add `apps/platform/tests/Unit/Support/Operations/Spec365OperationRunActionEligibilityTest.php` covering fresh queued, stale queued, stale running, unsupported, missing capability, and cross-workspace inputs. - [x] T016 [P] [US1] Add `apps/platform/tests/Unit/Support/Operations/Spec365OperationRunPrimaryActionTest.php` covering one primary action for review, evidence, review-pack/report, sync partial, backup blocked, restore verification-required, and restore failed. - [x] T017 [P] [US3] Cover high-risk action guard assertions in the Spec365 unit tests, proving restore/high-risk has no retry, re-execute, force complete, mark succeeded, delete, or purge action. - [x] T018 [P] [US1] Update OperationRun detail/presentation/browser coverage for outcome-specific decision summaries and raw-leakage sanitization. - [x] T019 [P] [US4] Add unit coverage proving safe retry returns unavailable/deferred for operation families without a repo-verified retry seam. ## Phase 4: Existing Operations UI Integration **Purpose**: Make the existing surfaces decision-first without creating new pages. - [x] T020 [US1] Update `Operations.php` table/list presentation to surface status/outcome, freshness, scope, primary reason, and one resolver-provided primary action or action label. - [x] T021 [US1] Update `OperationRunResource.php` detail sections to place decision summary, evidence, and next action before technical diagnostics. - [x] T022 [US1] Update `TenantlessOperationRunViewer.php` header/action groups to consume resolver output for primary and secondary actions. - [x] T023 [US1] Ensure technical/raw context sections are collapsed and capability-gated by default. - [x] T024 [US1] Remove or demote any redundant "View" action when row click/detail link already provides the primary inspect model. - [x] T025 [US3] Ensure high-risk restore detail uses "View restore details" or equivalent safe navigation and never presents retry/re-execute/force-success copy. ## Phase 5: Safe Reconcile Action **Purpose**: Integrate reconciliation only through existing canonical seams. - [x] T026 [US2] Add a Filament reconcile action on the appropriate OperationRun detail/header surface using `Action::make(...)->action(...)` and confirmation/description copy where appropriate. - [x] T078 [US2] Ensure Reconcile action helper text, modal description, preview, or confirmation communicates mutation scope before execution, normally TenantPilot-only OperationRun/action metadata. - [x] T027 [US2] Enforce server-side authorization and scope in `OperationRunPolicy` or a central action policy/helper; preserve non-member 404 and missing-capability 403 semantics. - [x] T028 [US2] Execute reconcile through `AdapterRunReconciler` and `OperationRunService`; do not mutate OperationRun state directly in the UI action. - [x] T029 [US2] Make reconcile idempotent for already reconciled or no-op adapter outcomes. - [x] T030 [US2] Write audit/action metadata for reconcile with action, run id, workspace, environment, actor, previous/new status/outcome, reason code, timestamp, and no secrets. - [x] T031 [US2] Add disabled/unavailable reason copy for unsupported, missing capability, cross-scope, insufficient proof, and already terminal/succeeded states. ## Phase 6: Safe Retry Action or Explicit Deferral **Purpose**: Offer retry only where safe and repo-real. - [x] T032 [US4] For each candidate non-high-risk operation family, verify whether a safe idempotent retry/start seam exists; document results in the close-out section. - [x] T033 [US4] No safe generic seam exists; retry action not implemented. - [x] T079 [US4] No Retry implemented; mutation-scope disclosure not applicable. - [x] T034 [US4] If no safe seam exists for a family, keep retry unavailable and show a localized disabled/deferred reason. - [x] T035 [US4] No Retry implemented; no new run-creation flood path added. - [x] T036 [US4] No Retry implemented; no retry audit metadata required. - [x] T037 [US4] Ensure completed/succeeded, unknown, restore, tenant mutation, destructive, and high-risk runs never become retryable. ## Phase 7: Related Domain Actions **Purpose**: Let operators open proof without raw context inspection. - [x] T038 [US5] Wire related actions through existing `OperationRunLinks` / `RelatedNavigationResolver` where canonical metadata and policy checks pass. - [x] T039 [US5] Support canonical related actions for review, evidence snapshot, review-pack/report artifact, backup set, sync/details if existing route exists, and restore details. - [x] T040 [US5] Hide or disable related actions when metadata is absent, capability is missing, or the target is cross-workspace/cross-environment. - [x] T041 [US5] Ensure no action reads signed URLs, raw payloads, or legacy fallback context from OperationRun context. ## Phase 8: Localization and Copy **Purpose**: Keep labels and summaries customer-safe in EN/DE. - [x] T042 [P] [US6] Add EN localization keys in `apps/platform/lang/en/localization.php` for reconcile, retry, related actions, disabled reasons, high-risk guard, and summary states. - [x] T043 [P] [US6] Add DE localization keys in `apps/platform/lang/de/localization.php` for the same key families. - [x] T044 [US6] Ensure primary action labels use Verb + Object and avoid implementation-first terms. - [x] T045 [US6] Ensure customer-readable copy does not expose SQL, Guzzle, stack trace, access token, client secret, queue payload, serialized job, or internal constraint names. ## Phase 9: Feature Tests **Purpose**: Prove direct action behavior, RBAC, scope, audit, and related links. - [x] T046 [P] [US2] Add `apps/platform/tests/Feature/Operations/Spec365OperationRunOperatorActionsTest.php` for reconcile success, unsupported reconcile denial, and idempotency. - [x] T047 [P] [US4] Add retry-unavailable tests in focused Spec365 unit/feature coverage; no Retry implemented. - [x] T048 [P] [US2,US4] Add `apps/platform/tests/Feature/Operations/Spec365OperationRunOperatorActionsTest.php` for missing capability and direct action denial. - [x] T049 [P] [US2,US5] Add cross-workspace and cross-environment denial tests. - [x] T050 [P] [US6] Add `apps/platform/tests/Feature/Operations/Spec365OperationRunOperatorActionsTest.php` for reconcile metadata and no-secret assertions. - [x] T080 [P] [US6] Extend denied-action coverage to assert failed/denied Reconcile attempts are audit-visible or safely logged without secrets; Retry not implemented. - [x] T051 [P] [US5] Cover same-scope related links and cross-scope denial in Spec365 unit/feature tests plus existing OperationRun link contract tests. - [x] T052 [P] [US1] Cover regression matrix states that do not require browser coverage in Spec365 unit tests and existing OperationRun presentation regressions. ## Phase 10: Browser Smoke **Purpose**: Prove the actual Operations UI is decision-first and safe. - [x] T053 [US1] Add `apps/platform/tests/Browser/Spec365OperationsUiOperatorActionsSmokeTest.php` for Operations list decision-first fields and no raw JSON by default. - [x] T054 [US2] Cover review reconcile state, confirmation modal, and absence of SQL/constraint leakage. - [x] T055 [US5] Cover review-pack/report and evidence snapshot available states with safe related actions. - [x] T056 [US1] Cover sync partial and backup blocked summary states. - [x] T057 [US3] Cover restore verification-required/high-risk state with safe restore details action and absence of Retry Restore, Force Complete, and Mark Succeeded. - [x] T058 [US6] Cover RBAC-denied user where reconcile/retry actions are unavailable in feature coverage; Retry not implemented. - [x] T059 [US6] Cover raw leakage guard for `SQLSTATE`, `Guzzle`, `stack trace`, `access token`, `client secret`, `environment_reviews_fingerprint_mutable_unique`, and `serialized job`. - [x] T060 [US1] Screenshots were not saved because the automated browser assertions were sufficient and no visual defect remained after smoke. ## Phase 11: Optional Acknowledge Decision **Purpose**: Avoid a local "reviewed" substitute unless the repo already supports it cleanly. - [x] T061 [US6] Verify whether a clean existing OperationRun acknowledge/note/audit seam exists. - [x] T062 [US6] No clean seam exists; Acknowledge not implemented. - [x] T063 [US6] Document Acknowledge as deferred in the close-out section and do not implement local context-only success-like state. ## Phase 12: Coverage Artifacts and Documentation Close-Out **Purpose**: Keep Spec Kit and UI coverage aligned. - [x] T064 [P] Update `artifacts/spec365-action-eligibility-matrix.md` if implementation changes eligible actions or disabled reasons. - [x] T065 [P] Update `artifacts/spec365-regression-gate-matrix.md` with actual test file names/statuses after implementation. - [x] T066 Update `docs/ui-ux-enterprise-audit/page-reports/ui-003-operations.md` and related design coverage files if implementation changes layout, action hierarchy, state hierarchy, or screenshots materially; record a no-update rationale only for pattern-compatible action/copy wiring. - [x] T067 Update this `tasks.md` close-out section with implemented/deferred/unsupported actions and validation outcomes. ## Phase 13: Validation **Purpose**: Run the final Spec365 and regression gate. - [x] T068 Run `cd apps/platform && php artisan test --compact --filter=Spec365` or targeted direct Spec365 lanes. - [x] T069 Run `cd apps/platform && php artisan test --compact --filter=Spec364`. - [x] T070 Run `cd apps/platform && php artisan test --compact --filter=Spec363`. - [x] T071 Run `cd apps/platform && php artisan test --compact --filter=Spec362`. - [x] T072 Run `cd apps/platform && php artisan test --compact --filter=Spec361`. - [x] T073 Run `cd apps/platform && php artisan test --compact --filter=Spec360`. - [x] T074 Run `cd apps/platform && php artisan test --compact --filter=Spec359`. - [x] T075 Run `cd apps/platform && php artisan test --compact --filter=Spec358`. - [x] T076 Run `cd apps/platform && php vendor/bin/pint --dirty`. - [x] T077 Run `git diff --check`. - [x] T081 Run a static scan over changed application files for Livewire v3 APIs: `emit`, `emitTo`, and `dispatchBrowserEvent`. - [x] T082 Review the final diff for Filament/Tailwind/build asset changes; if any are required, update `spec.md` and `plan.md` before merge. - [x] T083 If browser lane was not included in the Spec365 filter, run `cd apps/platform && php artisan test --compact tests/Browser/Spec365OperationsUiOperatorActionsSmokeTest.php`. ## Validation Close-Out - `php artisan test --compact --filter=Spec365`: 23 passed, 160 assertions. - `php artisan test --compact --filter=Spec364`: 10 passed, 59 assertions. - `php artisan test --compact --filter=Spec363`: no tests found. - `php artisan test --compact --filter=Spec362`: 27 passed, 238 assertions. - `php artisan test --compact --filter=Spec361`: 16 passed, 123 assertions. - `php artisan test --compact --filter=Spec360`: 9 passed, 79 assertions. - `php artisan test --compact --filter=Spec359`: 25 passed, 150 assertions. - `php artisan test --compact --filter=Spec358`: no tests found. - `php vendor/bin/pest tests/Feature/Operations/Spec359OperationRunAdapterReconciliationTest.php tests/Feature/EnvironmentReview/Spec359ReviewComposeReconciliationTest.php tests/Feature/Operations/Spec364RestoreExecuteReconciliationTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/Guards/OperationRunLinkContractGuardTest.php`: 42 passed, 194 assertions. - `php vendor/bin/pest tests/Feature/Monitoring/MonitoringOperationsTest.php tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php tests/Feature/Filament/OperationRunListFiltersTest.php tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php`: 37 passed, 271 assertions. - `php artisan test --compact tests/Browser/Spec365OperationsUiOperatorActionsSmokeTest.php`: 3 passed, 42 assertions. - `php artisan test --compact tests/Browser/Spec360OperationRunCanonicalCutoverSmokeTest.php`: 2 passed, 21 assertions. - `php vendor/bin/pint --dirty`: passed after formatting dirty PHP files. - Livewire v3 API scan over changed app files for `emit`, `emitTo`, and `dispatchBrowserEvent`: no matches. - `git diff --check`: passed. - Final diff review: no Filament panel/provider registration changes, no Tailwind/build asset changes, no new migrations, no env var changes, no queue/cron/storage changes. ## Dependencies and Ordering - Phase 1 must complete before runtime implementation. - Phase 2 must complete before Phases 4-7. - Phase 3 should be written before or alongside Phase 2. - Reconcile and retry feature tests depend on resolver and authorization decisions. - Browser smoke depends on visible UI wiring and localization. - Validation runs last. ## Parallel Execution Examples - T002-T006 can run in parallel during audit. - T015-T019 can run in parallel after resolver contract is sketched. - T042-T043 can run in parallel with feature test implementation. - T046-T052 can be split by action family after shared factories/fixtures exist. ## Notes - Do not add a new generic retry framework in this spec. - Do not add any restore retry/re-execute path. - Do not add Force Complete, Mark Succeeded, Delete, Purge, or equivalent copy. - Do not add new top-level Operations navigation. - Do not expose raw technical diagnostics by default. - Do not add new Filament/Tailwind assets unless implementation proves they are required and the spec/plan are updated first.