Files
breakpilot-compliance/backend-compliance/migrations/076_anti_fake_evidence.sql
Benjamin Admin e6201d5239 feat: Anti-Fake-Evidence System (Phase 1-4b)
Implement full evidence integrity pipeline to prevent compliance theater:
- Confidence levels (E0-E4), truth status tracking, assertion engine
- Four-Eyes approval workflow, audit trail, reject endpoint
- Evidence distribution dashboard, LLM audit routes
- Traceability matrix (backend endpoint + Compliance Hub UI tab)
- Anti-fake badges, control status machine, normative patterns
- 2 migrations, 4 test suites, MkDocs documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:15:45 +01:00

126 lines
5.8 KiB
SQL

-- Migration 076: Anti-Fake-Evidence Guardrails (Phase 1)
--
-- Prevents "Compliance-Theater": generated content passed off as real evidence,
-- controls without evidence marked as "pass", unvalidated 100% compliance claims.
--
-- Changes:
-- 1. New ENUM types for evidence confidence + truth status
-- 2. New columns on compliance_evidence (confidence, truth, review tracking)
-- 3. New value 'in_progress' for controlstatusenum
-- 4. status_justification column on compliance_controls
-- 5. New table compliance_llm_generation_audit
-- 6. Backfill existing evidence based on source
-- 7. Indexes on new columns
-- ============================================================================
-- 1. New ENUM types
-- ============================================================================
-- NOTE: CREATE TYPE cannot run inside a transaction block when combined with
-- ALTER TYPE ... ADD VALUE. Each statement here is auto-committed separately
-- when executed outside a transaction (which is the default for psql scripts).
CREATE TYPE evidence_confidence_level AS ENUM (
'E0', -- Generated / no real evidence (LLM output, placeholder)
'E1', -- Uploaded but unreviewed (manual upload, no hash, no reviewer)
'E2', -- Reviewed internally (human reviewed, hash verified)
'E3', -- Observed by system (CI/CD pipeline, API with hash)
'E4' -- Validated by external auditor
);
CREATE TYPE evidence_truth_status AS ENUM (
'generated', -- Created by LLM / system generation
'uploaded', -- Manually uploaded by user
'observed', -- Automatically observed (CI/CD, monitoring)
'validated_internal', -- Reviewed + approved by internal reviewer
'rejected', -- Reviewed and rejected
'provided_to_auditor', -- Shared with external auditor
'accepted_by_auditor' -- Accepted by external auditor
);
-- ============================================================================
-- 2. Add 'in_progress' to controlstatusenum
-- ============================================================================
-- ALTER TYPE ... ADD VALUE cannot run inside a transaction.
ALTER TYPE controlstatusenum ADD VALUE IF NOT EXISTS 'in_progress';
-- ============================================================================
-- 3. New columns on compliance_evidence
-- ============================================================================
ALTER TABLE compliance_evidence
ADD COLUMN IF NOT EXISTS confidence_level evidence_confidence_level DEFAULT 'E1',
ADD COLUMN IF NOT EXISTS truth_status evidence_truth_status DEFAULT 'uploaded',
ADD COLUMN IF NOT EXISTS generation_mode VARCHAR(100),
ADD COLUMN IF NOT EXISTS may_be_used_as_evidence BOOLEAN DEFAULT TRUE,
ADD COLUMN IF NOT EXISTS reviewed_by VARCHAR(200),
ADD COLUMN IF NOT EXISTS reviewed_at TIMESTAMPTZ;
-- ============================================================================
-- 4. status_justification on compliance_controls
-- ============================================================================
ALTER TABLE compliance_controls
ADD COLUMN IF NOT EXISTS status_justification TEXT;
-- ============================================================================
-- 5. LLM Generation Audit table
-- ============================================================================
CREATE TABLE IF NOT EXISTS compliance_llm_generation_audit (
id VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::text,
tenant_id VARCHAR(36),
entity_type VARCHAR(50) NOT NULL, -- 'evidence', 'control', 'document', ...
entity_id VARCHAR(36), -- FK to the generated entity
generation_mode VARCHAR(100) NOT NULL, -- 'draft_assistance', 'auto_generation', ...
truth_status evidence_truth_status NOT NULL DEFAULT 'generated',
may_be_used_as_evidence BOOLEAN NOT NULL DEFAULT FALSE,
llm_model VARCHAR(100),
llm_provider VARCHAR(50), -- 'ollama', 'anthropic', ...
prompt_hash VARCHAR(64), -- SHA-256 of the prompt
input_summary TEXT, -- Truncated input for auditability
output_summary TEXT, -- Truncated output for auditability
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- ============================================================================
-- 6. Backfill existing evidence based on source
-- ============================================================================
-- CI pipeline evidence → E3 + observed
UPDATE compliance_evidence
SET confidence_level = 'E3',
truth_status = 'observed'
WHERE source = 'ci_pipeline'
AND confidence_level = 'E1';
-- API evidence → E3 + observed
UPDATE compliance_evidence
SET confidence_level = 'E3',
truth_status = 'observed'
WHERE source = 'api'
AND confidence_level = 'E1';
-- Manual/upload evidence stays at E1 + uploaded (default)
-- Generated evidence → E0 + generated
UPDATE compliance_evidence
SET confidence_level = 'E0',
truth_status = 'generated',
may_be_used_as_evidence = FALSE
WHERE source = 'generated'
AND confidence_level = 'E1';
-- ============================================================================
-- 7. Indexes
-- ============================================================================
CREATE INDEX IF NOT EXISTS ix_evidence_confidence ON compliance_evidence (confidence_level);
CREATE INDEX IF NOT EXISTS ix_evidence_truth_status ON compliance_evidence (truth_status);
CREATE INDEX IF NOT EXISTS ix_evidence_may_be_used ON compliance_evidence (may_be_used_as_evidence);
CREATE INDEX IF NOT EXISTS ix_llm_audit_entity ON compliance_llm_generation_audit (entity_type, entity_id);
CREATE INDEX IF NOT EXISTS ix_llm_audit_tenant ON compliance_llm_generation_audit (tenant_id);