Implements Spec 075 (V1.5) on top of Spec 074. Highlights - Deterministic report fingerprint (sha256) + previous_report_id linkage - Viewer change indicator: "No changes" vs "Changed" when previous exists - Check acknowledgements (fail|warn|block) with capability-first auth, confirmation, and audit event - Verify-step UX polish (issues-first, primary CTA) Testing - Focused Pest coverage for fingerprint, previous resolver, change indicator, acknowledgements, badge semantics, DB-only viewer guard. Notes - Viewing remains DB-only (no external calls while rendering). Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box> Reviewed-on: #93
7.4 KiB
Implementation Plan: Verification Checklist Framework V1.5 (Governance + Supportability + UI-Complete)
Branch: 075-verification-v1_5 | Date: 2026-02-05 | Spec: 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)
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)
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
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:
Design focus:
- Report metadata: add
fingerprintandprevious_report_idinside the report JSON. - Previous report resolution: match identity exactly (type/flow + tenant + workspace + provider connection), with
NULLconnection matching onlyNULL. - 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_acknowledgementstable with unique(operation_run_id, check_key). - Model:
VerificationCheckAcknowledgementwith tenant/workspace scoping.
Report writer / viewer
- Extend the report writer to compute and store
fingerprintandprevious_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.acknowledgeto 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 noack_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 (
NULLonly matchesNULL). - RBAC-UX: non-member gets 404; member without capability gets 403 on acknowledgement.
- Audit: acknowledgement emits correct action id + minimal metadata (assert
ack_reasonabsent). - 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.