The fleet's causal-ordered, backend-pluggable store substrate — one thin layer that gives every agent the same durable ordering, identity, and coordination seam, on SQLite today and PostgreSQL tomorrow.
Status: bootstrapping (2026-06-13)
agent-store is not a database and not an agent. It is the small Rust crate
that two very different consumers sit on top of without re-inventing the same
machinery:
newt-agent's conversation store — a per-writer, BLAKE3-chained, tamper-evident log.modulex-mcp's routine engine — a monotonic generation counter that stamps every report.
It provides three things and nothing more:
- A pluggable [
Backend] —SqliteBackendtoday (bundled rusqlite, zero system dependencies, the laptop default). A synchronous Postgres backend lands behind thepgfeature in Phase 2, for where an operator already runs a server (your own box, or an operator-owned managed cluster database). Everything is synchronous, so consumers drop it into their existing call sites with no async refactor. - Two causal primitives —
Generation(a named monotonic counter) andWriterLog(a per-(stream, writer)log whose every entry chains the previous entry's BLAKE3 hash, verifiable withWriterLog::verify). - A commit [
Doorbell] — the seam co-located agents use to wake each other. The substrate only emits aCommitEvent; a consumer bridges it ontoagent-mesh, publishing the causal pointer(writer, seq)on a per-stream topic. The mesh stays the only distributed fabric —agent-storenever becomes a cross-machine coordination primitive.
- Wall-clock time is never a coordination primitive. Ordering is
(writer, seq)and generation counters. Any timestamp a consumer stores is a display claim, never compared to make a decision. - The substrate is synchronous and mesh-agnostic. No async creep, no dependency on the mesh transport. The doorbell hands events out; consumers do the bridging.
- The default is a file. SQLite, bundled, no server, no daemon. Postgres is opt-in and only ever a server someone else already owns and reaps.
use agent_store::{Doorbell, CommitEvent, Generation, SqliteBackend, WriterLog};
// Open a store and lay down the substrate tables.
let db = SqliteBackend::in_memory()?; // or SqliteBackend::open(path)?
Generation::ensure_schema(&db)?;
WriterLog::ensure_schema(&db)?;
// A monotonic generation counter (modulex's report clock).
let report = Generation::new("report");
assert_eq!(report.bump(&db)?, 1);
assert_eq!(report.bump(&db)?, 2);
// A per-writer chained log (newt's conversation turns) + a doorbell a
// session loop would bridge onto the mesh.
let bell = Doorbell::new();
bell.subscribe(|e: &CommitEvent| {
// publish (e.writer, e.seq) on a mesh topic here
});
let turn = WriterLog::append(&db, "conv:demo", "alice", b"hello world")?;
bell.ring(&CommitEvent {
stream: turn.stream.clone(),
writer: turn.writer.clone(),
seq: turn.seq,
content_hash: turn.content_hash,
});
// The chain is tamper-evident.
WriterLog::verify(&db, "conv:demo", "alice")?;
# Ok::<(), agent_store::StoreError>(())just check # fmt --check + clippy -D warnings + tests (the gate)
just install-hooks # REQUIRED after clone: installs .githooks/pre-pushZero-warnings policy; .githooks/pre-push and .github/workflows/ci.yml run
the same steps and must stay in parity.
| Phase | Scope |
|---|---|
| 0 (this repo) | Substrate: Backend + SQLite, Generation, WriterLog, Doorbell. |
| 1 | Consumers wire the doorbell over agent-mesh for local multi-agent coordination. |
| 2 | pg feature: synchronous Postgres Backend (opt-in, BYO/remote server). |
| 3 | Operator-owned managed Postgres for in-cluster fleets (the cluster "Meat Locker"). |
| 4 | Semantic recall (pgvector), in-cluster only. |
Dual-licensed under either MIT or Apache-2.0 at your option.