Skip to content
LIVE v1.0.0 acceptance testing → test.agenticmem.co|Reproducible results for peer review → testing methodology & outcomes
ai-memory / architectures
Menu
GitHub
ai-memory v1.0.0 · architectures

One memory substrate, from a single agent to a federated hive.

The same Rust binary, the same schema and the same three surfaces (MCP, HTTP, CLI) run on a laptop, behind a shared daemon, across a quorum-replicated cluster and on a PostgreSQL tier. What changes from tier to tier is topology, the consistency model and the trust boundary. New in v1.0.0: the wake plane, which pushes a content-free hint the moment a message lands, so agents stop sleeping between inbox polls.

SQLite + SQLCipher at rest PostgreSQL 18 + Apache AGE + pgvector Ed25519-signed federation W-of-N quorum writes wake-hub · wake-listen
The hive

ai-memory inside an agent hive.

Each host runs its agents, one ai-memory daemon, one same-host wake hub and one store. Hosts meet only through federation: a mutually-authenticated, Ed25519-signed push mesh with W-of-N quorum writes and a catch-up pull for peers that were away. Host A runs an MCP agent whose ai-memory mcp child opens SQLite in-process; host B runs the CLI, which also opens the store in-process (it is not a thin HTTP client); host C keeps its data in PostgreSQL, which agent traffic reaches only through its daemon. Every daemon listener is TLS, loopback included.

memory read/write wake hint operator side / backstop limit
ai-memory inside a three-host agent hiveThree hosts, each running agents, an ai-memory daemon, a same-host wake hub and a store. Hosts A and B use SQLite; host C uses PostgreSQL through its daemon. The daemons federate over a mutually-authenticated, Ed25519-signed mesh with W-of-N quorum writes and catch-up pulls. An operator-side triage consumer subscribes to wake hints like any agent and is not part of ai-memory. FEDERATION MESH · mTLS · Ed25519-signed /sync/push · W-of-N quorum · /sync/since catch-up HOST ASQLite · MCP agentHTTPS agentHTTPS agentMCP agentai-memory serveidentity · authgovernance gatememory engineai-memorymcpstdio childin-processSQLite onlywake-hubunix socketsame hostSQLite · WALSQLCipher build:encrypted at rest HOST BSQLite · CLI operatorHTTPS agentHTTPS agentCLI shellai-memory serveidentity · authgovernance gatememory engineai-memory<verb>CLI processin-process,not a clientwake-hubunix socketsame hostSQLite · WALSQLCipher build:encrypted at rest HOST CPostgreSQL tierHTTPS agentHTTPS agentHTTPS agentai-memory serveidentity · authgovernance gatememory engineHTTPS only:MCP stdio isSQLite-onlywake-hubunix socketsame hostPostgreSQL 18 · pgvectorAGE when installedagents via daemon only OPERATOR SIDE · NOT PART OF ai-memoryJev triage: subscribes to wake hints with wake-listen like anyagent, reads the inbox, routes and pre-scores. It never decidescorrectness, security or a merge. HONEST LIMITS· a wake hub never bridges hosts; hosts meet only through federation· no agent talks to PostgreSQL directly; no CDC stream is offered· quorum miss → 202 quorum_met:false; the row is already durable locally

Read it top-down. Agents reach the daemon over HTTPS or spawn a local process; the daemon resolves identity, applies governance and writes the store; a committed message publishes a wake to the local hub; the federation riser replicates the write to the other hosts. Sources: src/daemon_runtime.rs, src/mcp/mod.rs, src/federation/sync.rs, src/wake_hub/server.rs.

One node

Three surfaces, one engine, two backends.

MCP serves a named profile: core (the store, recall, list, get, search, load-family and smart-load tools, plus the always-on memory_capabilities bootstrap), graph, admin, power or full, or a comma-separated mix of profiles and tool families. HTTPS serves every route under /api/v1/: the daemon refuses to listen without TLS on any bind, loopback included; a single-operator install mints and renews a local CA certificate, and every fleet shape brings its own. The CLI exposes the same operations as verbs. All three resolve an agent identity and pass the same per-namespace governance gate before the engine touches storage.

