Skip to content

mempill

AI agents accumulate beliefs over time. mempill is the append-only, bi-temporal, provenance-aware claim store that surfaces conflict rather than silently resolving it. Temporally-correct memory — from the start.

A stored belief can be well-sourced and internally consistent yet factually wrong — because the underlying truth changed after the claim was recorded, and the agent has no mechanism to detect or signal that staleness. This is the temporal validity problem.

Contested-first conflict surfacing

When contradicting claims arrive and no oracle is present to adjudicate, mempill surfaces Contested rather than picking a winner. Every outcome is observable through the 12-state disposition model — there are no silent overwrites.

Oracle resolution loop

Stochastic proposals (model output, external lookups) never commit without passing a deterministic adjudication gate (C7). The oracle port is pluggable — supply your own resolver, or use the built-in human-in-the-loop pattern.

Valid-time succession

mempill maintains two time axes: transaction-time (engine-stamped, reliable) and valid-time (caller-supplied, fallible, confidence-tagged). Belief is recomputed at read time from the full claim history — nothing is overwritten, ever.

Provenance firewall

Every claim carries one of three typed provenance channels: External, RecallReEntry, or ModelDerived. The type system enforces exhaustiveness and prevents belief-amplification loops where the engine reads its own output and re-ingests it as fresh evidence.

mempill is a Rust library with Python (PyO3) bindings and an MCP adapter for direct integration with Claude, GPT, and other MCP-compatible agents.

Use case Topology
Single-agent embedded (tests, MCP sessions, CLI tools) SQLite topology-a — zero config, file-per-agent
Multi-agent production service PostgreSQL topology-b — shared DB, per-agent advisory locking
Claude / GPT integration MCP adapter — 4 tools over stdio transport
Rust — remember a fact and recall it
use mempill::{open_default_in_memory, remember, recall, RememberOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let engine = open_default_in_memory()?;
// Store a fact — valid from 2025 onward.
remember(&engine, "my-agent", "user", "city", "Munich",
RememberOptions::new().valid_from("2025-01-01")).await?;
// Read it back.
let r = recall(&engine, "my-agent", "user", "city").await?;
println!("city = {:?} contested = {}", r.as_str(), r.is_contested());
// city = Some("Munich") contested = false
Ok(())
}

Dates are lenient"2026", "2026-06", "2026-06-01", and RFC 3339 all work. Partial dates snap to the start of the period ("2026-06"2026-06-01); the filled day is a normalization placeholder, not asserted precision — granularity-aware valid-time is planned for v0.3. When two facts genuinely conflict (no time windows to differentiate them), recall returns is_contested() = true with both values in candidates — it never picks a silent winner. Need full provenance control? The full claim API (IngestClaimRequest, ProvenanceLabel, Cardinality, Confidence) is always available.


Apache-2.0 · 0.2.0 · Rust core + Python wheel + MCP adapter + PostgreSQL adapter

crates.io · docs.rs · PyPI · GitHub