TenantAtlas/specs/159-baseline-snapshot-truth/tasks.md
ahmido 8426741068 feat: add baseline snapshot truth guards (#189)
## Summary
- add explicit BaselineSnapshot lifecycle truth with conservative backfill and a shared truth resolver
- block baseline compare from building, incomplete, or superseded snapshots and align workspace/tenant UI truth surfaces with effective snapshot state
- surface artifact truth separately from operation outcome across baseline profile, snapshot, compare, and operation run pages

## Testing
- integrated browser smoke test on the active feature surfaces
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php`
- targeted baseline lifecycle and compare guard coverage added in Pest
- `vendor/bin/sail bin pint --dirty --format agent`

## Notes
- Livewire v4 compliance preserved
- no panel provider registration changes were needed; Laravel 12 providers remain in `bootstrap/providers.php`
- global search remains disabled for the affected baseline resources by design
- destructive actions remain confirmation-gated; capture and compare actions keep their existing authorization and confirmation behavior
- no new panel assets were added; existing deploy flow for `filament:assets` is unchanged

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #189
2026-03-23 11:32:00 +00:00

13 KiB

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.

  • T001 Add BaselineSnapshot lifecycle/backfill schema changes in database/migrations/2026_03_23_000001_add_lifecycle_state_to_baseline_snapshots_table.php
  • T002 [P] Create the BaselineSnapshot lifecycle enum in app/Support/Baselines/BaselineSnapshotLifecycleState.php
  • 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.

  • T004 Update lifecycle casts, transition helpers, and consumable scopes in app/Models/BaselineSnapshot.php
  • T005 [P] Add effective-snapshot and consumability resolution in app/Services/Baselines/BaselineSnapshotTruthResolver.php
  • T006 [P] Add non-consumable baseline reason codes in app/Support/Baselines/BaselineReasonCodes.php
  • T007 [P] Add lifecycle/operator-safe reason translations in app/Support/ReasonTranslation/ReasonTranslator.php
  • T008 [P] Register the new lifecycle badge domain in app/Support/Badges/BadgeDomain.php and app/Support/Badges/BadgeCatalog.php
  • 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.

  • T010 [P] [US1] Add BaselineSnapshot lifecycle domain tests in tests/Unit/Baselines/BaselineSnapshotLifecycleTest.php
  • T011 [P] [US1] Update capture lifecycle and partial-write regression coverage in tests/Feature/Baselines/BaselineCaptureTest.php

Implementation for User Story 1

  • T012 [US1] Add current-consumable snapshot helpers to app/Models/BaselineProfile.php
  • T013 [US1] Create building snapshots and completion-proof finalization in app/Jobs/CaptureBaselineSnapshotJob.php
  • 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 ⚠️

  • T015 [P] [US2] Update compare precondition coverage for building/incomplete snapshots in tests/Feature/Baselines/BaselineComparePreconditionsTest.php
  • T016 [P] [US2] Add compare execution guard regression coverage in tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php
  • T017 [P] [US2] Update effective-snapshot fallback and blocked-state stats coverage in tests/Feature/Baselines/BaselineCompareStatsTest.php
  • T018 [P] [US2] Add compare/capture confirmation and authorization regression coverage in tests/Feature/Filament/BaselineActionAuthorizationTest.php

Implementation for User Story 2

  • T019 [US2] Resolve only effective consumable snapshots and block historical explicit overrides in app/Services/Baselines/BaselineCompareService.php
  • T020 [US2] Reject non-consumable snapshots during job execution in app/Jobs/CompareBaselineToTenantJob.php
  • T021 [US2] Derive compare availability from effective snapshot truth in app/Support/Baselines/BaselineCompareStats.php
  • T022 [US2] Surface blocked compare reasons while preserving confirmation and authorization rules on the tenant compare page in app/Filament/Pages/BaselineCompareLanding.php
  • 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 ⚠️

  • T024 [P] [US3] Extend governance artifact-truth badge coverage in tests/Unit/Badges/GovernanceArtifactTruthTest.php
  • T025 [P] [US3] Add BaselineSnapshot artifact-truth presenter tests in tests/Unit/Support/GovernanceArtifactTruth/BaselineSnapshotArtifactTruthTest.php
  • T026 [P] [US3] Add baseline profile, snapshot, and compare truth-surface coverage in tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php
  • T027 [P] [US3] Add monitoring run-detail baseline truth coverage in tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php

Implementation for User Story 3

  • T028 [US3] Update BaselineSnapshot truth envelopes in app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php
  • T029 [US3] Show lifecycle and usability state in app/Filament/Resources/BaselineSnapshotResource.php
  • T030 [US3] Show effective-vs-latest snapshot truth in app/Filament/Resources/BaselineProfileResource.php
  • T031 [US3] Align capture and compare header actions with current-truth, confirmation, and authorization rules in app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
  • T032 [US3] Update snapshot detail enterprise state in app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php
  • 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.

  • T034 [P] Add deterministic expected-item decision-table coverage for legacy backfill in tests/Feature/Baselines/BaselineSnapshotBackfillTest.php
  • T035 Update expected-item decision-table legacy backfill branches in database/migrations/2026_03_23_000001_add_lifecycle_state_to_baseline_snapshots_table.php
  • T036 [P] Refresh lifecycle taxonomy regression coverage in tests/Unit/Badges/OperatorOutcomeTaxonomyTest.php
  • T037 [P] Add lifecycle auditability coverage for producing-run links, incomplete reasons, and derived historical truth in tests/Feature/Baselines/BaselineSnapshotLifecycleAuditabilityTest.php
  • 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

# 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

# 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

# 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