# Tasks: BaselineSnapshot Artifact Truth & Downstream Consumption Guards **Input**: Design documents from `/specs/159-baseline-snapshot-truth/` **Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/openapi.yaml, quickstart.md **Tests**: Tests are REQUIRED for this feature because it changes runtime behavior across capture, compare, UI truth presentation, and historical backfill. **Operations**: `baseline.capture` and `baseline.compare` already use canonical `OperationRun` flows. Tasks below preserve queued-only toasts, progress-only active surfaces, terminal `OperationRunCompleted`, service-owned run transitions, and numeric-only `summary_counts`. **RBAC**: Workspace-plane and tenant-plane authorization behavior is preserved. Non-members remain 404, members without capability remain 403, and destructive-like actions keep `->requiresConfirmation()`. **Badges**: All new lifecycle/usability status mapping must stay inside `BadgeCatalog` / `BadgeRenderer` / `ArtifactTruthPresenter`; no ad-hoc Filament mappings. **List Surface Review**: Modified Baseline Profiles and Baseline Snapshots list surfaces must be reviewed against `docs/product/standards/list-surface-review-checklist.md`. ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Create the shared lifecycle scaffolding this feature needs before any story-specific behavior can be implemented. - [X] T001 Add BaselineSnapshot lifecycle/backfill schema changes in `database/migrations/2026_03_23_000001_add_lifecycle_state_to_baseline_snapshots_table.php` - [X] T002 [P] Create the BaselineSnapshot lifecycle enum in `app/Support/Baselines/BaselineSnapshotLifecycleState.php` - [X] T003 [P] Extend snapshot lifecycle factory states in `database/factories/BaselineSnapshotFactory.php` --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Add the shared domain, reason, and badge infrastructure that all user stories depend on. **⚠️ CRITICAL**: No user story work should start until this phase is complete. - [X] T004 Update lifecycle casts, transition helpers, and consumable scopes in `app/Models/BaselineSnapshot.php` - [X] T005 [P] Add effective-snapshot and consumability resolution in `app/Services/Baselines/BaselineSnapshotTruthResolver.php` - [X] T006 [P] Add non-consumable baseline reason codes in `app/Support/Baselines/BaselineReasonCodes.php` - [X] T007 [P] Add lifecycle/operator-safe reason translations in `app/Support/ReasonTranslation/ReasonTranslator.php` - [X] T008 [P] Register the new lifecycle badge domain in `app/Support/Badges/BadgeDomain.php` and `app/Support/Badges/BadgeCatalog.php` - [X] T009 [P] Add lifecycle taxonomy and badge mapping in `app/Support/Badges/OperatorOutcomeTaxonomy.php` and `app/Support/Badges/Domains/BaselineSnapshotLifecycleBadge.php` **Checkpoint**: Shared lifecycle, resolver, and badge infrastructure are ready for story work. --- ## Phase 3: User Story 1 - Trust Only Complete Baselines (Priority: P1) 🎯 MVP **Goal**: Capture must only promote complete snapshots as effective baseline truth, while partial or failed captures remain explicitly unusable. **Independent Test**: Start a successful capture and verify the snapshot ends `complete` and becomes current truth; simulate a partial-write failure and verify the snapshot ends `incomplete` and the previous complete snapshot remains current. ### Tests for User Story 1 ⚠️ > **NOTE: Write these tests first and confirm they fail before implementation.** - [X] T010 [P] [US1] Add BaselineSnapshot lifecycle domain tests in `tests/Unit/Baselines/BaselineSnapshotLifecycleTest.php` - [X] T011 [P] [US1] Update capture lifecycle and partial-write regression coverage in `tests/Feature/Baselines/BaselineCaptureTest.php` ### Implementation for User Story 1 - [X] T012 [US1] Add current-consumable snapshot helpers to `app/Models/BaselineProfile.php` - [X] T013 [US1] Create `building` snapshots and completion-proof finalization in `app/Jobs/CaptureBaselineSnapshotJob.php` - [X] T014 [US1] Guard `active_snapshot_id` promotion and current-snapshot rollover in `app/Jobs/CaptureBaselineSnapshotJob.php` **Checkpoint**: Capture produces explicit lifecycle truth and only complete snapshots become effective current baselines. --- ## Phase 4: User Story 2 - Block Unsafe Compare Input (Priority: P2) **Goal**: Compare must resolve only consumable snapshots and fail safely when the selected or implicit baseline is building, incomplete, or otherwise unusable. **Independent Test**: Attempt compare with a complete snapshot, a building snapshot, and an incomplete snapshot; only the complete path should proceed while blocked cases return clear operator-safe reasons. ### Tests for User Story 2 ⚠️ - [X] T015 [P] [US2] Update compare precondition coverage for building/incomplete snapshots in `tests/Feature/Baselines/BaselineComparePreconditionsTest.php` - [X] T016 [P] [US2] Add compare execution guard regression coverage in `tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php` - [X] T017 [P] [US2] Update effective-snapshot fallback and blocked-state stats coverage in `tests/Feature/Baselines/BaselineCompareStatsTest.php` - [X] T018 [P] [US2] Add compare/capture confirmation and authorization regression coverage in `tests/Feature/Filament/BaselineActionAuthorizationTest.php` ### Implementation for User Story 2 - [X] T019 [US2] Resolve only effective consumable snapshots and block historical explicit overrides in `app/Services/Baselines/BaselineCompareService.php` - [X] T020 [US2] Reject non-consumable snapshots during job execution in `app/Jobs/CompareBaselineToTenantJob.php` - [X] T021 [US2] Derive compare availability from effective snapshot truth in `app/Support/Baselines/BaselineCompareStats.php` - [X] T022 [US2] Surface blocked compare reasons while preserving confirmation and authorization rules on the tenant compare page in `app/Filament/Pages/BaselineCompareLanding.php` - [X] T023 [US2] Sync compare warning widgets with blocked-state stats in `app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php` and `app/Filament/Widgets/Dashboard/BaselineCompareNow.php` **Checkpoint**: Compare can only run against complete snapshots and reports clear reasons when no consumable baseline exists. --- ## Phase 5: User Story 3 - See Run Truth And Artifact Truth Separately (Priority: P3) **Goal**: Operators can distinguish run outcome, snapshot lifecycle, snapshot usability, and historical status across the affected workspace and tenant surfaces. **Independent Test**: Review baseline profile detail, baseline snapshot list/detail, compare landing, and run detail for complete, incomplete, and historically superseded snapshots; each surface must present run truth and artifact truth as separate concepts. ### Tests for User Story 3 ⚠️ - [X] T024 [P] [US3] Extend governance artifact-truth badge coverage in `tests/Unit/Badges/GovernanceArtifactTruthTest.php` - [X] T025 [P] [US3] Add BaselineSnapshot artifact-truth presenter tests in `tests/Unit/Support/GovernanceArtifactTruth/BaselineSnapshotArtifactTruthTest.php` - [X] T026 [P] [US3] Add baseline profile, snapshot, and compare truth-surface coverage in `tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php` - [X] T027 [P] [US3] Add monitoring run-detail baseline truth coverage in `tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php` ### Implementation for User Story 3 - [X] T028 [US3] Update BaselineSnapshot truth envelopes in `app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php` - [X] T029 [US3] Show lifecycle and usability state in `app/Filament/Resources/BaselineSnapshotResource.php` - [X] T030 [US3] Show effective-vs-latest snapshot truth in `app/Filament/Resources/BaselineProfileResource.php` - [X] T031 [US3] Align capture and compare header actions with current-truth, confirmation, and authorization rules in `app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php` - [X] T032 [US3] Update snapshot detail enterprise state in `app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php` - [X] T033 [US3] Separate run outcome from snapshot truth on monitoring run detail in `app/Filament/Resources/OperationRunResource.php` **Checkpoint**: Operators can read baseline trust accurately without inferring artifact completeness from run outcome alone. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Finish legacy handling, regression coverage, and validation for the complete feature. - [X] T034 [P] Add deterministic expected-item decision-table coverage for legacy backfill in `tests/Feature/Baselines/BaselineSnapshotBackfillTest.php` - [X] T035 Update expected-item decision-table legacy backfill branches in `database/migrations/2026_03_23_000001_add_lifecycle_state_to_baseline_snapshots_table.php` - [X] T036 [P] Refresh lifecycle taxonomy regression coverage in `tests/Unit/Badges/OperatorOutcomeTaxonomyTest.php` - [X] T037 [P] Add lifecycle auditability coverage for producing-run links, incomplete reasons, and derived historical truth in `tests/Feature/Baselines/BaselineSnapshotLifecycleAuditabilityTest.php` - [X] T038 [P] Add Ops-UX guard coverage for service-owned run transitions and canonical terminal notifications in `tests/Feature/Operations/BaselineOperationRunGuardTest.php` --- ## Dependencies & Execution Order ### Phase Dependencies - **Setup (Phase 1)**: Starts immediately. - **Foundational (Phase 2)**: Depends on Setup completion and blocks all user stories. - **User Stories (Phases 3-5)**: All depend on Foundational completion. - **Polish (Phase 6)**: Depends on the desired user stories being complete. ### User Story Dependencies - **User Story 1 (P1)**: Starts after Foundational and delivers the MVP. - **User Story 2 (P2)**: Starts after Foundational; it depends on shared lifecycle and resolver infrastructure but not on US1 implementation order. - **User Story 3 (P3)**: Starts after Foundational; it depends on shared lifecycle and badge infrastructure but can proceed independently of US1 and US2 if teams split work. ### Within Each User Story - Write tests first and confirm they fail before implementation. - Update shared/domain helpers before wiring them into services, jobs, or Filament surfaces. - Finish model/service/job behavior before final UI and stats integration. - Keep each story independently verifiable against its stated checkpoint. ## Parallel Opportunities - `T002` and `T003` can run in parallel after `T001`. - `T005` through `T009` can run in parallel once `T004` defines the model lifecycle contract. - Story test tasks marked `[P]` can run in parallel within each user story. - UI tasks in US3 can split across separate resources/pages once `T026` lands the shared artifact-truth envelope changes. ## Parallel Example: User Story 1 ```bash # Write and run the capture-focused tests in parallel: T010 tests/Unit/Baselines/BaselineSnapshotLifecycleTest.php T011 tests/Feature/Baselines/BaselineCaptureTest.php # After tests exist, split the model/job work: T012 app/Models/BaselineProfile.php T013 app/Jobs/CaptureBaselineSnapshotJob.php ``` ## Parallel Example: User Story 2 ```bash # Compare guard tests can be prepared together: T015 tests/Feature/Baselines/BaselineComparePreconditionsTest.php T016 tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php T017 tests/Feature/Baselines/BaselineCompareStatsTest.php T018 tests/Feature/Filament/BaselineActionAuthorizationTest.php # Then service/job/page updates can be split by file: T019 app/Services/Baselines/BaselineCompareService.php T020 app/Jobs/CompareBaselineToTenantJob.php T022 app/Filament/Pages/BaselineCompareLanding.php ``` ## Parallel Example: User Story 3 ```bash # Shared truth tests can be prepared together: T024 tests/Unit/Badges/GovernanceArtifactTruthTest.php T025 tests/Unit/Support/GovernanceArtifactTruth/BaselineSnapshotArtifactTruthTest.php T026 tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php T027 tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php # After T028 lands shared presenter changes, UI files can split: T029 app/Filament/Resources/BaselineSnapshotResource.php T030 app/Filament/Resources/BaselineProfileResource.php T033 app/Filament/Resources/OperationRunResource.php ``` ## Implementation Strategy ### MVP First 1. Complete Phase 1 and Phase 2. 2. Deliver User Story 1 as the MVP so capture truth is no longer ambiguous. 3. Validate US1 with the focused capture lifecycle tests before moving on. ### Incremental Delivery 1. Add User Story 2 to block unsafe compare input once capture truth is explicit. 2. Add User Story 3 to make the new truth model visible and operator-safe across the affected surfaces. 3. Finish Phase 6 for deterministic legacy backfill and regression hardening. ### Suggested MVP Scope - Phase 1: Setup - Phase 2: Foundational - Phase 3: User Story 1 only