Where ljos fits among agent memory tools
Mem0, Zep, Letta, and most agent memory let a model decide what to keep. A CLAUDE.md file is the exception, and you write it by hand. ljos keeps only what you tell it to keep. That one choice explains most of the table below, including where ljos is behind.
Which to pick
Mem0, Graphiti and Letta suit memory that builds itself from conversations, with a model doing the extraction. A CLAUDE.md or AGENTS.md file is enough when one page of standing notes covers it. A plain retrieval index over your documents answers questions about those documents. ljos fits when each memory should be a sentence someone chose to write, kept in local files and searched back per prompt, next to a rule check on shell commands and a ticket tracker.
Side by side
| ljos | Mem0 | Graphiti (Zep) | Letta | Plain retrieval index | CLAUDE.md file | |
|---|---|---|---|---|---|---|
| Who writes a memory | You, by saying Remember: or Prefer:. A lesson an agent drafts waits until you accept it. | A model extracts facts from each conversation you pass to add(). | A model extracts entities, relations and their validity dates from each episode. | The agent edits its own memory files with tools; background subagents can consolidate from conversations. | Whatever you index. | You, or the agent when asked. |
| The unit | One claim, two sentences at most, with its kind, age and review date. | An extracted fact, with vectors and linked entities. | A temporal graph of entities and facts, traced to source episodes. | Markdown files in a git repository. | Chunks and their embeddings. | One Markdown file. |
| How it comes back | Searched per prompt: BM25+, plus a local encoder when installed, fused. | Semantic, keyword and entity search, fused. | Semantic, keyword and graph search. | Some files sit in every prompt; the agent reads the rest on demand. | Top-k by similarity. | The whole file, every session. |
| Model needed to write | No. | Yes; gpt-5-mini by default. | Yes; OpenAI by default. | The agent's own model. | An embedding model. | No. |
| Where it lives | Local files and a loopback daemon. | Your vector store, or the hosted platform. | A graph database (Neo4j, FalkorDB, Neptune), or Zep's cloud. | A Letta server, Letta Cloud, or your git remote. | Your index. | Your repository. |
| Shell command check | Yes: fixed rules plus yours, before each command. | Not part of a memory layer. Use the runner's own permissions. | ||||
| Work tracker | Yes: vissue, plain Org files in git. | Not included. | ||||
| Licence | MIT (claimdag: Apache-2.0 OR MIT) | Apache-2.0 | Apache-2.0 | Apache-2.0 | Depends | None needed |
Where ljos is behind
- Retrieval accuracy. On LongMemEval_S session retrieval the fused arm reaches recall@5 0.949. A public neighbour reports 95.2% R@5 on the same protocol, so the two are level. The lexical arm scores 0.568 on MemoryAgentBench accurate retrieval, below the published BM25 row of 0.605 (that row used GPT-4o-mini as the reader; ours used a local 7 B model). The measured rows and where the data is.
- Changing facts. Graphiti keeps a validity window on every fact. ljos closes an earlier lesson only when a new one opens with the same words, and scores 0.395 on MemoryAgentBench conflict resolution at 262K tokens. The measured row and where the data is.
- Question answering. Those scores come from a local 7 B reader. Its answer accuracy on LongMemEval_S is 0.549 against a 0.634 ceiling for perfect sessions. Projects that use a hosted reader and judge report higher answer accuracy (one on the compare page reports 96.20%); the protocols differ, and we have not run a hosted model.
- It forgets what nobody said. Answers can only use what was written, and nothing is extracted from the conversation. If you never say Remember:, the next session starts without it. That is the point, and it is also a cost.
What we think is new
The parts all have neighbours: hybrid retrieval, review schedules, ticket trackers, command filters. What we have not found elsewhere is the combination with provenance kept on every write: memory written only by declaration, no model in the write path, lessons an agent drafts held until you accept them, and artefacts recorded as hashed deeds the tracker cites.
Tools that build memory from transcripts can be poisoned by text that reaches the transcript, such as a web page or a tool result. Writing only on declaration should resist that. We have not yet measured it; that test is the next piece of work, and the results will go on the compare page when they exist.
Sources: each project's README and documentation (Mem0, Graphiti, Letta), read on 10 October 2026. Corrections are welcome as issues.