Memory primitives
Lerim uses three core memory types:| Primitive | Purpose | Example |
|---|---|---|
| Decision | An architectural or design choice made during development | ”Use JWT bearer tokens for API auth” |
| Learning | A reusable insight, procedure, friction point, or preference | ”pytest fixtures must be in conftest.py for discovery” |
| Summary | An episodic record of what happened in a coding session | ”Refactored auth module, added rate limiting” |
Decisions and learnings are extracted automatically from agent sessions. Summaries are created for every synced session as episodic records.
Learning kinds
Learnings are further categorized by kind:insight
insight
A general observation or understanding that provides value for future work.Example: “React hooks must follow the rules of hooks — no conditionals, loops, or nested functions.”
procedure
procedure
A step-by-step process or workflow for accomplishing a task.Example: “To add a new API endpoint: 1) Define route in routes.py, 2) Add handler in controllers/, 3) Write tests in tests/api/”
friction
friction
Something that caused difficulty, slowdown, or frustration.Example: “Docker build takes 8 minutes on M1 Macs due to platform emulation. Use —platform linux/arm64 flag.”
pitfall
pitfall
A mistake or trap to avoid in the future.Example: “Never commit .env files — they contain production secrets. Add to .gitignore immediately.”
preference
preference
A stylistic or tooling preference, habit, or convention.Example: “Use single quotes for strings in Python. Auto-formatted with black —skip-string-normalization.”
Directory layout
Project scope: <repo>/.lerim/
Each registered project stores its own memories:
The
workspace/ directory contains detailed run artifacts for debugging. Each sync or maintain run gets its own timestamped folder.Global scope: ~/.lerim/
Shared across all projects:
Frontmatter schemas
All metadata lives in YAML frontmatter — no sidecars. The frontmatter schema is enforced by thewrite_memory runtime tool.
Decision frontmatter
id— Unique identifier (format:dec-{slug}orlrn-{slug})title— Short, descriptive titlecreated— ISO 8601 timestamp of creationupdated— ISO 8601 timestamp of last updatesource— Where the memory came from (usuallysyncormanual)confidence— Float from 0.0 to 1.0 representing extraction confidencetags— List of descriptive labels for categorization
Learning frontmatter
kind— One of:insight,procedure,friction,pitfall,preference
Summary frontmatter
id— Unique identifier (format:sum-{slug})title— Session titledescription— Brief session descriptiondate— Session date (YYYY-MM-DD)time— Session start time (HH:MM:SS)coding_agent— Platform name (claude,codex,cursor,opencode)raw_trace_path— Relative path to session JSONL filerun_id— Session identifier from the agent platformrepo_name— Repository name or pathcreated— ISO 8601 timestampsource— Usuallysynctags— List of topics/themes
Memory lifecycle
Memories flow through a simple lifecycle:1. Create
During sync, the extraction pipeline identifies memory candidates:- DSPy
ChainOfThoughtanalyzes transcript windows - Candidates are validated for quality and confidence
- Explorer subagent checks for existing similar memories
- Lead agent writes new memory files via
write_memorytool
2. Read
Query commands retrieve memories with project-first scope:lerim ask "question"— Natural language querylerim memory search "keyword"— Direct keyword search- Project memories are searched first, global fallback is planned
3. Update
When similar memories exist, the lead agent decides to merge or update:- Compare confidence scores
- Merge complementary information
- Update
updatedtimestamp - Keep the stronger memory and archive the weaker one
4. Archive
During maintain, low-value memories are soft-deleted:- Moved to
memory/archived/{primitive}/ - Not deleted permanently (can be restored manually)
- Triggered by low effective confidence or time-based decay
Confidence and decay
Each memory has aconfidence score (0.0 to 1.0) assigned during extraction. Over time, memories that aren’t accessed lose effective confidence through decay.
Decay calculation
Default decay settings
- Decay period: 180 days
- Confidence floor: 0.1 (never drops below)
- Archive threshold: 0.2 (effective confidence below this triggers archiving)
- Grace period: 30 days (recently accessed memories skip decay)
Access tracking happens automatically when memories are read via
lerim ask or lerim memory search. The access timestamp and count are stored in index/memories.sqlite3.Scope resolution
Lerim supports three memory scope modes (configured via[memory] scope in config):
| Scope | Read behavior | Write behavior |
|---|---|---|
project_fallback_global (default) | Read from project first, fall back to global | Write to project |
project_only | Project only | Project only |
global_only | Global only | Global only |
Global memory fallback is configured but not yet fully implemented in the runtime. Memories are currently project-scoped only.
File naming convention
Memory files follow a consistent naming pattern:- Date prefix: Extracted from the sync run ID or current date
- Slug: Generated from the title using
slugify()— ASCII only, lowercase, hyphens for spaces
20260220-use-jwt-auth.md20260221-pytest-fixtures.md20260222-docker-m1-performance.md
Reset policy
Memory reset is explicit and destructive:What’s next?
Sync and maintain
Learn how memories are extracted and refined
CLI reference
Explore all memory commands
Configuration
Configure decay settings and memory scope
API reference
Use the HTTP API to query memories