-- pgvector knowledge schema (v0.2, branch embeddings)nCREATE EXTENSION IF NOT EXISTS vector;nn-- Documents tracked by content hash; multiple logical paths may point to same blobnCREATE TABLE IF NOT EXISTS doc_blob (n  blob_sha256  text PRIMARY KEY,n  bytes        bigint NOT NULL,n  created_at   timestamptz DEFAULT now()n);nn-- Logical document identity and branch/commit lineagenCREATE TABLE IF NOT EXISTS doc (n  id           bigserial PRIMARY KEY,n  origin       text,          -- e.g., filesystem, forgejo, exportn  root_path    text,          -- repo root or base dirn  rel_path     text,          -- path relative to rootn  blob_sha256  text REFERENCES doc_blob(blob_sha256)n);nCREATE TABLE IF NOT EXISTS branch (n  id           bigserial PRIMARY KEY,n  name         text UNIQUE,n  created_at   timestamptz DEFAULT now()n);nCREATE TABLE IF NOT EXISTS revision (n  id           bigserial PRIMARY KEY,n  branch_id    bigint REFERENCES branch(id) ON DELETE CASCADE,n  parent_id    bigint REFERENCES revision(id),n  commit_sha   text,          -- optional link to VCSn  message      text,n  created_at   timestamptz DEFAULT now()n);nn-- Chunked text with provenance; each revision can re-chunk same docnCREATE TABLE IF NOT EXISTS chunk (n  id           bigserial PRIMARY KEY,n  revision_id  bigint REFERENCES revision(id) ON DELETE CASCADE,n  doc_id       bigint REFERENCES doc(id) ON DELETE CASCADE,n  lineno       int,n  text         text NOT NULL,n  tags         text[],n  sha256       text,n  created_at   timestamptz DEFAULT now()n);nCREATE INDEX IF NOT EXISTS idx_chunk_doc ON chunk(doc_id);nCREATE INDEX IF NOT EXISTS idx_chunk_rev ON chunk(revision_id);nn-- Embedding models registrynCREATE TABLE IF NOT EXISTS embed_model (n  id           bigserial PRIMARY KEY,n  name         text UNIQUE NOT NULL,   -- e.g., mxbai-embed-largen  dims         int NOT NULL,n  tokenizer    text,n  notes        textn);nn-- Branch embeddings: per revision, per chunk, per model (dims parametrized by table)nCREATE TABLE IF NOT EXISTS embedding_1024 (n  id           bigserial PRIMARY KEY,n  chunk_id     bigint REFERENCES chunk(id) ON DELETE CASCADE,n  model_id     bigint REFERENCES embed_model(id),n  embedding    vector(1024) NOT NULL,n  created_at   timestamptz DEFAULT now()n);nCREATE INDEX IF NOT EXISTS idx_emb1024_chunk ON embedding_1024(chunk_id);nCREATE INDEX IF NOT EXISTS idx_emb1024_vec ON embedding_1024 USING ivfflat (embedding vector_l2_ops) WITH (lists=100);nn-- Views: latest chunks per branchnCREATE OR REPLACE VIEW v_latest_chunks AS
SELECT c.* FROM chunk c
JOIN (SELECT revision_id, max(id) over (partition by doc_id, branch_id) as maxid, doc_id
      FROM revision r JOIN chunk c2 ON c2.revision_id=r.id) t
  ON c.id=t.maxid;nn-- Ledger mirror (optional)nCREATE TABLE IF NOT EXISTS ledger_mirror (n  id          bigserial PRIMARY KEY,n  ts          timestamptz NOT NULL,n  actor       text,n  action      text,n  body        jsonbn);n