TenantAtlas/specs/074-verification-checklist/tasks.md
ahmido 439248ba15 feat: verification report framework (074) (#89)
Implements the 074 verification checklist framework.

Highlights:
- Versioned verification report contract stored in operation_runs.context.verification_report (DB-only viewer).
- Strict sanitizer/redaction (evidence pointers only; no tokens/headers/payloads) + schema validation.
- Centralized BADGE-001 semantics for check status, severity, and overall report outcome.
- Deterministic start (dedupe while active) via shared StartVerification service; capability-first authorization (non-member 404, member missing capability 403).
- Completion audit event (verification.completed) with redacted metadata.
- Integrations: OperationRun detail viewer, onboarding wizard verification step, provider connection start surfaces.

Tests:
- vendor/bin/sail artisan test --compact tests/Feature/Verification tests/Unit/Badges/VerificationBadgesTest.php
- vendor/bin/sail bin pint --dirty

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #89
2026-02-03 23:58:17 +00:00

8.0 KiB
Raw Blame History

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)

  • 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.
  • 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).
  • T003 [P] [US1] Add report redaction/sanitization utility in app/Support/Verification/VerificationReportSanitizer.php (denylist keys/values; enforce evidence pointers only).
  • 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

  • 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).
  • 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)

  • T007 [P] [US1] Add badge domains for verification status/severity in app/Support/Badges/BadgeDomain.php.
  • T008 [P] [US1] Add domain mappers in app/Support/Badges/Domains/* (e.g., VerificationCheckStatusBadge, VerificationCheckSeverityBadge).
  • T009 [US1] Register domains in app/Support/Badges/BadgeCatalog.php.
  • 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 whats 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)

  • 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).
  • T012 [US1] Add a redaction test in tests/Feature/Verification/VerificationReportRedactionTest.php to ensure forbidden keys/values never appear in stored/rendered evidence.
  • T013 [US1] Add a “malformed/missing report” viewer test in tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php (safe empty state).

Implementation

  • 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).
  • 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.
  • 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

  • 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).
  • T018 [US2] Add a “new run after completion” test in tests/Feature/Verification/VerificationStartAfterCompletionTest.php.

Implementation

  • 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.
  • 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.
  • 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

  • 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

  • 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.
  • 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)

  • T025 [US1] Add a stable audit action ID for verification completion in app/Support/Audit/AuditActionId.php.
  • 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).
  • 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.
  • 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.
  • 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

  • T027 [P] Add UI polish for empty/missing report state in the viewer (no leaks of internal details).
  • T028 Run formatting: vendor/bin/sail bin pint --dirty.
  • 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.