TenantAtlas/specs/075-verification-v1-5/data-model.md

115 lines
3.5 KiB
Markdown

# Data Model: Verification Checklist Framework V1.5 (075)
**Date**: 2026-02-05
**Phase**: Phase 1 (Design)
**Status**: Draft (design-complete for implementation planning)
---
## Existing Entity (reference)
### OperationRun (existing)
**Purpose**: Canonical operational record. Verification reports are stored in `operation_runs.context.verification_report` (JSONB).
**Key fields (relevant)**:
- `id`
- `tenant_id`
- `workspace_id`
- `type` (verification flow identifier)
- `run_identity_hash` (identity hash used for active dedupe + identity matching)
- `status`
- `context` (JSONB)
**Verification report storage**:
- `context.verification_report` (JSON object)
---
## New Persistent Entity
### VerificationCheckAcknowledgement (new table)
**Table name**: `verification_check_acknowledgements`
**Purpose**: First-class governance record that a failing/warning check is acknowledged for a specific report (report == operation run).
**Fields**:
- `id` (primary key)
- `tenant_id` (FK or scalar; used for tenant-scoped filtering and isolation checks)
- `workspace_id` (FK or scalar)
- `operation_run_id` (FK to `operation_runs.id`) — the “report”
- `check_key` (string)
- `ack_reason` (string, max 160)
- `expires_at` (timestamp, nullable) — informational only in v1.5
- `acknowledged_at` (timestamp)
- `acknowledged_by_user_id` (FK to `users.id`)
- `created_at`, `updated_at`
**Uniqueness constraint (required)**:
- unique `(operation_run_id, check_key)`
**Indexes (recommended)**:
- `(tenant_id, workspace_id, operation_run_id)`
- `(operation_run_id)`
**Validation rules**:
- `ack_reason`: required, string, length ≤ 160
- `expires_at`: optional, must be a valid timestamp, should be >= acknowledged_at (implementation may enforce)
**State transitions**:
- Immutable per report/check in v1.5: create once; no update/delete/unack flows.
---
## Contracted Document (stored in JSON)
### VerificationReport (JSON in `OperationRun.context.verification_report`)
**Purpose**: Structured, versioned report of verification results used by the DB-only viewer.
**Identity**:
- `report_id`: `operation_runs.id`
- `previous_report_id`: previous run id for same identity (nullable)
**New v1.5 fields**:
- `fingerprint` (string; lowercase hex; SHA-256)
- `previous_report_id` (nullable integer/uuid depending on `OperationRun` PK type)
**Existing core fields (from 074, reference)**:
- `schema_version` (SemVer string; major `1`)
- `flow` (verification flow identifier; aligns with `OperationRun.type`)
- `generated_at` (timestamp)
- `summary` (counts + overall outcome)
- `checks[]` (flat array) including:
- `key`
- `title`
- `status` (`pass|fail|warn|skip|running`)
- `severity` (`info|low|medium|high|critical` or empty string)
- `blocking` (boolean)
- `reason_code` (string)
- safe evidence pointers
- `next_steps[]` (navigation-only links)
**Fingerprint normalization input** (strict):
- Flatten all checks across `checks[]`.
- Sort by `check.key`.
- Contribute the stable tuple string:
- `key|status|blocking|reason_code|severity`
- `severity` must always be present (missing normalized to empty string).
---
## Derived/Computed View Data (not persisted)
### Change indicator
Computed in the viewer by comparing:
- current `verification_report.fingerprint`
- previous `verification_report.fingerprint`
States:
- no previous report → no indicator
- fingerprints match → “No changes since previous verification”
- fingerprints differ → “Changed since previous verification”