# Tasks: Baseline Capture Truthful Outcomes and Upstream Guardrails

**Input**: Design documents from `/specs/235-baseline-capture-truth/`
**Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `quickstart.md`

**Tests**: Required. This feature changes runtime behavior and operator truth on an existing queued workflow, so Pest coverage must be added or updated in `apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php`, `apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php`, `apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php`, `apps/platform/tests/Feature/Filament/BaselineCaptureResultExplanationSurfaceTest.php`, `apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php`, `apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php`, `apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php`, `apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php`, and `apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php`. `apps/platform/tests/Feature/Baselines/BaselineSnapshotBackfillTest.php` remains conditional and is only updated if implementation proves historical empty complete snapshots still affect current runtime truth.
**Operations**: Existing `baseline_capture` `OperationRun` remains canonical. Tasks below explicitly preserve the Ops-UX 3-surface feedback contract, keep `OperationRun.status` and `OperationRun.outcome` service-owned through `apps/platform/app/Services/OperationRunService.php`, keep `summary_counts` flat and numeric-only, avoid any queued/running DB notification drift, and preserve initiator-null Monitoring-only behavior for scheduled/system runs.
**RBAC**: No new authorization model is introduced, but the touched admin `/admin`, tenant-context `/admin/t/{tenant}/baseline-compare`, and Monitoring `/admin/operations/{run}` surfaces must preserve current capability enforcement and `404` versus `403` semantics through existing helpers and regression coverage in `apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php`.
**UI Naming**: Operator-facing copy must remain baseline-domain specific and centralized through `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php`, `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php`, `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, and `apps/platform/app/Support/Ui/OperatorExplanation/OperatorExplanationBuilder.php`. No task may introduce page-local copy branches for blocked or no-data baseline capture truth.
**Cross-Cutting Shared Pattern Reuse**: This is a shared interaction slice. Extend `apps/platform/app/Support/Baselines/BaselineReasonCodes.php`, `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php`, `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php`, `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, and `apps/platform/app/Support/Ui/OperatorExplanation/OperatorExplanationBuilder.php` before considering any local UI branching.
**UI / Surface Guardrails**: `review-mandatory` slice. Surfaces stay `native` Filament plus shared baseline/Ops UX primitives. Required coverage is `standard-native-filament` plus `monitoring-state-page`; no exception path is planned.
**Filament UI Action Surfaces**: No new Resource, Page, or destructive action is introduced. `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`, `apps/platform/app/Filament/Pages/BaselineCompareLanding.php`, and `apps/platform/app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php` keep their current action topology, existing confirmation-gated capture actions, and current global-search-disabled posture.
**Badges**: No new badge domain or outcome family is introduced. Existing blocked and `partially_succeeded` semantics remain centralized through current outcome and Ops UX renderers; avoid ad-hoc badge/status mappings in Filament.

**Organization**: Tasks are grouped by user story so each slice stays independently testable. Recommended delivery order is `US1` then `US2` then `US3`, because zero-subject and Monitoring truth depend on the shared reason-code and run-context groundwork from the false-green capture fix.

## 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 heavy-governance or 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 or `standard-native-filament` relief is explicit.
- [X] Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.

## Phase 1: Setup (Shared Anchors)

**Purpose**: Lock the implementation anchors and proving commands before touching runtime truth.

- [X] T001 [P] Verify the feature anchor inventory across `apps/platform/app/Services/Baselines/BaselineCaptureService.php`, `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php`, `apps/platform/app/Support/Baselines/BaselineReasonCodes.php`, `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php`, `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php`, `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`, `apps/platform/app/Filament/Pages/BaselineCompareLanding.php`, and `apps/platform/app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php`
- [X] T002 [P] Verify the narrow proving commands, guardrail class, and validation-lane expectations in `specs/235-baseline-capture-truth/plan.md` and `specs/235-baseline-capture-truth/quickstart.md`

**Checkpoint**: Runtime anchors and proof commands are locked before implementation begins.

---

## Phase 2: Foundational (Blocking Truth Boundaries)

**Purpose**: Audit the shared boundaries that every story depends on so the implementation does not widen or drift into local fixes.

**CRITICAL**: No user story work should begin until this phase is complete.