Inside one ai-memory nodeThree surfaces (MCP over stdio with named profiles from core to full, HTTPS under /api/v1 with TLS on every bind, and the CLI) resolve an agent identity, pass the per-namespace governance gate, reach one memory engine and land in SQLite or SQLCipher, or in PostgreSQL with agent traffic through the HTTPS daemon only. Audit, signed events, curator and operations tooling sit underneath. MCP · stdio JSON-RPCprofiles: core · graph ·admin · power · full HTTPS · /api/v1/*TLS on every bind (#3705)API key required off loopback CLI · ai-memory <verb>in-process, not a client;admin verbs: --store-url SURFACESIDENTITYX-Agent-Id headerper-agent API keysmTLS fingerprintallowlistEd25519 agent keys GOVERNANCEnamespace standardswrite · promote · deleteany | registered |owner | approveAllow · Deny · Pendingcapability tokens MEMORY ENGINEtiers short · mid · longkeyword + vector recalltemporal knowledge graphhooks · subscriptionsleases · checkpointscurator · autonomy STORAGESQLite · WALevery surfaceSQLCipher build feature:encrypted at restone writer at a time PostgreSQL 18pgvector · AGE if installedagents via the daemon:76 of the 89 unique pathsthe rest fail closed: 501 UNDERNEATH EVERY NODEaudit loghash-chained JSON linesopt-in · audit verify signed_eventsappend-only SHA-256 chainverify-signed-events-chain curator · autonomyLLM sweeps, opt-in passestagging · contradictions operationsbackup · restore (SQLite)doctor · export · import

Backend parity, stated exactly. On PostgreSQL every request still terminates at the daemon: postgres_route_gate serves 76 of the 89 unique paths and answers the rest with a uniform 501 NOT IMPLEMENTED rather than ever touching the wrong database. serve and curator run against PostgreSQL; the tenant-facing CLI read/write verbs and MCP over stdio are SQLite-only; the admin verbs schema-init, keys, reown, verify-audit-trail, agents bind-api-key, identity hub-cache and doctor take a per-run --store-url target. Sources: src/handlers/postgres_gate.rs, src/profile.rs, src/transit_encryption.rs, src/daemon_runtime.rs.

Data tiers

short · mid · long

Every memory carries a tier. Short expires after hours, mid after days, long never; recall boosts and promotion move memories up. TTLs come from the retention model in src/models/memory.rs.

At rest

SQLCipher or deployment-specific

Build with the sqlcipher feature to encrypt the SQLite file. For PostgreSQL volumes, the enterprise posture check records an operator attestation that storage encryption is on; it does not probe the disk itself.

Forensics

Two tamper-evident chains

The signed_events table is an append-only SHA-256 chain checked by verify-signed-events-chain. The opt-in audit log is a hash-chained JSON stream checked by audit verify. Content is never written to the audit log.

Operations

backup · restore · doctor

ai-memory backup snapshots SQLite with an operator-signed manifest and refuses other stores; PostgreSQL uses your own base backups and WAL archive. doctor reports health locally or across a fleet with --remote.

Curator · autonomy

LLM sweeps, opt-in

The curator periodically auto-tags and checks for contradictions through a configured LLM; autonomy adds consolidation, forgetting of superseded memories and priority feedback. Neither runs without an LLM configured.

Recall

Keyword + vector, plus a graph

Keyword search, embeddings from a local MiniLM model or an OpenAI-compatible endpoint, an in-process HNSW index on SQLite or pgvector on PostgreSQL, and temporal links with valid_from / valid_until. Apache AGE accelerates graph walks when installed.

New in v1.0.0 · rust-a2a wake plane

Messages that wake their recipient.

memory_notify commits a durable inbox row, then publishes a bounded hint through an in-process bus, a wake sink and the host's wake-hub (a Unix-domain-socket switch with per-recipient queues, an allowlist and a delegation verifier) to the recipient's wake-listen session. The hint carries a digest, never the body. Across hosts the row travels by federation, and the receiving node publishes its own local wake only when the apply actually moved the row forward.

The rust-a2a wake planeOn host A a notify commits a durable inbox row first, then publishes a content-free wake through the in-process bus, a wake sink and the same-host wake hub to the recipient, who does one catch-up inbox read. A bounded backstop poll makes a lost wake cost latency only. The row reaches host B through signed federation; applying a fresh row there publishes a local wake, while replayed or superseded rows wake nobody. An operator-side triage consumer subscribes like any agent. HOST A01sender agentmemory_notifyMCP · HTTPS 02inbox row_inbox/<recipient>committed first 03inbox_wake busagent_notifiedin-process 04wake_sinkco-hosted, orUDS forwarder 05wake-hubunix socketper-recipient queue 06wake-listenrecipient agent1 catch-up read wake = { inbox_row_id, namespace, sender, digest, seq_high_watermark } · no body backstop poll at least every 60 s: the inbox row is the record, a lost wake costs latency onlyHOST Bquorum fan-out · mTLS · Ed25519 X-Memory-Sig/sync/pushverify signatureattest the sender apply rownewer-wins mergeon the local store applied_wakefresh apply onlylocal wake publish wake-hubhost B socketper-recipient queue wake-listenrecipient on B1 catch-up read replayed, superseded, tombstoned or quarantined rows wake nobody: the bridge cannot loopoperator sideJev triagelike any agent wake hint to an operator-side subscriber (not part of ai-memory)

Degrade, never corrupt. The inbox row commits before any wake fires, so a slow, full or absent hub costs a hint and a counter, never a message. Clients must keep polling at least once a minute (BACKSTOP_POLL_MAX). The hub has no TCP or TLS listener: it is same-host by construction, and the cross-host leg is federation's mutual TLS. Jev is drawn as what it is: an operator-side subscriber that routes and pre-scores, not an ai-memory component. Sources: src/inbox_wake.rs, src/wake_sink/mod.rs, src/wake_hub/routing.rs, src/federation/applied_wake.rs; guide: wake plane, integrate any agent.

Federation

Durable first, replicated second.

A federated write commits locally before it fans out, so replication can be slow or partial without losing data. Every push is Ed25519-signed and carried over mutual TLS with pinned certificate fingerprints; receivers verify the signature, refuse replays and unenrolled peers, and check that the sender may write the namespace it claims.

Federated quorum writeAn agent writes to node A. Node A commits locally first, signs the body with Ed25519, fans out to peers over mTLS and waits for W of N acknowledgements. In time, the write is acknowledged; on a miss the answer is 202 Accepted with quorum_met false and durability local, and the push dead-letter queue retries. Rejoining peers catch up with sync/since. Erasures travel through a durable outbox. WRITE PATHPEERSRECOVERYagentwrite via HTTPS node A · ai-memory serve01local commitdurable, never rolled back02sign the bodyEd25519 X-Memory-Sig + nonce03fan out to N peersmutual TLS, pinned certs04collect W acksuntil --quorum-timeout-ms peer Bverify sig · attest · apply peer Cverify sig · attest · apply peer Dverify sig · attest · apply catch-uprejoining peers pullGET /api/v1/sync/sincepush DLQ replaysmissed deliveries W of N acks in timewrite acknowledgedreplicated to the quorum quorum miss → 202 Accepted{quorum_met:false, acks, needed, reason, durability:"local"} · never a 5xx erasureforget / delete → durableoutbox → pushed to peers Receivers refuse unsigned, replayed or unenrolled pushes (401). Peer attestation checks the claimed sender and its namespace scope.

The 202 contract. When fewer than W peers acknowledge before --quorum-timeout-ms, the daemon answers 202 Accepted with quorum_met:false and durability:"local": the write is safe on this node and queued for redelivery, which is why it is never reported as a server error. Writes made over MCP stdio join the quorum only when mcp_federation_forward_url points the MCP server at the local daemon; otherwise they skip the quorum and reach peers through the catch-up pull (a peer receives only rows in namespaces its attestation allowlist grants (deny by default) that are visible to its identity; scope=private rows stay on the node unless marked federation_share:true or the operator sets AI_MEMORY_FED_SYNC_TRUST_PEER=1), and their erasures travel through the outbox. Sources: src/handlers/parity.rs, src/replication.rs, src/federation/signing.rs, src/federation/peer_attestation.rs, src/federation/erasure_outbox.rs, src/config.rs; guide: federation.

Governance

Policy per namespace, approval where it matters.

A namespace standard binds a governance policy: for each of write, promote and delete, who may act (any, registered, owner or approve). The gate answers Allow, Deny or Pending; pending actions wait in a queue for memory_pending_approve or memory_pending_reject. Capability tokens are on by default and strictly additive.

Governance decision pathA request resolves its agent identity, walks the namespace standard chain and reads the policy level for write, promote or delete. The decision is Allow, Deny or Pending. Pending actions queue for approval or rejection. A capability token can only lift Pending to Allow and never lifts Deny. A namespace standard can require approval above a reflection depth. requestagent id resolved namespace standardglobal → parent →namespace policy levelwrite · promote · delete:any · registered ·owner · approve decide Allowcommitted Pendingpending_actions queue Denyrefused, terminal approveor reject capability token (macaroon)on by default, additive only: no token,no change · may lift Pending to Allow ·never lifts Deny · invalid token refused approval depthrequire_approval_above_depthin the namespace standard:deeper reflect → pending

Sources: src/models/namespace.rs, src/governance/capability.rs, src/governance/agent_action.rs; guide: governance.

Capability matrix

What each tier uses.

Every capability below is in the v1.0.0 build; the matrix shows where it does work. “opt” means available and off unless you turn it on.

CapabilityT1T2T3T4T5
StoreSQLiteSQLite, sharedSQLite per peer, or PostgreSQLPostgreSQLPostgreSQL or SQLite per site
Encryption at restSQLCipher buildSQLCipher buildSQLCipher, or attested volumeattested volumeattested volume
MCP (core / full) · stdio, SQLite onlyyesyesSQLite peersnoSQLite sites
HTTPS /api/v1/ daemon (TLS on every bind)optyesyesyesyes
CLI (in-process)yesyesyesadmin verbs via --store-urladmin verbs via --store-url
Namespaces, scope visibility, governanceyesyesyesyesyes
Wake plane (one hub per host)optyesper hostper hostper host
Signed federation, W-of-N quorum——yesrack-awarecross-site
mTLS between peers—optrequiredrequiredrequired
signed_events chain · audit logchain · audit optchain · audit optper peeraudit opt · chain verifier reads SQLiteper SQLite peer · audit opt
Backupsai-memory backupai-memory backupbackup, or PostgreSQL base backupsbase backups + WAL archiveWAL shipping off-site
Distributed consensus (Raft / Paxos)nonononono

Tier guidance and sizing: enterprise deployment. Certified scope: the enterprise federation certification covers 500–1000-agent clusters built from blocks of at most 50 peers, as a trust boundary, not as a throughput figure (docs/compliance/ENTERPRISE-FEDERATION-CERTIFICATION.md).

Honest limits

What this architecture does not do.

Read these before you size a fleet. Each is documented with its reasoning in architectural limits.

Access path

No direct-to-PostgreSQL client

Agent traffic never connects to PostgreSQL: every request terminates at the ai-memory daemon, which stays the throughput bottleneck on both backends. Only operator admin verbs open a per-run --store-url connection.

Writers

One writer at a time per SQLite file

WAL lets readers pass the writer, but writes serialize. A shared daemon, MCP children and CLI processes on one host all queue on the same file lock. PostgreSQL removes this ceiling.

Change feed

No CDC

There is no logical-replication or change-stream interface on either backend. The supported observation surface is hooks and webhook subscriptions.

Consistency

Eventual, not consensus

Federation is quorum writes plus catch-up, with no Raft or Paxos and no gossip discovery. Knowledge-graph invalidations reach peers asynchronously.

Wake plane

Same host only

The hub listens on a Unix socket; mounting it remotely is not a supported transport. Cross-host messages ride federation, and the poll stays the delivery guarantee.

Vectors

HNSW lives in process

On SQLite the vector index is held in RAM and rebuilt at start-up. pgvector keeps a durable index on PostgreSQL.