TenantAtlas/specs/075-verification-v1-5/plan.md

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