TenantAtlas/specs/242-operational-controls/tasks.md
ahmido d96abc65fb
Some checks failed
Main Confidence / confidence (push) Failing after 1m23s
Remove Findings lifecycle backfill operational surface (controls slice) (#280)
Removes the Findings lifecycle backfill from the Operational Controls UI and OperationalControlCatalog.

This patch is a safe, controls-only change; runbooks, jobs and other runtime artifacts are NOT removed yet. Follow-up work will delete the runbook service/scope, jobs, commands, and update tests.

Files changed:
- apps/platform/app/Filament/System/Pages/Ops/Controls.php
- apps/platform/app/Support/OperationalControls/OperationalControlCatalog.php
- apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php
- apps/platform/tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php
- apps/platform/tests/Unit/Support/OperationalControls/OperationalControlScopeResolutionTest.php

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #280
2026-04-26 15:43:47 +00:00

17 KiB

description
Task list for Operational Controls

Tasks: Operational Controls

Input: Design documents from /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/
Prerequisites: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/plan.md (required), /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/spec.md (required), /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/research.md, /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/data-model.md, /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/contracts/operational-controls.contract.yaml, /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/242-operational-controls/quickstart.md

Tests: REQUIRED (Pest) for all runtime behavior changes in this slice. Keep proof in Unit + Feature lanes only.
Operations: Allowed starts must continue to reuse the shared OperationRun start UX. Blocked starts for findings.lifecycle.backfill and restore.execute must create no queued execution OperationRun, no queued execution RestoreRun, no queued job, and no provider-backed execution. Control activation governs new starts only and must not retroactively mutate already accepted runs.
RBAC: Management is platform-plane only under /system; affected execution surfaces stay on /system or /admin/t/{tenant}. Non-members remain 404, members without the underlying capability remain 403, and entitled users blocked only by an active operational control get explicit paused-state feedback.
Organization: Tasks are grouped by user story so each slice remains independently testable and bounded to the first-slice controls findings.lifecycle.backfill and restore.execute.

Phase 1: Setup (Shared Infrastructure)

Purpose: Prepare the local implementation lane and feature-local file layout without widening scope.

  • T001 Start the local Sail environment with cd apps/platform && ./vendor/bin/sail up -d (script: apps/platform/vendor/bin/sail)
  • T002 Create the bounded feature-local directories under apps/platform/app/Support/OperationalControls/, apps/platform/tests/Unit/Support/OperationalControls/, apps/platform/tests/Feature/System/OpsControls/, apps/platform/tests/Feature/System/OpsRunbooks/, apps/platform/tests/Feature/Findings/, apps/platform/tests/Feature/Restore/, and apps/platform/tests/Feature/OperationalControls/

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Add the single new persistence model, the bounded operational-controls support namespace, and the shared capability/audit plumbing that all stories depend on.

Checkpoint: The repo has one operational_control_activations truth, one evaluator/catalog/decision support path, one platform capability, and shared audit IDs before any surface integration begins.

  • T003 Create the activation migration in apps/platform/database/migrations/*_create_operational_control_activations_table.php, including partial unique indexes for active global and workspace-scoped rows
  • T004 Create the activation model in apps/platform/app/Models/OperationalControlActivation.php
  • T005 [P] Create the activation factory in apps/platform/database/factories/OperationalControlActivationFactory.php
  • T006 [P] Create the bounded catalog for findings.lifecycle.backfill and restore.execute in apps/platform/app/Support/OperationalControls/OperationalControlCatalog.php
  • T007 [P] Create the derived decision object in apps/platform/app/Support/OperationalControls/OperationalControlDecision.php
  • T008 Create the shared evaluator for global and workspace-targeted activations, including foundational global-first precedence and expiry handling, in apps/platform/app/Support/OperationalControls/OperationalControlEvaluator.php
  • T009 [P] Add the platform management capability for the controls surface in apps/platform/app/Support/Auth/PlatformCapabilities.php and grant it in apps/platform/database/seeders/PlatformUserSeeder.php for the seeded local operator path
  • T010 [P] Add stable audit action IDs for pause, update, resume, and execution-blocked events in apps/platform/app/Support/Audit/AuditActionId.php
  • T011 Extend canonical audit plumbing for control scope, reason, expiry, requested-scope metadata, and blocked-execution evidence using apps/platform/app/Services/Audit/AuditRecorder.php for global control changes and blocked system all-tenant attempts and apps/platform/app/Services/Audit/WorkspaceAuditLogger.php for workspace/tenant-scoped changes and blocked execution
  • T012 [P] Add catalog and evaluator unit coverage in apps/platform/tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php and apps/platform/tests/Unit/Support/OperationalControls/OperationalControlEvaluatorTest.php
  • T013 [P] Add global-first precedence and expiry coverage in apps/platform/tests/Unit/Support/OperationalControls/OperationalControlScopeResolutionTest.php
  • T014 Run the foundational unit suite with cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php tests/Unit/Support/OperationalControls/OperationalControlEvaluatorTest.php tests/Unit/Support/OperationalControls/OperationalControlScopeResolutionTest.php (tests: apps/platform/tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php)

Phase 3: User Story 1 — Pause A Risky Action Centrally (Priority: P1) 🎯 MVP

Goal: Give platform operators one system-plane control center that can pause findings.lifecycle.backfill and make the runbook and findings surfaces show one explicit blocked-state path instead of env-driven disappearance.

Independent Test: Pause findings.lifecycle.backfill globally from /system/ops/controls, then verify /system/ops/runbooks and /admin/t/{tenant}/findings both show the action truthfully for entitled users, block execution server-side, and show the same paused-state reason.

Tests for User Story 1

  • T015 [P] [US1] Add system-plane management coverage for staged scope-impact preview, controls-page 403 access denial, pause, update, resume, confirmation, global-audit ownership, on-demand audit history links, and audit logging in apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php
  • T016 [P] [US1] Add findings lifecycle gate coverage for blocked findings.lifecycle.backfill starts at the shared FindingsLifecycleBackfillRunbookService::start() seam, including system-runbook callers, mandatory blocked-execution audit evidence, and truthful platform-plane ownership for blocked all-tenant attempts in apps/platform/tests/Feature/System/OpsRunbooks/OperationalControlRunbookGateTest.php
  • T017 [P] [US1] Add findings header-action coverage for explicit blocked-state feedback, mandatory blocked-execution audit evidence, and no-start behavior in apps/platform/tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php

Implementation for User Story 1

  • T018 [US1] Create the system ops controls page with native Filament sections, staged scope-impact preview plus confirmation-protected pause/resume actions, effective-state summaries, owner display, on-demand audit history links, and the mutation-path cleanup that deletes expired conflicting activations before writing a new pause in apps/platform/app/Filament/System/Pages/Ops/Controls.php
  • T019 [US1] Integrate the evaluator into apps/platform/app/Services/Runbooks/FindingsLifecycleBackfillRunbookService.php::start() so the system runbooks page, CLI command, and deploy-hook command all honor the same blocked-start contract
  • T020 [US1] Replace the env-gated findings maintenance path by routing the tenant findings action through the shared findings lifecycle service/evaluator path, blocked-execution audit recording, and shared paused-state feedback in apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php
  • T021 [US1] Retire the in-scope findings env gate from apps/platform/config/tenantpilot.php
  • T022 [US1] Run the US1 suite with cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/OpsControls/OperationalControlManagementTest.php tests/Feature/System/OpsRunbooks/OperationalControlRunbookGateTest.php tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php (tests: apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php)

Phase 4: User Story 2 — Block Execution Server-Side Without Masquerading As Auth (Priority: P1)

Goal: Stop restore.execute before any queue, OperationRun, RestoreRun, or provider-backed execution starts while preserving normal 404 and 403 semantics.

Independent Test: Activate restore.execute, attempt the restore execution flow as an entitled user, a non-member, and a member missing capability, and verify the outcomes are respectively paused-with-reason, 404, and 403, with no execution side effects on blocked paths.

Tests for User Story 2

  • T023 [P] [US2] Add restore execution gate coverage for blocked execution starts, mandatory blocked-execution audit evidence, no queued-execution RestoreRun/OperationRun side effects, provider-start suppression, and proof that a later pause does not retroactively mutate already accepted restore runs in apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php
  • T024 [P] [US2] Add explicit authorization-semantics and break-glass non-bypass coverage for non-member 404, missing-capability 403 with the existing capability-denied UX, and paused-state feedback only for entitled users blocked by an operational control in apps/platform/tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php

Implementation for User Story 2

  • T025 [US2] Integrate the evaluator into the restore execution start seam so blocked restore.execute decisions stop before any queued execution RestoreRun, queued execution OperationRun, queue dispatch, or provider call in apps/platform/app/Filament/Resources/RestoreRunResource.php
  • T026 [US2] Reuse the shared provider-start gate for operational-control blocked outcomes instead of introducing restore-local runtime flags in apps/platform/app/Services/Providers/ProviderOperationStartGate.php
  • T027 [US2] Run the US2 suite with cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php (tests: apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php)

Phase 5: User Story 3 — Scope A Pause To One Workspace (Priority: P2)

Goal: Allow platform operators to target one workspace without affecting unrelated workspaces, while keeping evaluator precedence and expiry behavior explicit and stable.

Independent Test: Pause restore.execute or findings.lifecycle.backfill for Workspace A only, then verify the targeted workspace is blocked with the correct reason and a second workspace remains unaffected until the activation is removed or expires.

Tests for User Story 3

  • T028 [P] [US3] Extend controls-page feature coverage for workspace-targeted pause, update, expiry, and resume flows in apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php
  • T029 [P] [US3] Add workspace-isolation coverage for targeted findings and restore blocking in apps/platform/tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php and apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php

Implementation for User Story 3

  • T030 [US3] Add workspace-targeted scope selection, validation, and effective-state presentation to the controls page in apps/platform/app/Filament/System/Pages/Ops/Controls.php
  • T031 [US3] Extend OperationalControlDecision with workspace-targeted presentation details for matched scope, reason, expiry, and labels without redefining the foundational shared decision shape in apps/platform/app/Support/OperationalControls/OperationalControlDecision.php
  • T032 [US3] Ensure runbooks, findings, and restore all pass workspace context consistently into control evaluation in apps/platform/app/Filament/System/Pages/Ops/Runbooks.php, apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php, and apps/platform/app/Filament/Resources/RestoreRunResource.php
  • T033 [US3] Run the US3 suite with cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/OpsControls/OperationalControlManagementTest.php tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php (tests: apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php)

Phase 6: Polish & Cross-Cutting Concerns

Purpose: Lock down the shared-path contract, update feature artifacts if implementation details move, and run the narrow validation suite.

  • T034 [P] Add a CI guard against ad-hoc config(...) or page-local runtime-control bypasses for the in-scope controls in apps/platform/tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php
  • T035 Update feature artifact close-out notes and final validation commands in specs/242-operational-controls/plan.md and specs/242-operational-controls/quickstart.md
  • T036 Run formatting on touched platform files with cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent (target: apps/platform/)
  • T037 Run the full narrow validation suite from specs/242-operational-controls/quickstart.md, including the timed manual smoke for SC-001, across apps/platform/tests/Unit/Support/OperationalControls/, apps/platform/tests/Feature/System/OpsControls/, apps/platform/tests/Feature/System/OpsRunbooks/, apps/platform/tests/Feature/Findings/, apps/platform/tests/Feature/Restore/, and apps/platform/tests/Feature/OperationalControls/

Dependencies & Execution Order

User Story Dependency Graph

Phase 1 (Setup)
  ↓
Phase 2 (Foundation: activation persistence + evaluator + capability/audit plumbing)
  ↓
US1 (system controls page + findings lifecycle gating) ─┐
                                                        ├─→ US3 (workspace-targeted scope + precedence/expiry)
US2 (restore execution gate + auth semantics) ──────────┘

Parallel Opportunities

  • Foundational tasks marked [P] can run in parallel once the migration/model direction is agreed.
  • US1 tests for controls, runbooks, and findings can be authored in parallel because they target separate files.
  • US2 restore and authorization-semantics tests can run in parallel while the restore seam work is isolated to RestoreRunResource.php and ProviderOperationStartGate.php.
  • US3 extends existing US1/US2 tests and can parallelize the findings and restore workspace-isolation assertions while one person updates the controls page scope UI.

Parallel Example: User Story 1

Task: "Add system-plane management coverage in apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php"
Task: "Add runbook gating coverage in apps/platform/tests/Feature/System/OpsRunbooks/OperationalControlRunbookGateTest.php"
Task: "Add findings header-action coverage in apps/platform/tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php"
Task: "Create the controls page in apps/platform/app/Filament/System/Pages/Ops/Controls.php"

Parallel Example: User Story 2

Task: "Add restore execution gate coverage in apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php"
Task: "Add authorization-semantics coverage in apps/platform/tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php"
Task: "Integrate the evaluator into apps/platform/app/Filament/Resources/RestoreRunResource.php"

Parallel Example: User Story 3

Task: "Extend controls-page workspace scope coverage in apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php"
Task: "Add workspace-isolation assertions in apps/platform/tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php"
Task: "Add workspace-isolation assertions in apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php"
Task: "Add workspace-targeted scope selection in apps/platform/app/Filament/System/Pages/Ops/Controls.php"

Implementation Strategy

MVP First (User Story 1)

  1. Complete Phase 1 and Phase 2.
  2. Deliver the controls page plus findings.lifecycle.backfill integrations in US1.
  3. Validate with the US1 feature suite before extending the second control.

Incremental Delivery

  1. US1 delivers the new system-plane management surface and removes the ad-hoc findings env gate.
  2. US2 wires the same evaluator into restore.execute and proves blocked execution is not treated as authorization failure.
  3. US3 adds workspace-targeted scope, precedence, and expiry without widening the catalog or support namespace.
  4. Phase 6 adds the bypass guard, feature-artifact close-out, formatting, and the narrow validation pass.