Architecture overview
Lerim follows a simple, file-first philosophy:- Memory primitives are stored as plain markdown files in
.lerim/directories - No database required — files are the canonical store
- Project-scoped by default — each repository gets its own memory store
- Agent-agnostic — works with Claude Code, Codex, Cursor, OpenCode, and more
lerim serve) that provides:
- Daemon loop for continuous sync and maintenance
- HTTP API for CLI commands and agent integrations
- Dashboard UI for browsing memories and sessions
When you run
lerim up, Docker starts the service in a container. Alternatively, use lerim serve to run directly without Docker.Data flow
Lerim operates through two primary paths: sync and maintain.The sync path
The sync path processes new agent sessions and extracts memories:
- Discover sessions — Platform adapters scan agent storage directories (e.g.,
~/.claude/projects/,~/.codex/sessions/) - Index sessions — New or modified sessions are added to the queue in
~/.lerim/index/sessions.sqlite3 - Read transcript — The lead agent loads one session transcript at a time
- Extract candidates — DSPy pipeline analyzes the transcript and identifies decision and learning candidates
- Deduplicate — Explorer subagent checks existing memories to avoid duplicates
- Write memories — Lead agent creates new memory files in
<repo>/.lerim/memory/ - Write summary — An episodic summary of the session is stored in
memory/summaries/
lerim up, or manually with lerim sync.
The maintain path
The maintain path runs offline refinement over stored memories:
- Scan memories — Load all existing decision and learning files from
memory/ - Merge duplicates — Identify and consolidate similar memories
- Archive low-value entries — Move memories with low effective confidence to
memory/archived/ - Consolidate related memories — Group and strengthen related learnings
- Apply time-based decay — Reduce confidence for memories that haven’t been accessed recently
lerim maintain.
Maintenance is non-destructive — archived memories are moved to
memory/archived/ rather than deleted.Agent orchestration
Lerim uses PydanticAI for agent orchestration with strict security boundaries:Lead agent
The lead agent orchestrates all flows and is the only component allowed to write memory files:- Tools:
read,glob,grep,write,write_memory,edit,extract_pipeline,summarize_pipeline - Write boundary: Runtime tools deny writes outside
memory_rootand workspace directories - Deterministic decision policy: Uses
add|update|no-oplogic to avoid duplicate or low-value memories
Explorer subagent
A read-only agent delegated from the lead for gathering existing memory context:- Tools:
read,glob,greponly - Cannot write — no access to write or edit tools
- Purpose: Find similar memories to help with deduplication
DSPy pipelines
Called as tools from the lead agent:- Extraction: Uses
dspy.ChainOfThoughtwith transcript windowing to extract memory candidates - Summarization: Creates structured session summaries with frontmatter metadata
- Windowing: Large transcripts are split into overlapping windows (default 300K tokens per window with overlap)
Deployment model
Lerim runs as a single process that combines the daemon, HTTP API, and dashboard:init, project add, up, down) run on the host and manage configuration.
Service commands (ask, sync, maintain, status) are thin HTTP clients that forward requests to the running server.
Storage model
Project scope: <repo>/.lerim/
Each registered project stores its own memories and run artifacts:
Global scope: ~/.lerim/
Shared across all projects:
Memories are always project-scoped. The
project_fallback_global mode exists in config but global memory fallback is not yet implemented.Scope resolution
Configuration is loaded in priority order (low to high):src/lerim/config/default.toml(shipped defaults)~/.lerim/config.toml(user global)<repo>/.lerim/config.toml(project overrides)LERIM_CONFIGenv var (explicit override for CI/tests)
ZAI_API_KEY, OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY.
Security boundaries
Lerim enforces strict security boundaries to prevent agents from writing outside approved directories:- Runtime tools reject
writeandeditoperations outsidememory_rootand workspace roots - Memory files can only be created via the
write_memorytool, which accepts structured fields and builds markdown in Python — the LLM never assembles frontmatter directly - All file operations use Python tools (no shell/subprocess execution)
- Explorer subagent is read-only
- HTTP API binds to
127.0.0.1by default (localhost only, no auth needed)
Observability
Lerim uses minimal stderr logging with detailed tracing through OpenTelemetry:- Loguru for short status lines on stderr
- OpenTelemetry + Logfire for detailed agent traces, model calls, tool calls, tokens, and timing
- Per-run LLM cost tracking via OpenRouter’s usage data
- Activity log at
~/.lerim/activity.logrecords sync/maintain cycles with stats and costs
LERIM_TRACING=1 or [tracing] enabled = true in config.
What’s next?
Memory model
Learn about the file structure, frontmatter schemas, and memory primitives
Sync and maintain
Understand the sync and maintain processes in detail
Supported agents
See which coding agents are supported and how sessions are stored
Configuration
Configure models, roles, tracing, and more