-- Poimen Memory schema (M2.3, M2.4 spec)
-- Tables: memory_node, memory_edge, memory_vector, failure_signature, memory_supersede

-- Enable pgvector extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Core memory node (sha256 = content identity, idempotent upsert key)
CREATE TABLE IF NOT EXISTS memory_node (
  id BIGSERIAL PRIMARY KEY,
  sha256 TEXT NOT NULL UNIQUE,
  level TEXT NOT NULL CHECK (level IN ('L0', 'L1', 'L2', 'R')),
  project TEXT NOT NULL,
  query_id TEXT,  -- NULL at L2 and R; CHECK enforced below
  run_id TEXT NOT NULL,
  t INT NOT NULL,
  source TEXT,  -- set at L0; source URI at R
  text TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  CONSTRAINT level_query_id_check CHECK (
    (level IN ('L2', 'R') AND query_id IS NULL) OR 
    (level NOT IN ('L2', 'R') AND query_id IS NOT NULL)
  )
);

CREATE INDEX idx_memory_node_project_level ON memory_node(project, level);
CREATE INDEX idx_memory_node_sha256 ON memory_node(sha256);

-- Memory edges (provenance graph: child → parent)
CREATE TABLE IF NOT EXISTS memory_edge (
  child_sha TEXT NOT NULL REFERENCES memory_node(sha256) ON DELETE CASCADE,
  parent_sha TEXT NOT NULL REFERENCES memory_node(sha256) ON DELETE CASCADE,
  PRIMARY KEY (child_sha, parent_sha)
);

CREATE INDEX idx_memory_edge_parent ON memory_edge(parent_sha);

-- Vector storage (one node can have multiple kinds: text + symptom)
CREATE TABLE IF NOT EXISTS memory_vector (
  node_sha TEXT NOT NULL REFERENCES memory_node(sha256) ON DELETE CASCADE,
  kind TEXT NOT NULL CHECK (kind IN ('text', 'symptom')),
  embedding vector(768) NOT NULL,
  PRIMARY KEY (node_sha, kind)
);

-- Partial indexes per kind (literal predicate required for planner to use them)
CREATE INDEX idx_memory_vector_text ON memory_vector USING hnsw (embedding vector_cosine_ops) WHERE kind = 'text';
CREATE INDEX idx_memory_vector_symptom ON memory_vector USING hnsw (embedding vector_cosine_ops) WHERE kind = 'symptom';

-- Exact-match failure signature tier (M3.7.7)
CREATE TABLE IF NOT EXISTS failure_signature (
  sig_sha TEXT PRIMARY KEY,  -- hash of normalized signature
  node_sha TEXT NOT NULL REFERENCES memory_node(sha256) ON DELETE CASCADE,
  tool TEXT NOT NULL,  -- 'github-actions' | 'kubectl' | 'npm' | ...
  raw TEXT NOT NULL,  -- pre-normalisation, for display
  seen_count INT NOT NULL DEFAULT 1,
  last_seen TIMESTAMPTZ NOT NULL
);

CREATE INDEX idx_failure_signature_tool ON failure_signature(tool);
CREATE INDEX idx_failure_signature_node ON failure_signature(node_sha);

-- Memory supersession (old lesson replaced by new one)
CREATE TABLE IF NOT EXISTS memory_supersede (
  old_sha TEXT NOT NULL REFERENCES memory_node(sha256) ON DELETE CASCADE,
  new_sha TEXT NOT NULL REFERENCES memory_node(sha256) ON DELETE CASCADE,
  reason TEXT,
  PRIMARY KEY (old_sha, new_sha)
);

CREATE INDEX idx_memory_supersede_new ON memory_supersede(new_sha);
