# Implementation Plan: Verification Checklist Framework V1.5 (Governance + Supportability + UI-Complete) **Branch**: `075-verification-v1_5` | **Date**: 2026-02-05 | **Spec**: [spec.md](./spec.md) **Input**: Feature specification from `/specs/075-verification-v1-5/spec.md` **Note**: This file is generated from the plan template and then filled in by `/speckit.plan` workflow steps. ## Summary - Extend the existing 074 verification report system with deterministic **fingerprints** and a **previous report** link so the viewer can show “Changed / No changes”. - Introduce per-check **acknowledgements** as first-class records (unique per report + check) with explicit confirmation and audit logging, without changing outcomes (“no greenwashing”). - Update the Verify step UX to be operator-ready: issues-first tabs, centralized badge semantics (BADGE-001), and exactly one primary CTA depending on state. ## Technical Context **Language/Version**: PHP 8.4 (Laravel 12) **Primary Dependencies**: Laravel 12 + Filament v5 + Livewire v4 (Filament v5 requires Livewire v4.0+) **Storage**: PostgreSQL (Sail) with JSONB (`operation_runs.context`) + a new acknowledgement table **Testing**: Pest (PHPUnit) **Target Platform**: Web application (Sail/Docker locally; container deploy via Dokploy) **Project Type**: web **Performance Goals**: DB-only viewer renders quickly from stored JSON; fingerprint computation is linear in number of checks (typical report ≤ 50 checks) **Constraints**: - Viewer + Verify step are DB-only at render time (no outbound HTTP / Graph / job dispatch). - All mutations require server-side authorization (RBAC-UX) and explicit confirmation. - Status-like UI must use centralized badge semantics (BADGE-001). **Scale/Scope**: Multiple tenants/workspaces; many runs over time; verification used in onboarding and provider workflows ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first, snapshots-second: PASS (report/ack UX; no inventory semantics changed). - Read/write separation: PASS (viewer remains read-only; acknowledgements are explicit mutations with confirmation + audit + tests). - Graph contract path: PASS (viewer is DB-only; no new Graph calls added by this feature). - Deterministic capabilities: PASS (capabilities remain centrally registered; no raw strings). - RBAC-UX: PASS (non-member access is 404; member missing capability is 403; server-side enforcement required). - Run observability: PASS (verification remains an `OperationRun`; dedupe while active is unchanged). - Data minimization: PASS (no secrets/tokens; audit payload excludes `ack_reason`). - Badge semantics (BADGE-001): PASS (no new status values; existing verification badge domains remain canonical). ## Project Structure ### Documentation (this feature) ```text specs/075-verification-v1-5/ ├── plan.md # This file ├── research.md # Phase 0 output ├── data-model.md # Phase 1 output ├── quickstart.md # Phase 1 output ├── contracts/ # Phase 1 output └── tasks.md # Phase 2 output (/speckit.tasks) ``` ### Source Code (repository root) ```text app/ ├── Filament/ ├── Jobs/ ├── Models/ ├── Policies/ ├── Services/ └── Support/ database/ └── migrations/ resources/ routes/ tests/ ``` **Structure Decision**: Single Laravel web app with Filament v5 panel. This feature extends verification report writer/viewer, adds an acknowledgement persistence model + migration, and refactors the Verify step UI in Filament. ## Complexity Tracking > **Fill ONLY if Constitution Check has violations that must be justified** | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | [e.g., 4th project] | [current need] | [why 3 projects insufficient] | | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | ## Phase 0 — Research (output: `research.md`) See: [research.md](./research.md) Goals covered: - Confirm canonical storage approach for report metadata (keep report in `operation_runs.context`). - Define deterministic fingerprint algorithm and previous report resolution rules. - Define acknowledgement persistence strategy and capability naming reconciliation. ## Phase 1 — Design & Contracts (outputs: `data-model.md`, `contracts/`, `quickstart.md`) See: - [data-model.md](./data-model.md) - [contracts/](./contracts/) - [quickstart.md](./quickstart.md) Design focus: - Report metadata: add `fingerprint` and `previous_report_id` inside the report JSON. - Previous report resolution: match identity exactly (type/flow + tenant + workspace + provider connection), with `NULL` connection matching only `NULL`. - Acknowledgements: first-class DB table keyed by `(operation_run_id, check_key)`; immutable in v1.5. - Filament UX: issues-first tabs and “one primary CTA” rule; acknowledgements via `Action::make(...)->action(...)` + `->requiresConfirmation()`. ## Phase 2 — Implementation Outline (tasks created in `/speckit.tasks`) ### Data - Migration: create `verification_check_acknowledgements` table with unique `(operation_run_id, check_key)`. - Model: `VerificationCheckAcknowledgement` with tenant/workspace scoping. ### Report writer / viewer - Extend the report writer to compute and store `fingerprint` and `previous_report_id` (report_id is the run id). - Extend the DB-only viewer to load previous report (when present) and compute the “changed/no-change” indicator. - Ensure the viewer consumes acknowledgements (DB lookup) and groups “Acknowledged issues” separately. ### Authorization + audit - Capability: add `tenant_verification.acknowledge` to the canonical capability registry and map to roles. - Server-side auth: non-members 404; members without capability 403 for acknowledgement. - Audit: add a new stable action ID (e.g. `verification.check_acknowledged`) with minimal metadata and no `ack_reason`. ### Filament UX - Verify step: implement the issues-first layout and strict “exactly one primary CTA” rule. - Actions: acknowledgement requires confirmation; navigation-only links remain links-only. - BADGE-001: continue to use centralized badge domains for statuses and summary. ### Tests (Pest) - Fingerprint determinism: same normalized inputs → same hash; severity-only differences → different hash. - Previous report linking: identity match includes provider connection (`NULL` only matches `NULL`). - RBAC-UX: non-member gets 404; member without capability gets 403 on acknowledgement. - Audit: acknowledgement emits correct action id + minimal metadata (assert `ack_reason` absent). - Viewer DB-only: no outbound HTTP during render/hydration. ## Constitution Check (Post-Design) Re-check result: PASS. Design keeps report viewing DB-only, introduces a single tenant-scoped mutation with confirmation + audit, preserves RBAC-UX semantics, and maintains BADGE-001 centralized badge rendering.