--- description: "Task list for Spec 115 implementation" --- # Tasks: Baseline Operability & Alert Integration (Spec 115) **Input**: Design documents from `/specs/115-baseline-operability-alerts/` **Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/, quickstart.md **Tests**: REQUIRED (Pest) — this feature changes runtime behavior (Jobs/Services/Settings/UI). **Operations (Ops-UX)**: This feature reuses `OperationRun`. Tasks must preserve the 3-surface feedback contract, keep all status/outcome transitions service-owned (via `OperationRunService`), and keep `summary_counts` numeric-only with keys from `OperationSummaryKeys::all()`. **RBAC**: Any new/changed UI mutations or operation-start surfaces must use the capability registry (no raw strings) and preserve 404 vs 403 semantics (non-member/tenant-mismatch → 404; member missing capability → 403). **Filament**: Any destructive-like actions must use `->requiresConfirmation()` and remain workspace vs tenant-plane correct (FR-018). **Organization**: Tasks are grouped by user story so each story can be implemented and tested independently. ## Phase 1: Setup (Confirm Inputs) - [X] T001 Confirm scope + priorities in specs/115-baseline-operability-alerts/spec.md - [X] T002 Confirm implementation sequencing and touched paths in specs/115-baseline-operability-alerts/plan.md --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Shared building blocks required by US1/US2/US3. - [X] T003 Add baseline settings definitions + strict validation in app/Support/Settings/SettingsRegistry.php - [X] T004 [P] Add canonical run types for baseline operations in app/Support/OperationRunType.php - [X] T005 Update baseline run creation to use canonical run types in app/Services/Baselines/BaselineCompareService.php and app/Services/Baselines/BaselineCaptureService.php - [X] T006 [P] Add baseline compare precondition regression coverage ensuring unmet preconditions return `ok=false` and no `OperationRun` is created in tests/Feature/Baselines/BaselineComparePreconditionsTest.php **Checkpoint**: Baseline settings keys exist with correct defaults; baseline run types are canonical and referenced from code. --- ## Phase 3: User Story 1 — Safe auto-close removes stale baseline drift (Priority: P1) 🎯 **Goal**: Resolve stale baseline drift findings only after a fully successful, complete compare, and never on `partially_succeeded`/failed/incomplete runs. **Independent Test**: A compare that produces an initial seen fingerprint set, followed by a fully successful compare where those fingerprints are absent, resolves only the stale baseline findings. ### Tests (write first) - [X] T007 [P] [US1] Add auto-close safety gate coverage in tests/Feature/Baselines/BaselineOperabilityAutoCloseTest.php - [X] T008 [P] [US1] Extend lifecycle coverage (new vs reopened vs preserve open status) in tests/Feature/Baselines/BaselineCompareFindingsTest.php ### Implementation - [X] T009 [US1] Add safe auto-close implementation in app/Services/Baselines/BaselineAutoCloseService.php - [X] T010 [US1] Preserve finding workflow state and implement reopen semantics in app/Jobs/CompareBaselineToTenantJob.php - [X] T011 [US1] Apply baseline severity mapping by change_type when upserting findings in app/Jobs/CompareBaselineToTenantJob.php - [X] T012 [US1] Wire auto-close into compare completion using the safe gate (outcome+safety+completeness+kill-switch) in app/Jobs/CompareBaselineToTenantJob.php and app/Services/Baselines/BaselineAutoCloseService.php ### Verification - [X] T013 [US1] Run focused baseline tests: `vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineOperabilityAutoCloseTest.php` **Checkpoint**: Auto-close resolves only when safe; `partially_succeeded`/failed/incomplete compares never resolve baseline findings. --- ## Phase 4: User Story 2 — Baseline alerts are precise and deduplicated (Priority: P1) **Goal**: Emit baseline alerts only for new/reopened baseline findings (within window), and for compare failures, with correct dedupe/cooldown. **Independent Test**: Create baseline findings with controlled timestamps and statuses; evaluate alerts and ensure only new/reopened findings emit `baseline_high_drift` and only failed/`partially_succeeded` compares emit `baseline_compare_failed`. ### Tests (write first) - [X] T014 [P] [US2] Add baseline drift alert event coverage in tests/Feature/Alerts/BaselineHighDriftAlertTest.php - [X] T015 [P] [US2] Add baseline compare failed alert event coverage in tests/Feature/Alerts/BaselineCompareFailedAlertTest.php ### Implementation - [X] T016 [US2] Register baseline alert event constants in app/Models/AlertRule.php - [X] T017 [US2] Add baseline event types to the rule UI options/labels in app/Filament/Resources/AlertRuleResource.php - [X] T018 [US2] Produce baseline_high_drift events (baseline-only, new/reopened-only, severity threshold) in app/Jobs/Alerts/EvaluateAlertsJob.php - [X] T019 [US2] Produce baseline_compare_failed events for baseline compare runs with outcome failed/partially_succeeded in app/Jobs/Alerts/EvaluateAlertsJob.php - [X] T020 [US2] Ensure baseline drift event dedupe uses finding fingerprint (not numeric ID) in app/Jobs/Alerts/EvaluateAlertsJob.php ### Verification - [X] T021 [US2] Run focused alert tests: `vendor/bin/sail artisan test --compact tests/Feature/Alerts/BaselineHighDriftAlertTest.php` - [X] T022 [US2] Run focused alert tests: `vendor/bin/sail artisan test --compact tests/Feature/Alerts/BaselineCompareFailedAlertTest.php` **Checkpoint**: Alerts fire only on new/reopened baseline work; repeated compares do not re-alert the same open finding. --- ## Phase 5: User Story 3 — Workspace-controlled severity mapping and alert threshold (Priority: P2) **Goal**: Workspace admins can configure baseline severity mapping, alert threshold, and auto-close enablement via Workspace Settings. **Independent Test**: Saving workspace overrides updates effective values and affects newly created baseline findings and baseline alert eligibility. ### Tests (write first) - [X] T023 [P] [US3] Extend manage flow assertions for baseline settings in tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php - [X] T024 [P] [US3] Extend read-only flow assertions for baseline settings in tests/Feature/SettingsFoundation/WorkspaceSettingsViewOnlyTest.php ### Implementation - [X] T025 [US3] Add baseline settings fields to the settings field map in app/Filament/Pages/Settings/WorkspaceSettings.php - [X] T026 [US3] Render a "Baseline settings" section (mapping + minimum severity + auto-close toggle) in app/Filament/Pages/Settings/WorkspaceSettings.php - [X] T027 [US3] Ensure save/reset uses SettingsWriter validation and records audit logs for baseline settings in app/Filament/Pages/Settings/WorkspaceSettings.php ### Verification - [X] T028 [US3] Run focused settings tests: `vendor/bin/sail artisan test --compact tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php` **Checkpoint**: Workspace overrides are validated strictly and reflected as effective settings. --- ## Phase 6: Polish & Cross-Cutting Concerns - [X] T029 [P] Validate implementation matches the baseline alert event contract in specs/115-baseline-operability-alerts/contracts/baseline-alert-events.openapi.yaml and app/Jobs/Alerts/EvaluateAlertsJob.php - [X] T030 Validate the manual workflow remains accurate in specs/115-baseline-operability-alerts/quickstart.md - [X] T031 Run focused suites: `vendor/bin/sail artisan test --compact tests/Feature/Baselines/` and `vendor/bin/sail artisan test --compact tests/Feature/Alerts/` - [X] T032 [P] Add FR-018 regression coverage ensuring Baseline Profile CRUD remains workspace-owned (not reachable via tenant-context URLs and not present in tenant navigation) in tests/Feature/Baselines/BaselineProfileWorkspaceOwnershipTest.php --- ## Dependencies & Execution Order ### Dependency Graph ```mermaid graph TD Setup[Phase 1: Setup] --> Foundation[Phase 2: Foundational] Foundation --> US1[US1: Safe auto-close] Foundation --> US2[US2: Baseline alerts] Foundation --> US3[US3: Workspace baseline settings] US1 --> Polish[Phase 6: Polish] US2 --> Polish US3 --> Polish ``` ### Phase Dependencies - **Setup (Phase 1)**: No dependencies. - **Foundational (Phase 2)**: Blocks all user stories. - **US1 + US2 (Phase 3–4)**: Can proceed in parallel after Phase 2. - **US3 (Phase 5)**: Can proceed after Phase 2; does not block US1/US2 (defaults exist), but is required for workspace customization. - **Polish (Phase 6)**: After desired user stories complete. ### User Story Dependencies - **US1 (P1)** depends on: baseline settings defaults (T003) and compare job wiring. - **US2 (P1)** depends on: baseline settings defaults (T003) and baseline compare run type (T004–T005). - **US3 (P2)** depends on: baseline settings definitions (T003) and Workspace Settings page wiring (T025–T027). --- ## Parallel Execution Examples ### US1 - Run in parallel: - T007 (auto-close tests) and T008 (lifecycle tests) - T009 (auto-close service) and T010/T011 (compare job lifecycle + severity mapping) ### US2 - Run in parallel: - T014 (baseline drift alert tests) and T015 (compare failed alert tests) - T016/T017 (rule model/UI constants) while T018–T020 (job event producers) are implemented ### US3 - Run in parallel: - T023 (manage tests) and T024 (view-only tests) - T025 (field map) and T026 (form section rendering) --- ## Implementation Strategy - **MVP**: Complete Phase 2 + Phase 3 (US1). This delivers operability via safe auto-close with defaults. - **Next**: Phase 4 (US2) to make alerting low-noise and actionable. - **Then**: Phase 5 (US3) to let workspaces tailor severity mapping and alert thresholds.