Skip to Content

Memory

The CMDOP agent has two kinds of memory: working memory (the messages in the current session) and persistent memory (a shared SQLite store the agent can write to across sessions). They serve different purposes and are wired in different places.

Two layers

LayerLifetimeWhere it lives
Working memoryOne sessionThe message list, rebuilt every turn
Persistent memoryCross-sessionA single memory.db SQLite file in the user’s data directory

Working memory is the conversation history the LLM sees on the current turn. Persistent memory is something the agent explicitly chose to remember by calling a memory tool.

Working memory — the turn cycle

Every turn the runner injects fresh system context (identity, env info, target machine hints) and replays the message history. There are no hidden long-term facts at this layer — what the LLM sees is exactly what is in the message list plus the system prompt.

Working memory carries:

  • The user’s prompts.
  • The assistant’s previous replies.
  • Tool call requests and tool results.
  • The current todo list (re-injected each turn so the agent stays oriented).

When the history grows large, the chat layer can call the Jarvis summary agent to produce a brief summary that replaces older turns and reduces token debt.

Persistent memory — the SQLite store

memory.db is a single SQLite file lazy-opened by whichever consumer needs it first. Two consumers share one file:

ConsumerNotes
Local chat (CLI / TUI / Desktop)Opens the store on first use
Remote ask_machine (daemon)Opens the same store on first remote call

The store is opened once and shared safely across concurrent callers. If it fails to open, the chat logs a warning and continues without memory tools rather than failing the turn.

Memory tools

When the store is wired, four memory tools become available to the agent:

ToolPurpose
remember_topicStore a fact under a topic key.
recall_memoryLook up facts by topic or free-text query.
list_memoriesBrowse stored topics.
forget_topicRemove a topic and its associated facts.

If a session never sees these tools despite a healthy DB, the surface hosting that session was started without a memory store attached. That is the canonical debug path.

How the agent decides what to remember

The agent is responsible for calling the memory tools — the system does not auto-summarise into the store. Typical patterns the system prompt encourages:

  • Long-lived preferences (“user prefers TypeScript over JavaScript for new components”).
  • Project anchors (“the auth service is at services/auth”).
  • Cross-session facts the next turn would otherwise have to rediscover.

Things that should not go into persistent memory:

  • Secrets or credentials.
  • High-churn state (current branch, current todo).
  • Arbitrary chat content “just in case”.

Storage and isolation

Persistent memory is per-installation, not per-fleet. The memory.db store in the user’s data directory is shared across all sessions on that machine for the user that owns the daemon. If you need fleet isolation, use distinct OS users.

Switching fleets does not switch memory stores. If you store project-specific context, prefix topics with the project name so recall stays clean.

Don’t store secrets in memory. The store is not encrypted and is readable by any process running as the same OS user.

What is not memory

Several adjacent features get confused with memory and are documented elsewhere:

  • Sessions — persistent transcripts, see Sessions.
  • Todo list — the current plan, replayed each turn but stored in the session, not in memory.db. See todo_write in Tools.
  • Skill state — skills run as sub-sessions; their internal state is theirs to manage.

Background reading: Persistent Memory Is Not Persistent Execution State — why remembering you started a server is not the same as a server being alive.