-- Durable browser-corpus projections and append-only review evidence. CREATE TABLE capture_labels ( capture_id TEXT PRIMARY KEY REFERENCES captures(capture_id) ON DELETE RESTRICT, classification_json TEXT NOT NULL CHECK(length(classification_json) BETWEEN 2 AND 4096), revision INTEGER NOT NULL DEFAULT 0 CHECK(revision >= 0), labeled_at TEXT NOT NULL ); CREATE TABLE capture_label_evidence ( evidence_id INTEGER PRIMARY KEY, capture_id TEXT NOT NULL REFERENCES captures(capture_id) ON DELETE RESTRICT, replaced_revision INTEGER NOT NULL CHECK(replaced_revision >= 0), classification_json TEXT NOT NULL CHECK(length(classification_json) BETWEEN 2 AND 4096), replaced_at TEXT NOT NULL, UNIQUE(capture_id, replaced_revision) ); CREATE INDEX capture_label_evidence_capture ON capture_label_evidence(capture_id, evidence_id); CREATE INDEX captures_blob_sha256 ON captures(blob_sha256); CREATE INDEX jobs_capture_id ON jobs(capture_id); CREATE INDEX ocr_runs_capture_id ON ocr_runs(capture_id); CREATE INDEX runtime_failures_capture_subject ON runtime_failures(subject_type, subject_id); CREATE INDEX lineage_child_id ON lineage(child_id); CREATE INDEX lineage_parent_id ON lineage(parent_id); CREATE TABLE capture_rejections ( rejection_id INTEGER PRIMARY KEY, capture_id TEXT NOT NULL UNIQUE REFERENCES captures(capture_id) ON DELETE RESTRICT, rejected_at TEXT NOT NULL ); CREATE TABLE capture_deletion_intents ( blob_sha256 TEXT PRIMARY KEY REFERENCES blobs(sha256) ON DELETE RESTRICT, capture_id TEXT NOT NULL UNIQUE CHECK(length(capture_id) BETWEEN 8 AND 64), byte_size INTEGER NOT NULL CHECK(byte_size > 0 AND byte_size <= 67108864), capture_state TEXT NOT NULL CHECK(length(capture_state) BETWEEN 1 AND 32), received_at TEXT NOT NULL CHECK(length(received_at) BETWEEN 1 AND 40), receipt_token TEXT NOT NULL UNIQUE CHECK(length(receipt_token) BETWEEN 1 AND 128), failure_reason TEXT, revision INTEGER NOT NULL CHECK(revision >= 0), created_at TEXT NOT NULL CHECK(length(created_at) BETWEEN 1 AND 40) );