Design principles
Lerim follows three fundamental design principles that inform all architectural decisions:File-first architecture
Memories are stored as plain markdown files with YAML frontmatter, not in proprietary databases. This design choice ensures that:- Humans can read and edit memories directly in any text editor
- Agents can traverse memory using standard file operations
- Version control works naturally with git
- No database lock-in or schema migrations
- Backup and sync tools work without special adapters
Primitive-first memory model
Lerim organizes knowledge into three memory primitives:- decisions — explicit architectural or design choices
- learnings — insights, procedures, frictions, pitfalls, and preferences
- summaries — session narratives with user intent and outcomes
id and slug references in frontmatter, not from vector embeddings or proprietary indexes.
Project-scoped memory
Memories are stored per-project in<repo>/.lerim/ by default. This keeps context local to the codebase and prevents knowledge bleed between unrelated projects. A global fallback scope exists at ~/.lerim/ for memories outside git repositories.
The
project_fallback_global scope mode is configured but global fallback retrieval is not yet implemented in the runtime. Memories are currently project-only.System components
Deployment model
Lerim runs as a single process (lerim serve) that provides:
- Background daemon for sync and maintenance cycles
- HTTP API server on
localhost:8765 - Dashboard web UI for session analytics and memory browsing
lerim up, but can also be started directly for development.
lerim ask, lerim sync, and lerim status are thin HTTP clients that forward requests to the server.
Architecture diagram
The system processes agent sessions through three main flows:Component responsibilities
Component responsibilities
Adapters — Platform-specific connectors that discover and normalize sessions from Claude, Codex, Cursor, and OpenCode into JSONL format.Session Catalog — SQLite database with FTS index for session metadata and job queue state.Lead Agent — PydanticAI orchestrator with runtime tools for extraction, summarization, and memory writes.Explorer Subagent — Read-only PydanticAI agent delegated by the lead for evidence gathering.DSPy Pipelines — ChainOfThought extraction and summarization with transcript windowing.Memory Store — Markdown files in
decisions/, learnings/, summaries/ with YAML frontmatter.HTTP API — JSON REST API for CLI, skills, and dashboard communication.Data flow overview
Sync flow
- Session discovery: Adapters scan platform-specific session stores (JSONL files or SQLite databases)
- Normalization: Sessions are exported to JSONL format in
~/.lerim/cache/ - Indexing: Session metadata is indexed in
sessions.sqlite3with FTS for search - Extraction: Lead agent orchestrates DSPy extraction pipeline with transcript windowing
- Deduplication: Explorer subagent finds existing memories; lead agent applies
add|update|no-oppolicy - Memory write: Lead agent writes new/updated memories via boundary-enforced runtime tools
- Summarization: DSPy summarization pipeline creates session narrative in
summaries/
The sync flow processes one session at a time. The lead agent receives only the
trace_path and creates a workspace folder for all run artifacts.Maintain flow
- Scan: Lead agent reads all memories in the project’s memory folder
- Merge: Identifies and merges near-duplicate memories
- Archive: Soft-deletes low-confidence or stale memories to
archived/ - Consolidate: Combines related memories into higher-level insights
- Decay: Applies time-based confidence decay based on access patterns
- Report: Writes
maintain_actions.jsonwith operation counts
Query flow
Theask and memory search commands are read-only:
- File scan: Default search uses
globandgrepover markdown files (no index required) - FTS search: Optional full-text search via SQLite FTS virtual table
- Access tracking: Reads are recorded in
memories.sqlite3for decay calculations - Response: Lead agent (for
ask) or direct search (formemory search) returns results
Storage model
Per-project storage
Global storage
Configuration precedence
Configuration is layered from low to high priority:- Package defaults —
src/lerim/config/default.toml(shipped with package) - User global —
~/.lerim/config.toml - Project overrides —
<repo>/.lerim/config.toml - Environment override —
LERIM_CONFIGenv var path (for CI/tests)
ZAI_API_KEY— primary API keyOPENROUTER_API_KEY— OpenRouter key for DSPy pipelinesOPENAI_API_KEY— optional OpenAI direct keyANTHROPIC_API_KEY— optional Anthropic direct key
Security boundaries
Lerim enforces strict runtime boundaries:- Write boundary: Runtime tools deny
writeandeditoutsidememory_rootand workspace folders - Memory primitive enforcement: Memory files can only be created via
write_memorytool (Python builds frontmatter, LLM never touches YAML) - Read-only subagent: Explorer subagent has only
read,glob,greptools (no write/edit) - No shell execution: All file operations use Python tools (no subprocess)
- Local-only HTTP: API binds to
127.0.0.1by default (no auth needed)
See
runtime/tools.py lines 142-149 for write boundary implementation.Next steps
Extraction pipeline
Learn how DSPy ChainOfThought extracts memories from transcripts
Agent runtime
Understand the PydanticAI lead agent and subagent orchestration
Adapters
Explore platform-specific session adapters and normalization