- [X] T003 [P] Audit latest relevant inventory lookup, terminal-outcome interpretation, and no-stale-fallback boundaries in `apps/platform/app/Services/Baselines/BaselineCaptureService.php` and `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php`
- [X] T004 [P] Audit current baseline promotion and consumability boundaries in `apps/platform/app/Models/BaselineProfile.php`, `apps/platform/app/Models/BaselineSnapshot.php`, and `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php`
- [X] T005 [P] Audit shared explanation and copy consumers across `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php`, `apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php`, `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, `apps/platform/app/Support/Ui/OperatorExplanation/OperatorExplanationBuilder.php`, `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`, `apps/platform/app/Filament/Pages/BaselineCompareLanding.php`, and `apps/platform/app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php`
- [X] T006 [P] Audit existing `baseline_capture` run-truth enforcement in `apps/platform/app/Services/OperationRunService.php`, `apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php`, `apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php`, and `apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php` so service-owned transitions, numeric `summary_counts`, and `404` versus `403` expectations are explicit before story work begins

**Checkpoint**: The shared inventory, artifact-truth, Ops-UX, and auth boundaries are explicit and safe to extend.

---

## Phase 3: User Story 1 - Block False-Green Capture Starts (Priority: P1) 🎯 MVP

**Goal**: Prevent baseline capture from reporting success when the latest relevant inventory basis is missing, blocked, failed, or otherwise non-credible.

**Independent Test**: Seed no inventory, blocked latest inventory, failed latest inventory, unusable coverage, and after-enqueue drift scenarios, then prove capture start or execution never lands on `succeeded` and never advances effective baseline truth.

### Tests for User Story 1

- [X] T007 [P] [US1] Expand `apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php` for no inventory, blocked latest inventory, failed latest inventory, unusable coverage, after-enqueue prerequisite drift, older-success-does-not-fallback, and clean consumable-success scenarios including the success-path run-context and audit metadata contract
- [X] T008 [P] [US1] Expand `apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php` for shared preflight blocking copy and preserved confirmation-gated capture action topology on `Capture baseline` and `Capture baseline (full content)` actions
- [X] T009 [P] [US1] Expand `apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php` to preserve the authorized happy-path access proof plus `404` versus `403` semantics on the profile capture explanation path and related Monitoring/detail surfaces touched by blocked prerequisite truth

### Implementation for User Story 1

- [X] T010 [P] [US1] Extend `apps/platform/app/Support/Baselines/BaselineReasonCodes.php` with deterministic capture-prerequisite reason codes for missing inventory, blocked inventory, failed inventory, unusable coverage, and `baseline.capture.zero_subjects`
- [X] T011 [P] [US1] Extend `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php` with centralized operator-safe wording and next steps for `Run tenant sync first`, `Latest inventory sync failed`, `Latest inventory sync was blocked`, unusable-coverage outcomes, and `No subjects were in scope`
- [X] T012 [US1] Implement latest relevant inventory eligibility preflight in `apps/platform/app/Services/Baselines/BaselineCaptureService.php` so known non-credible prerequisites short-circuit before `OperationRun` creation
- [X] T013 [US1] Re-check latest relevant inventory inside `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php` and resolve blocked terminal truth through `apps/platform/app/Services/OperationRunService.php` with numeric `summary_counts`, upstream inventory run reference, chosen eligibility decision, terminal reason code, current-baseline-change flag, and no queued/running DB-notification drift
- [X] T014 [US1] Update `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php` and any capture-result explanation consumers to use the shared translated prerequisite truth while preserving existing confirmation-gated action placement and capability enforcement

**Checkpoint**: User Story 1 is independently functional and capture can no longer false-green on non-credible latest inventory truth.

---

## Phase 4: User Story 2 - Keep No-Data Captures Visible but Non-Authoritative (Priority: P2)

**Goal**: Let zero-subject captures remain auditable without allowing them to replace the current trustworthy baseline.

**Independent Test**: Capture against credible inventory that resolves zero in-scope subjects and verify `partially_succeeded`, no promotion of baseline truth, and clear no-data artifact messaging on affected surfaces.

### Tests for User Story 2

- [X] T015 [P] [US2] Expand `apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php` for zero-subject capture, preserved previous consumable snapshot, and absence of `succeeded` when no usable baseline was captured
- [X] T016 [P] [US2] Expand `apps/platform/tests/Feature/Filament/BaselineCaptureResultExplanationSurfaceTest.php` for no-data artifact messaging, current-versus-historical truth on profile and snapshot explanation surfaces, and profile-level compare affordance guidance after blocked or no-data capture outcomes
- [X] T017 [P] [US2] Expand `apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php` for prior-trustworthy-baseline preservation versus no-current-baseline guidance after blocked latest-inventory and zero-subject capture outcomes

### Implementation for User Story 2

- [X] T018 [US2] Refactor zero-subject handling in `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php` to short-circuit before existing consumable snapshot reuse or `active_snapshot_id` promotion, emit `OperationRunOutcome::PartiallySucceeded`, and record the no-data reason, `baseline_capture.subjects_total`, `result.snapshot_lifecycle` when present, plus effect on current baseline truth
- [X] T019 [US2] Reuse existing lifecycle/usability semantics in `apps/platform/app/Models/BaselineSnapshot.php` and the finalization payloads from `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php` so any zero-subject artifact stays non-consumable and stores no-data finalization metadata instead of a new lifecycle state
- [X] T020 [US2] Preserve `BaselineProfile::resolveCurrentConsumableSnapshot()` behavior in `apps/platform/app/Models/BaselineProfile.php` and update `apps/platform/app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php` plus `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php` to distinguish current trustworthy baseline from no-data evidence
- [X] T021 [US2] Update `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Filament/Pages/BaselineCompareLanding.php`, and profile-level compare affordances in `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php` so compare availability derives from effective consumable baseline truth after blocked, failed, or no-data capture outcomes rather than latest capture completion or snapshot existence alone
- [X] T022 [US2] If implementation proves historical empty complete snapshots still influence current runtime truth, adjust the relevant legacy finalization path and `apps/platform/tests/Feature/Baselines/BaselineSnapshotBackfillTest.php` inside the same slice; otherwise record in `specs/235-baseline-capture-truth/quickstart.md` and the active PR close-out note that no compatibility backfill change was required

**Checkpoint**: User Story 2 is independently functional and zero-subject capture remains visible without becoming authoritative baseline truth.

---

## Phase 5: User Story 3 - Explain All-Zero Capture Truth On Monitoring Surfaces (Priority: P3)

**Goal**: Ensure Monitoring leads with the dominant blocked or no-data explanation before raw counts or JSON.

**Independent Test**: Open seeded blocked and zero-subject baseline capture runs in Monitoring and verify the dominant cause and next step appear before diagnostics.

### Tests for User Story 3

- [X] T023 [P] [US3] Expand `apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php` for blocked latest inventory, failed latest inventory, after-enqueue drift, and zero-subject no-usable-baseline headlines
- [X] T024 [P] [US3] Expand `apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php`, `apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php`, and `apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php` for consistent blocked or `partially_succeeded` baseline-capture truth, audit summary wording including whether current baseline truth changed, and initiator-aware terminal notification behavior

### Implementation for User Story 3

- [X] T025 [P] [US3] Extend `apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php` with dominant explanation and next-step branches for blocked latest inventory, after-enqueue drift, failed inventory, unusable coverage, and zero-subject no-data capture
- [X] T026 [US3] Reconcile shared run-detail and operator-explanation consumption across `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php`, `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, and `apps/platform/app/Support/Ui/OperatorExplanation/OperatorExplanationBuilder.php` so Monitoring, compare landing, and audit prose use the same baseline-domain vocabulary and explicitly communicate whether current baseline truth changed without page-local fallbacks
- [X] T027 [US3] Update `apps/platform/app/Notifications/OperationRunCompleted.php` and any baseline-capture completion payload helpers so terminal notification copy reflects the same dominant reason, communicates whether current baseline truth changed, and preserves initiator-aware delivery rules for interactive versus initiator-null runs

