Core Architecture of ai-memory: A Dual-Layer Memory System for AI Agents
The ai-memory system implements a dual-layer architecture where markdown files serve as the single source of truth while a SQLite index provides fast retrieval, organized into eight single-responsibility crates that communicate through strict typed APIs and invariants.
The ai-memory project by akitaonrails is a local-first memory system designed for AI agents and developer workflows. Understanding the core architecture of ai-memory reveals how it balances durability, searchability, and auditability without requiring external LLM providers by default.
Dual-Layer Storage Model
The foundation of ai-memory rests on a strict separation between authoritative storage and derived indices.
Markdown Wiki as Source of Truth
All knowledge persists as markdown files in <data_dir>/wiki/. This layer remains the authoritative representation of memory through several mechanisms:
- Atomic writes: All file operations use a temporary file + rename + fsync pattern to guarantee crash safety
- Git versioning: The
ai-memory-wikicrate integratesgit2for automatic versioning of all changes - Human-readable: Files remain accessible via standard text editors and command-line tools
As documented in docs/ARCHITECTURE.md, writes to the wiki layer trigger corresponding updates to the derived index, never the reverse.
SQLite-Driven Derived Index
The <data_dir>/db/memory.sqlite database mirrors the wiki for high-performance access patterns:
- WAL mode: SQLite operates in Write-Ahead Logging mode for concurrent read performance
- Single-writer actor: The
ai-memory-storecrate implements an actor pattern where a single connection owns all writes, eliminating race conditions - Rich metadata: Stores embeddings, session observations, handoffs, and cross-project link graphs
The ReaderPool in crates/ai-memory-store/src/lib.rs manages a pool of read-only connections for query operations, while the writer actor序列所有 mutations.
Modular Crate Architecture
The codebase organizes into eight independent crates under crates/, each enforcing a single responsibility:
ai-memory-core/: Domain types, IDs, and error variants—zero I/O operationsai-memory-store/: SQLite writer actor, reader pool connection management, and decay mathematicsai-memory-wiki/: Atomic markdown writes, file-watcher implementation, and Git handlingai-memory-mcp/: RMCP transport layer, tool routing, and admin HTTP endpointsai-memory-hooks/: Hook payload schemas, sanitization logic, and the/hookendpoint handlerai-memory-llm/: Provider authentication,LlmProviderandEmbeddertrait definitionsai-memory-consolidate/: Karpathy-style ingestion pipeline, linting, and auto-improvement schedulingai-memory-workstream/: Read-only native transcript adapters and launch integrationsai-memory-cli/: Theai-memorybinary entry point and subcommand dispatch insrc/main.rs
Each crate exposes typed APIs; no crate accesses another's internal data structures directly. This enforces cross-cutting invariants like "typed 3-tuple identity" (workspace_id, project_id, path) and single configuration paths.
Steady-State Data Flow
The system processes agent observations through a six-stage pipeline:
- Lifecycle hook: External agent CLIs POST JSON events to
/hookwith a strict ≤200ms timeout (fire-and-forget) - Sanitization: The
ai-memory-hookssanitiser acts as the only trust boundary between untrusted input and storage - WriteCmd enqueue: Sanitized observations route to the writer actor, which persists to SQLite and creates wiki pages when necessary
- Session termination: On
session-endevents, the server synthesizessessions/<id>.md, creates handoff rows, and commits wiki updates atomically - LLM consolidation: If
AI_MEMORY_LLM_PROVIDERis configured,memory_consolidaterewrites summaries into richer conceptual pages (concepts/,decisions/) - Auto-improvement: Background jobs in
ai-memory-consolidatereview completed sessions and generate proposals through the standard wiki mutation path
This flow ensures all edits remain auditable through Git history while supporting real-time agent integrations.
Multi-Stream Retrieval Pipeline
The memory_query function implements Reciprocal Rank Fusion (RRF) across four parallel search streams:
| Stream | Index Type | Search Target |
|---|---|---|
| FTS5 | Full-text | Page titles and bodies |
| Entity | Front-matter | entities list in YAML headers |
| Link-neighbour | Graph | Wikilink relationships |
| Vector | Cosine similarity | Embedding space (when Embedder configured) |
Results merge with authority multipliersbased on tier (Working, Episodic, Semantic, Procedural), pinned status, and calculated salience. When AI_MEMORY_RERANKER=llm is set, a final LLM-based reranking pass reorders the result set.
Memory Tiers and Decay System
Pages categorize into four lifecycle tiers, each with distinct retention policies:
- Working: Active session data with short TTL
- Episodic: Past session summaries
- Semantic: Conceptual knowledge and decisions
- Procedural: How-to guides and instructions
A periodic forget sweep (implemented in ai-memory-store) applies tier-specific decay formulas, evicts cold pages, hard-deletes TTL-expired entries, and prunes raw observations while pinned pages remain exempt from all decay.
Security and Cross-Cutting Invariants
The architecture enforces strict invariants at the type system level:
- Single-writer SQLite: Prevents concurrent write transactions entirely
- Sanitiser isolation: Only path from untrusted hook data to storage
- Atomic wiki operations: Guarantees filesystem consistency via
fsync - Typed IDs: Every row enforces
workspace_id,project_id, andpathas a composite key - Zero-LLM default: Core functionality works without any
AI_MEMORY_LLM_PROVIDERconfigured
These invariants are enumerated in docs/ARCHITECTURE.md under Cross-cutting invariants.
Summary
- ai-memory uses a dual-layer design with markdown as the source of truth and SQLite for fast access
- Eight single-responsibility crates in
crates/enforce strict API boundaries and typed IDs - The single-writer actor pattern in
ai-memory-storeeliminates SQLite concurrency issues - RRF retrieval combines FTS5, entity matching, link graphs, and optional vector similarity
- Memory tiers with decay formulas and pinned exemptions manage storage lifecycle
- All mutations flow through the wiki layer, ensuring Git-auditable history without LLM dependencies
Frequently Asked Questions
How does ai-memory ensure consistency between the markdown wiki and SQLite index?
All writes originate in the wiki layer through atomic file operations (tmp + rename + fsync) in ai-memory-wiki, then propagate to the SQLite index via the single-writer actor in ai-memory-store. The wiki remains the authoritative source; the database is purely a derived view. If the database corrupts, it can rebuild entirely from the markdown files.
What is the single-writer actor pattern used in ai-memory-store?
The ai-memory-store crate implements an actor pattern where one dedicated connection handles all write operations through a message queue. This design eliminates SQLite's "database is locked" errors without complex retry logic, while a separate ReaderPool manages multiple read-only connections for concurrent queries.
Can ai-memory function without connecting to an LLM provider?
Yes. The system operates in zero-LLM default mode. All core features—wiki storage, SQLite indexing, session tracking, and decay management—work without any AI_MEMORY_LLM_PROVIDER configuration. LLM integration only enables optional features like semantic search embeddings, consolidation rewriting, and LLM-based result reranking.
How does cross-project linking work in the wiki architecture?
Wikilinks support the syntax [[project:path.md]] to reference pages across workspaces. The wiki parser extracts a LinkTarget { workspace, project, path } struct, and the store records these with to_workspace and to_project columns. This enables a global dependency graph while maintaining scope isolation, allowing agents to trace relationships across project boundaries without namespace collisions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →