diff --git a/migrations/V5__truth_scoring.sql b/migrations/V5__truth_scoring.sql new file mode 100644 index 0000000..499d214 --- /dev/null +++ b/migrations/V5__truth_scoring.sql @@ -0,0 +1,34 @@ +-- V5: Add truth scoring columns for the Truth Engine integration +-- Part of: https://gitea.ingwaz.work/Ingwaz/openbrain-mcp/issues/31 +-- +-- All columns are nullable — existing memories start unscored and +-- get populated by the background truth scoring worker. +-- +-- Rollback (manual): +-- ALTER TABLE memories +-- DROP COLUMN IF EXISTS truth_value, +-- DROP COLUMN IF EXISTS truth_confidence, +-- DROP COLUMN IF EXISTS truth_category, +-- DROP COLUMN IF EXISTS truth_evaluated_at, +-- DROP COLUMN IF EXISTS ecan_sti, +-- DROP COLUMN IF EXISTS ecan_lti; +-- DROP INDEX IF EXISTS idx_memories_truth_category; +-- DROP INDEX IF EXISTS idx_memories_truth_unevaluated; + +ALTER TABLE memories + ADD COLUMN truth_value REAL, + ADD COLUMN truth_confidence REAL, + ADD COLUMN truth_category TEXT, + ADD COLUMN truth_evaluated_at TIMESTAMPTZ, + ADD COLUMN ecan_sti REAL, + ADD COLUMN ecan_lti REAL; + +-- Partial index: quickly find memories by truth category +CREATE INDEX idx_memories_truth_category + ON memories (truth_category) + WHERE truth_category IS NOT NULL; + +-- Partial index: efficiently find unscored memories for the background worker +CREATE INDEX idx_memories_truth_unevaluated + ON memories (created_at) + WHERE truth_evaluated_at IS NULL; diff --git a/src/db.rs b/src/db.rs index 5cd70c6..ae3447b 100644 --- a/src/db.rs +++ b/src/db.rs @@ -30,6 +30,13 @@ pub struct MemoryRecord { pub metadata: serde_json::Value, pub created_at: chrono::DateTime, pub expires_at: Option>, + // Truth scoring fields (populated by background worker) + pub truth_value: Option, + pub truth_confidence: Option, + pub truth_category: Option, + pub truth_evaluated_at: Option>, + pub ecan_sti: Option, + pub ecan_lti: Option, } /// Query result with similarity score @@ -299,6 +306,13 @@ impl Database { metadata: row.get("metadata"), created_at: row.get("created_at"), expires_at: row.get("expires_at"), + // Truth fields will be populated by issue #39 + truth_value: None, + truth_confidence: None, + truth_category: None, + truth_evaluated_at: None, + ecan_sti: None, + ecan_lti: None, }, similarity: row.get("hybrid_score"), vector_score: row.get("vector_score"),