# Tasks: 074 Verification Checklist Framework

**Input**: Design documents from `/specs/074-verification-checklist/`
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/

**Tests**: Required (Pest).

---

## Phase 1: Foundational (Blocking Prerequisites)

- [x] T001 [US1] Add example reports under specs: `specs/074-verification-checklist/contracts/examples/*.json` (pass/fail/warn/running) aligned to `contracts/verification-report.schema.json`.
- [x] T002 [P] [US1] Add a small schema validation helper for reports (pure PHP, no external deps) in `app/Support/Verification/VerificationReportSchema.php` (version parsing + shape validation + graceful fallback).
- [x] T003 [P] [US1] Add report redaction/sanitization utility in `app/Support/Verification/VerificationReportSanitizer.php` (denylist keys/values; enforce evidence pointers only).
- [x] T004 [US1] Add value objects (or typed arrays) for report/check concepts in `app/Support/Verification/*` (status/severity enums or constants) to avoid ad-hoc strings throughout UI.

**RBAC & UX prereqs**

- [x] T005 [US3] Decide and document the start capability used per verification flow (v1: use `Capabilities::PROVIDER_RUN` for `provider.connection.check`; prefer existing constants in `app/Support/Auth/Capabilities.php`).
- [x] T006 [US3] Add/confirm central UI enforcement helper usage for “visible-but-disabled with tooltip” in verification start UI (use tenant-scoped `app/Support/Rbac/UiEnforcement.php` with a resolved `Tenant` record).

**Badges (BADGE-001)**

- [x] T007 [P] [US1] Add badge domains for verification status/severity in `app/Support/Badges/BadgeDomain.php`.
- [x] T008 [P] [US1] Add domain mappers in `app/Support/Badges/Domains/*` (e.g., `VerificationCheckStatusBadge`, `VerificationCheckSeverityBadge`).
- [x] T009 [US1] Register domains in `app/Support/Badges/BadgeCatalog.php`.
- [x] T010 [US1] Add mapping tests for new badge domains in `tests/Unit/Badges/*`.

**Checkpoint**: Report contract + sanitizer + badge domains exist; UI work can start.

---

## Phase 2: User Story 1 — Operator sees what’s wrong (Priority: P1)

**Goal**: Render a structured, DB-only verification report viewer for a run.

**Independent Test**: Seed an `OperationRun` with `context.verification_report` and assert the viewer renders the correct summary + per-check details, with no outbound HTTP.

### Tests (write first)

- [x] T011 [US1] Add a viewer DB-only test (no outbound HTTP, no job dispatch) in `tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php` using `Http::fake()` + `Bus::fake()` and asserting no requests / no dispatch during page render (including a second render to cover Livewire refresh/poll paths).
- [x] T012 [US1] Add a redaction test in `tests/Feature/Verification/VerificationReportRedactionTest.php` to ensure forbidden keys/values never appear in stored/rendered evidence.
- [x] T013 [US1] Add a “malformed/missing report” viewer test in `tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php` (safe empty state).

### Implementation

- [x] T014 [US1] Create a reusable viewer Blade partial in `resources/views/filament/components/verification-report-viewer.blade.php` (summary banner + counts + collapsible checks + next steps links-only).
- [x] T015 [US1] Create a Filament view entry/helper to render the viewer from an `OperationRun` in `app/Filament/Support/VerificationReportViewer.php` (or existing Filament helpers location), using only DB values.
- [x] T016 [US1] Integrate viewer into Monitoring → Operations run view page: update `app/Filament/Resources/OperationRunResource.php` (infolist) to show the verification report section when `context.verification_report` exists.

**Checkpoint**: A seeded report is readable in Monitoring; viewer is DB-only.

---

## Phase 3: User Story 2 — Deterministic starts (Priority: P2)

**Goal**: Starting verification is idempotent while active (dedupe) and guides users to the active run.

**Independent Test**: Start verification twice for the same identity and assert a single active run is used.

### Tests

- [x] T017 [US2] Add a dedupe regression test in `tests/Feature/Verification/VerificationStartDedupeTest.php` asserting repeated starts reuse the same active run (leveraging the existing `OperationRunService::ensureRunWithIdentity()` behavior).
- [x] T018 [US2] Add a “new run after completion” test in `tests/Feature/Verification/VerificationStartAfterCompletionTest.php`.

### Implementation

- [x] T019 [US2] Add (or adapt) a small “start verification” service wrapper in `app/Services/Verification/StartVerification.php` that: authorizes, creates/reuses a run identity, enqueues a verifier job, and returns the run.
- [x] T020 [US2] Update the managed tenant onboarding verification step to route through the shared starter and replace the binary status UI with the shared verification report viewer (or a safe empty state) in `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`.
- [x] T021 [US2] Update provider connection verification start surface(s) (where present) to route through the same shared starter.

**Checkpoint**: Starts are deterministic and route users to the active run.

---

## Phase 4: User Story 3 — Least-privilege and safe disclosure (Priority: P3)

**Goal**: View vs start capability split; non-members get 404; members lacking start capability get 403 on execution.

**Independent Test**: Readonly member can view report but cannot start; non-member cannot discover tenant/run.

### Tests

- [x] T022 [US3] Add authorization tests for view vs start in `tests/Feature/Verification/VerificationAuthorizationTest.php` covering:
  - tenant non-member → 404 on view + start
  - tenant member without start capability → can view, start returns forbidden (403)
  - tenant member with start capability → can start

### Implementation

- [x] T023 [US3] Ensure start actions enforce server-side authorization via Gate/Policy (no UI-only enforcement) and use capability constants from `app/Support/Auth/Capabilities.php`.
- [x] T024 [US3] Ensure tenant-scope non-membership yields deny-as-not-found behavior for verification routes/actions (align with existing tenant routing patterns and helpers).

**Checkpoint**: Authorization behavior matches RBAC-UX contract.

---

## Phase 5: Audit & Completion Events (Cross-cutting)

- [x] T025 [US1] Add a stable audit action ID for verification completion in `app/Support/Audit/AuditActionId.php`.
- [x] T026 [US1] Emit a completion audit event when a verification run finalizes (where run completion is set) using `app/Services/Audit/WorkspaceAuditLogger.php` with redacted metadata (run id + counts only).
- [x] T030 [US1] Add a report writer in `app/Support/Verification/VerificationReportWriter.php` that builds `context.verification_report`, derives `summary.overall` deterministically, enforces reason codes + evidence pointer-only policy, and runs sanitizer before persistence.
- [x] T031 [US1] Integrate the report writer into `app/Jobs/ProviderConnectionHealthCheckJob.php` so `provider.connection.check` writes a compliant `verification_report` to the run (both success and failure paths) before marking the run completed.
- [x] T032 [US1] Add a report-writing integration test in `tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php` ensuring the run ends with a valid, sanitized `context.verification_report` (and no forbidden evidence fields).

---

## Phase 6: Polish & Regression Guards

- [x] T027 [P] Add UI polish for empty/missing report state in the viewer (no leaks of internal details).
- [x] T028 Run formatting: `vendor/bin/sail bin pint --dirty`.
- [x] T029 Run targeted tests: `vendor/bin/sail artisan test --compact tests/Feature/Verification`.

---

## Dependencies & Execution Order

- Phase 1 (Foundational) blocks all other phases.
- US1 can start after Phase 1; US2/US3 can proceed after Phase 1 but should reuse US1 primitives (viewer + sanitizer + badges).
- Audit completion (Phase 5) depends on the shared verification job/service that finalizes runs.
