SHIPS TODAY · v0.7.0

Tier 2 — Single node, many agents

The first multi-tenant tier. One ai-memory process, but a swarm of agents — typically 10 concurrent — each writing into its own namespace, recalling with scope visibility filters, and gated by per-namespace governance with a pending-approval queue.

10 agents namespace isolation scope visibility policy/namespace

This is the canonical shape for a workstation running a planner, a coder, a reviewer, and a handful of skills as separate Claude Code agents — all sharing the same memory store but each siloed by namespace.

Architecture diagram

10 agents · namespace isolation · governance gate.

T2 · 10 agents · namespace isolation · governance gate
Planneragents/planner Coderagents/coder Revieweragents/reviewer Researcheragents/researcher Data engagents/data-eng SecOpsagents/secops Testeragents/test Docsagents/docs Triageagents/triage Opsagents/ops Governance policy/namespace Allow / Deny / Pending ✓ allow ✗ deny ⌛ pending PendingAction queue memory_pending_list memory_pending_approve memory_pending_reject ai-memory core recall pipeline scope filter as_agent param FTS5 + HNSW touch + promote v0.6.3 KG layer (extended at v0.7.0 — Apache AGE backend + Ed25519 attestation) SQLite memories scope_idx FTS5 pending_actions namespace_meta memory_get_taxonomy v0.6.3 hierarchical view agents/* / collective/*
agent → governance policy decision scope-filtered recall persistent I/O
Each agent writes into its own namespace, then trips the per-namespace governance gate before the row is committed. Recalls flow back through the scope filter — agents only see what their namespace position permits.
Walkthrough

What's actually happening.

Namespace isolation

Every agent has a namespace position — typically agents/<role> or org/team/role. Memories are written with that namespace, and the indexed scope_idx generated column captures the agent's visibility scope (private / team / unit / org / collective).

When agent agents/planner calls memory_recall and passes as_agent=agents/planner, compute_visibility_prefixes() (src/storage/mod.rs) walks the namespace ancestors and returns [agents/planner, agents/, '']. The recall SQL then WHEREs on scope_idx IN (...) — the planner sees its own private memories plus anything scoped team or collective that an ancestor namespace publishes.

This is the same machinery T1 has — but at T2 it's actually doing work.

Per-namespace governance

Set a policy with memory_namespace_set_standard:

# 1. store the standard memory that carries the policy, capture its id
ai-memory --json store -T "secops namespace standard" -c "write gating" -n agents/secops
# 2. bind it — the JSON merges into the standard's metadata.governance
ai-memory namespace set-standard --namespace agents/secops --id <standard-memory-uuid> \
  --governance '{"write":"approve","promote":"owner","delete":"approve"}'

Now any agent writing into agents/secops triggers the governance gate (check_agent_action()) which returns Pending(action_id). The write isn't committed — it's parked in pending_actions. The owning operator (or a designated approver agent) calls memory_pending_list, inspects the diff, and either memory_pending_approve or memory_pending_reject. Approved writes get committed; rejected ones are dropped with an audit row.

Per-namespace policy means a strict-write namespace can sit next to a permissive one. The hierarchy lets you set a default at org/ and override at org/team/.

Capabilities introspection (v0.6.3)

Before an agent invokes a skill, it can ask: "is auto-tag actually wired here?"

$ curl -s http://127.0.0.1:9077/api/v1/capabilities   # or the memory_capabilities MCP tool
{
  "schema_version": "3",
  "tier": "semantic",
  "version": "0.7.0",
  "features": {
    "keyword_search": true,
    "hybrid_recall": true,
    "auto_tagging": false,
    "contradiction_analysis": false,
    "cross_encoder_reranking": false,
    ...
  },
  "permissions": { ... }, "hooks": { ... },
  "approval": {"pending_requests": 7, ...}
}

Capabilities v2 shipped in v0.6.3; at v0.7.0 the envelope defaults to schema_version "3" (v1/v2 still negotiable via Accept-Capabilities) — agents discover what's available at runtime instead of hard-coding assumptions.

Deployment recipe

Workstation, multi-agent, multi-namespace.

# Run as a long-lived HTTP daemon on the workstation
ai-memory --db /var/lib/ai-memory/store.db serve \
  --host 127.0.0.1 --port 9077

# Each agent is a separate MCP client (or HTTP client) pointing at the same store.
# MCP is stdio JSON-RPC, not an HTTP endpoint — spawn ai-memory mcp directly.
# In .mcp.json for each agent's Claude Code config:
{
  "mcpServers": {
    "memory": {
      "command": "ai-memory",
      "args": ["mcp", "--profile", "full"],
      "env": {"AI_MEMORY_AGENT_ID": "agents/planner"}
    }
  }
}

# HTTP clients (non-MCP agents) connect to the daemon's REST surface:
#   curl -s -X POST http://127.0.0.1:9077/api/v1/recall \
#     -H "X-Agent-Id: agents/planner" -d '{"context": "..."}'

# Agents pass as_agent=agents/<role> on every recall
# Per-namespace policies set once, enforced forever:
ai-memory namespace set-standard --namespace agents/secops --id <standard-memory-uuid> \
  --governance '{"write":"approve","delete":"approve"}'
Wiring

Governance, skills, and attestations at T2.

Limits

Honest ceilings.

DimensionT2 ceilingWhen it bites
Concurrent writers~10–20 before mutex contention shows upBulk imports starve real-time agents
Total memories~10⁶ before HNSW RAM cost is noticeableVector index lives in-process
Write throughput~500-2000 writes/sec (single SQLite writer)Bulk operations should chunk
Recall p95sub-10ms at 10⁵ memories with HNSWScales to 10⁶ with care
Network exposureloopback by default, mTLS availableSet up TLS before binding non-loopback
Cross-machine sharingnoneWalk to Tier 3
Source

Source-of-truth references.