**Checkpoint**: User Story 3 is independently functional and Monitoring explains blocked/no-data baseline truth before diagnostics.

---

## Phase 6: Polish & Cross-Cutting Validation

**Purpose**: Finish formatting, verify there is no local truth drift, and run the narrow proving pack.

- [X] T028 [P] Search the touched runtime and surface files `apps/platform/app/Services/Baselines/BaselineCaptureService.php`, `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php`, `apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php`, `apps/platform/app/Support/Baselines/BaselineCompareStats.php`, `apps/platform/app/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php`, `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`, `apps/platform/app/Filament/Pages/BaselineCompareLanding.php`, `apps/platform/app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php`, `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, and `apps/platform/app/Support/Ui/OperatorExplanation/OperatorExplanationBuilder.php` to confirm no page-local explanation branches or stale-success fallback logic remain
- [X] T029 Run formatting for all touched PHP and test files with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- [X] T030 [P] Run the baseline capture and Filament surface validation pack from `specs/235-baseline-capture-truth/quickstart.md` against `apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php`, `apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php`, `apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php`, and `apps/platform/tests/Feature/Filament/BaselineCaptureResultExplanationSurfaceTest.php`
- [X] T031 [P] Run the Monitoring, audit/notification, and authorization validation pack from `specs/235-baseline-capture-truth/quickstart.md` against `apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php`, `apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php`, `apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php`, `apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php`, and `apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php`
- [X] T032 [P] Run `apps/platform/tests/Feature/Baselines/BaselineSnapshotBackfillTest.php` only if `T022` changed legacy empty-snapshot classification behavior
- [X] T033 Record the Guardrail close-out entry in `specs/235-baseline-capture-truth/quickstart.md` and the active PR description for `Guardrail` status, `standard-native-filament` plus `monitoring-state-page` coverage, and whether `T022` resolved as `document-in-feature` or required a follow-up

---

## Dependencies & Execution Order

### Phase Dependencies

- **Setup (Phase 1)**: Starts immediately and locks anchors plus proving commands.
- **Foundational (Phase 2)**: Depends on Setup and blocks all story work until shared truth boundaries are explicit.
- **User Story 1 (Phase 3)**: Depends on Foundational and is the MVP cut.
- **User Story 2 (Phase 4)**: Depends on User Story 1 because zero-subject truth builds on the new reason-code and eligibility groundwork in the same capture workflow.
- **User Story 3 (Phase 5)**: Depends on User Story 1 and User Story 2 because Monitoring must reflect the final blocked and no-data truth contract.
- **Polish (Phase 6)**: Depends on all completed story work.

### User Story Dependencies

- **US1**: No dependency beyond Foundational.
- **US2**: Depends on US1 shared reason-code, run-context, and preflight/runtime truth changes.
- **US3**: Depends on US1 and US2 shared truth being complete.

### Within Each User Story

- Write the story tests first and confirm they fail before implementation is considered complete.
- Keep copy and explanation centralized through shared baseline and Ops UX helpers.
- Preserve current confirmation-gated action topology and existing capability enforcement.
- Preserve `OperationRunService` ownership of terminal status and outcome transitions.
- Finish story-level validation before moving to the next dependent story.

### Parallel Opportunities

- `T001` and `T002` can run in parallel during Setup.
- `T003`, `T004`, `T005`, and `T006` can run in parallel during Foundational work.
- `T007`, `T008`, and `T009` can run in parallel for User Story 1; `T010` and `T011` can also proceed in parallel before `T012` through `T014`.
- `T015`, `T016`, and `T017` can run in parallel for User Story 2 before the implementation sequence `T018` through `T022`.
- `T023` and `T024` can run in parallel for User Story 3 before `T025` through `T027`.
- `T030`, `T031`, and `T032` can run in parallel during final validation when their prerequisites are satisfied.

---

## Parallel Example: User Story 1

```bash
# User Story 1 tests in parallel
T007 apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php
T008 apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php
T009 apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php

