-- Migration: Trust Vector Calibration Schema -- Sprint: 7100.0002.0002 -- Description: Creates schema and tables for trust vector calibration system -- Create calibration schema CREATE SCHEMA IF NOT EXISTS excititor_calibration; -- Calibration manifests table -- Stores signed manifests for each calibration epoch CREATE TABLE IF NOT EXISTS excititor_calibration.calibration_manifests ( manifest_id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, epoch_number INTEGER NOT NULL, epoch_start_utc TIMESTAMP NOT NULL, epoch_end_utc TIMESTAMP NOT NULL, sample_count INTEGER NOT NULL, learning_rate DOUBLE PRECISION NOT NULL, policy_hash TEXT, lattice_version TEXT NOT NULL, manifest_json JSONB NOT NULL, signature_envelope JSONB, created_at_utc TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'), created_by TEXT NOT NULL, CONSTRAINT uq_calibration_manifest_tenant_epoch UNIQUE (tenant_id, epoch_number) ); CREATE INDEX idx_calibration_manifests_tenant ON excititor_calibration.calibration_manifests(tenant_id); CREATE INDEX idx_calibration_manifests_created ON excititor_calibration.calibration_manifests(created_at_utc DESC); -- Trust vector adjustments table -- Records each provider's trust vector changes per epoch CREATE TABLE IF NOT EXISTS excititor_calibration.trust_vector_adjustments ( adjustment_id BIGSERIAL PRIMARY KEY, manifest_id TEXT NOT NULL REFERENCES excititor_calibration.calibration_manifests(manifest_id), source_id TEXT NOT NULL, old_provenance DOUBLE PRECISION NOT NULL, old_coverage DOUBLE PRECISION NOT NULL, old_replayability DOUBLE PRECISION NOT NULL, new_provenance DOUBLE PRECISION NOT NULL, new_coverage DOUBLE PRECISION NOT NULL, new_replayability DOUBLE PRECISION NOT NULL, adjustment_magnitude DOUBLE PRECISION NOT NULL, confidence_in_adjustment DOUBLE PRECISION NOT NULL, sample_count_for_source INTEGER NOT NULL, created_at_utc TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'), CONSTRAINT chk_old_provenance_range CHECK (old_provenance >= 0 AND old_provenance <= 1), CONSTRAINT chk_old_coverage_range CHECK (old_coverage >= 0 AND old_coverage <= 1), CONSTRAINT chk_old_replayability_range CHECK (old_replayability >= 0 AND old_replayability <= 1), CONSTRAINT chk_new_provenance_range CHECK (new_provenance >= 0 AND new_provenance <= 1), CONSTRAINT chk_new_coverage_range CHECK (new_coverage >= 0 AND new_coverage <= 1), CONSTRAINT chk_new_replayability_range CHECK (new_replayability >= 0 AND new_replayability <= 1), CONSTRAINT chk_confidence_range CHECK (confidence_in_adjustment >= 0 AND confidence_in_adjustment <= 1) ); CREATE INDEX idx_trust_adjustments_manifest ON excititor_calibration.trust_vector_adjustments(manifest_id); CREATE INDEX idx_trust_adjustments_source ON excititor_calibration.trust_vector_adjustments(source_id); -- Calibration feedback samples table -- Stores empirical evidence used for calibration CREATE TABLE IF NOT EXISTS excititor_calibration.calibration_samples ( sample_id BIGSERIAL PRIMARY KEY, tenant_id TEXT NOT NULL, source_id TEXT NOT NULL, cve_id TEXT NOT NULL, purl TEXT NOT NULL, expected_status TEXT NOT NULL, actual_status TEXT NOT NULL, verdict_confidence DOUBLE PRECISION NOT NULL, is_match BOOLEAN NOT NULL, feedback_source TEXT NOT NULL, -- 'reachability', 'customer_feedback', 'integration_tests' feedback_weight DOUBLE PRECISION NOT NULL DEFAULT 1.0, scan_id TEXT, collected_at_utc TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'), processed BOOLEAN NOT NULL DEFAULT FALSE, processed_in_manifest_id TEXT REFERENCES excititor_calibration.calibration_manifests(manifest_id), CONSTRAINT chk_verdict_confidence_range CHECK (verdict_confidence >= 0 AND verdict_confidence <= 1), CONSTRAINT chk_feedback_weight_range CHECK (feedback_weight >= 0 AND feedback_weight <= 1) ); CREATE INDEX idx_calibration_samples_tenant ON excititor_calibration.calibration_samples(tenant_id); CREATE INDEX idx_calibration_samples_source ON excititor_calibration.calibration_samples(source_id); CREATE INDEX idx_calibration_samples_collected ON excititor_calibration.calibration_samples(collected_at_utc DESC); CREATE INDEX idx_calibration_samples_processed ON excititor_calibration.calibration_samples(processed) WHERE NOT processed; -- Calibration metrics table -- Tracks performance metrics per source/severity/status CREATE TABLE IF NOT EXISTS excititor_calibration.calibration_metrics ( metric_id BIGSERIAL PRIMARY KEY, manifest_id TEXT NOT NULL REFERENCES excititor_calibration.calibration_manifests(manifest_id), source_id TEXT, severity TEXT, status TEXT, precision DOUBLE PRECISION NOT NULL, recall DOUBLE PRECISION NOT NULL, f1_score DOUBLE PRECISION NOT NULL, false_positive_rate DOUBLE PRECISION NOT NULL, false_negative_rate DOUBLE PRECISION NOT NULL, sample_count INTEGER NOT NULL, created_at_utc TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'), CONSTRAINT chk_precision_range CHECK (precision >= 0 AND precision <= 1), CONSTRAINT chk_recall_range CHECK (recall >= 0 AND recall <= 1), CONSTRAINT chk_f1_range CHECK (f1_score >= 0 AND f1_score <= 1), CONSTRAINT chk_fpr_range CHECK (false_positive_rate >= 0 AND false_positive_rate <= 1), CONSTRAINT chk_fnr_range CHECK (false_negative_rate >= 0 AND false_negative_rate <= 1) ); CREATE INDEX idx_calibration_metrics_manifest ON excititor_calibration.calibration_metrics(manifest_id); CREATE INDEX idx_calibration_metrics_source ON excititor_calibration.calibration_metrics(source_id) WHERE source_id IS NOT NULL; -- Grant permissions to excititor service role DO $$ BEGIN IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'excititor_service') THEN GRANT USAGE ON SCHEMA excititor_calibration TO excititor_service; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA excititor_calibration TO excititor_service; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA excititor_calibration TO excititor_service; ALTER DEFAULT PRIVILEGES IN SCHEMA excititor_calibration GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO excititor_service; ALTER DEFAULT PRIVILEGES IN SCHEMA excititor_calibration GRANT USAGE, SELECT ON SEQUENCES TO excititor_service; END IF; END $$; -- Comments for documentation COMMENT ON SCHEMA excititor_calibration IS 'Trust vector calibration data for VEX source scoring'; COMMENT ON TABLE excititor_calibration.calibration_manifests IS 'Signed calibration epoch results'; COMMENT ON TABLE excititor_calibration.trust_vector_adjustments IS 'Per-source trust vector changes per epoch'; COMMENT ON TABLE excititor_calibration.calibration_samples IS 'Empirical feedback samples for calibration'; COMMENT ON TABLE excititor_calibration.calibration_metrics IS 'Performance metrics per calibration epoch';