Skip to main content

Shared Memory Layer

AideMemo can serve one durable memory store to multiple coding agents while keeping project context and writer provenance explicit. The intended boundary is a trusted agent fleet: use source_id to choose the memory namespace, actor_id to record who wrote a fact, and bearer-token bindings when a network caller must not be allowed to choose either value.

This guide is the deployment-level view. For individual MCP tool schemas, see MCP Setup. For locking, backup, and sync details, see Operations. For the accepted but not-yet-shipped multi-tenant server, SaaS, and Kubernetes target, see Server and SSOT Architecture.

Choose the deployment model

SituationRecommended layout
One person, one projectOne local SQLite store, stdio MCP, no source_id required
Several agents sharing one projectOne store and one project source_id; give each writer a distinct actor_id
Several trusted projects on one serverOne SQLite store, one mcp-serve, and a fixed token binding per source/actor
Mutually untrusted tenantsSeparate stores and preferably separate AideMemo processes
Cloud or speculative agent runsRestore a baseline backup, write locally, then merge only the selected branch log

These rows describe the implemented shared-store product. They are not a claim that the current source_id model is a SaaS tenant boundary. The server target introduces tenant/project membership, command idempotency, revision guards, and an ordered tombstone-bearing change feed instead of widening this local scope model.

SQLite / libsqlite is the default shared-store backend. Prefer one daemon or HTTP server as the writer coordinator. The optional redb backend is useful for embedded single-process workloads, but its single-writer file lock makes a shared server the practical multi-agent path.

Reference architecture

The server binds its listener before semantic prewarm starts. Lexical requests and /health therefore remain available while the model is warming. /admin/status.semantic_prewarm reports warming, ready, failed, or disabled to an unbound administrator.

Identity and visibility rules

Keep these three concepts separate:

ValuePurposeSecurity meaning
source_idSelect the project, team, or upstream memory namespaceFilters facts, pinned context, entity visibility, graph reads, and mutations
actor_idRecord the writer profile or agent instanceProvenance only; it does not grant read access
Bearer tokenAuthenticate an HTTP callerWith a binding file, fixes both identities and rejects caller overrides

The storage and read contracts are:

SurfaceScoped behavior
Exact-content deduplicationKeyed by normalized (source_id, content_hash); the same text in two sources creates two facts
Fact get/list/search/pin/mutationsThe fact must belong to the selected source
Entity get/listReturned only when the entity has a fact in the selected source; unscoped summary metadata is omitted
Traverse/path/graphBoth visible entities and relation provenance must match the exact source namespace
Context/query/recent/aggregateOnly source-visible facts participate before limits or arithmetic are applied
Global admin and sync exportDenied to source-bound HTTP tokens

Entity names and entity types remain a shared ontology inside one store. This is why source_id is a strong cooperating-team partition, not a hostile multi-tenant database boundary. Separate stores are the isolation unit when even entity names, resource usage, or administrator access must not be shared.

Share one project between local agents

Choose one stable project source and a different actor for each writer:

aidememo --backend libsqlite --store ~/.aidememo/team.sqlite \
mcp-install --target codex --source-id project:payments --actor-id codex:primary

aidememo --backend libsqlite --store ~/.aidememo/team.sqlite \
mcp-install --target claude --source-id project:payments --actor-id claude:reviewer

Both agents see the same project facts because the source_id matches. Their writes remain attributable because the actor_id differs. These installed environment defaults are appropriate for trusted local processes; explicit MCP arguments can still override them.

For shared writes, keep one warm coordinator running:

aidememo --backend libsqlite daemon start \
--store ~/.aidememo/team.sqlite --port 3000

Bind network callers to fixed identities

For independently authenticated HTTP agents, create a mode-0600 binding file. Each token must have a non-empty token, source, and actor, and duplicate tokens are rejected.

{
"tokens": [
{
"token": "replace-with-agent-a-secret",
"source_id": "project:payments",
"actor_id": "codex:primary"
},
{
"token": "replace-with-agent-b-secret",
"source_id": "project:search",
"actor_id": "claude:reviewer"
}
]
}
chmod 600 ./token-bindings.json

aidememo --backend libsqlite --store ~/.aidememo/shared.sqlite \
mcp-serve --bind 127.0.0.1 --port 3000 \
--auth-bindings-file ./token-bindings.json

For every authenticated tools/call, the server injects the bound source_id and actor_id. A different top-level value, or a different value inside an aidememo_fact_add_many item, is rejected. Bound callers cannot read /admin/status or /sync/since; /health returns only health and prewarm state.

mcp-serve is plain HTTP. Keep it on loopback, or put any non-loopback bind behind a TLS-terminating reverse proxy or encrypted private tunnel with rate limits appropriate for the deployment.

Use the shared-memory loop

The normal agent loop needs few calls:

  1. Open with aidememo_context or start ticket work with aidememo_workflow_start.
  2. Use aidememo_query for a topic dive.
  3. Use aidememo_aggregate only for deterministic cross-fact counting, currency, duration, or timelines.
  4. Persist durable outcomes with aidememo_fact_add or aidememo_fact_add_many, keeping decision, lesson, error, and preference types explicit.

With a bound token, clients should omit identity fields. The server supplies them. With a trusted stdio install, the MCP environment supplies defaults.

Protect continuity

For SQLite stores, a backup includes the hot database and an existing <store>.cold.sqlite archive in one manifest with independent sizes and SHA-256 checksums:

aidememo --store ~/.aidememo/shared.sqlite backup create ~/backups/aidememo
aidememo --store ~/.aidememo/shared.sqlite backup restore ~/backups/aidememo --force

Restore validates both tiers and preserves complete previous-store safety snapshots before replacement. Stop writers before restore.

Incremental sync is canonical-writer and pull-only. Cursor persistence is process-locked and atomic, relation additions and updates replicate, and relation deletion is not represented. Use branch logs for disposable cloud agents or what-if memory experiments rather than treating sync as multi-primary conflict resolution.

Production checklist

  • Use an absolute store path and keep the suffix aligned with the backend.
  • Give every shared project a stable source_id and every writer a stable actor_id.
  • Use token bindings whenever an HTTP caller must not select its own scope.
  • Keep mcp-serve on loopback or terminate TLS before it reaches clients.
  • Run aidememo doctor --json to inspect store health and sharing guidance.
  • Back up both hot and cold tiers before upgrades or destructive maintenance.
  • Use one daemon/server for sustained shared writes.
  • Treat relation deletes and competing semantic decisions as application-level coordination concerns.