# Shared reason and translation groundwork in parallel
T010 apps/platform/app/Support/Baselines/BaselineReasonCodes.php
T011 apps/platform/app/Support/ReasonTranslation/ReasonTranslator.php
```

## Parallel Example: User Story 2

```bash
# User Story 2 tests in parallel
T015 apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php
T016 apps/platform/tests/Feature/Filament/BaselineCaptureResultExplanationSurfaceTest.php
T017 apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php
```

## Parallel Example: User Story 3

```bash
# User Story 3 tests in parallel
T023 apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php
T024 apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php
```

---

## Implementation Strategy

### MVP First (User Story 1 Only)

1. Complete Phase 1: Setup.
2. Complete Phase 2: Foundational.
3. Complete Phase 3: User Story 1.
4. Run `T029` and `T030` before widening the slice.

### Incremental Delivery

1. Ship User Story 1 to eliminate false-green capture starts and runtime success on non-credible latest inventory.
2. Ship User Story 2 to keep zero-subject captures visible but non-authoritative.
3. Ship User Story 3 to align Monitoring with the hardened capture truth.
4. Finish with the final formatting, validation, and guardrail close-out tasks.

### Parallel Team Strategy

1. One contributor can prepare the shared reason-code and translation groundwork while another prepares the User Story 1 proof surfaces.
2. After User Story 1 lands, one contributor can take the zero-subject runtime path while another prepares the User Story 2 surface tests.
3. User Story 3 can start once the blocked and no-data run-context truth is stable enough for Monitoring and Ops UX proof.

---

## Notes

- `[P]` tasks target different files or independent proof surfaces and can be worked in parallel once upstream blockers are cleared.
- `[US1]`, `[US2]`, and `[US3]` map directly to the feature specification user stories.
- No `contracts/` artifact is required for this feature because there is no external API or route contract change.
- The suggested MVP scope is Phase 1 through Phase 3 only.
