Install with pipx install provena-agent-memory, then provena quickstart claude (or codex /
gemini).
Problem
Coding agents like Claude Code, Codex and Gemini CLI forget everything between sessions. The usual fix is a vector store of past snippets. That is relevant but opaque. It can’t tell you who asserted a fact, what the original source said, whether anyone reviewed it, or which agent session received it. Memory that is relevant can still be stale, speculative, or wrong. Once it’s in the context window, it is treated as truth.
Approach
Provena separates what was said from what is believed:
- Events are immutable source material: a user statement, an assistant inference, a tool observation.
- Claims are structured propositions (subject, predicate, value, validity interval, review state).
- Evidence links a claim to the event that supports it, and can never be edited or deleted.
Agents write through MCP tools or lifecycle hooks. A local model extracts candidate claims, which are returned to later sessions as clearly provisional context. Only a human credential can promote, quarantine, or resolve a conflict. Model output can never raise its own authority.
Architecture
Agent host (Claude Code / Codex / Gemini CLI)
└─ MCP server + lifecycle hooks
└─ FastAPI: policy + transaction boundary
├─ PostgreSQL + pgvector (system of record, derived embeddings)
├─ Ollama (claim extraction + embeddings, local)
└─ Next.js operator console (review, conflicts, retrieval audit)
- One store. Events, claims, evidence and audit records live in PostgreSQL, so a claim and its evidence are created atomically. Embeddings are derived indexes and never count as evidence.
- Exact scopes. Every record carries an organization ID. Retrieval requires an exact organization, project or branch scope, so branch experiments never leak into project memory.
- Append-only history. A status change must come with a new, versioned action row. PostgreSQL enforces this, and also requires a human credential, even if application code tries to bypass it.
- Retrieval audit. Every query records exactly which claims were delivered to which agent session.
Tech stack
Python 3.12, FastAPI, SQLAlchemy and Alembic, PostgreSQL with pgvector, Ollama (qwen2.5:1.5b for extraction, nomic-embed-text for embeddings, OpenAI as an optional provider), the MCP Python SDK, a Next.js operator console, Docker Compose, and distribution via PyPI.
Key trade-offs
Local models by default instead of a hosted API
Extraction first ran on OpenAI. That made a local install depend on a second paid API and fixed the vector column to one provider’s dimensions. Moving to Ollama made setup free and private. The cost was weaker extraction quality from a 1.5B model. Since extraction only ever produces candidates, that trade is acceptable.
Exact cosine ordering instead of an ANN index
Embeddings from different models and dimensions share one table. I dropped the initial HNSW index, and PostgreSQL now filters by tenant, scope, model and dimension before exact cosine ordering. At per-project scale this is fast enough and always correct. A model-specific partial index can come later, once measurements justify it.
Candidates are retrievable before review
Requiring human review before any recall would make memory useless day to day. Candidates are returned instead, with their status and source authority attached, so the agent can tell “provisional” from “verified”.
Record delivery, not influence
Provena can prove a claim was sent to an agent. It deliberately doesn’t claim that the claim caused a later action, because that would need a separate, trusted action-use signal.
Results
- Published on PyPI as
provena-agent-memory(v0.1.11). One command provisions the Docker stack, issues separate agent and reviewer credentials, and installs hooks for Claude Code, Codex or Gemini CLI. - Memories are shared across all three hosts when they use the same scope.
- 21 architecture decision records document each boundary. Integration tests run against real PostgreSQL rather than mocks.
Links
- GitHub
- PyPI
- Product demo on YouTube
- Why agent memory needs provenance, the write-up