Skip to main content
Claurst provides two tiers of memory: an in-process short-term store for the current conversation, and a file-based long-term store called memdir that persists knowledge across sessions. A background consolidation process called AutoDream keeps the long-term store organised and within size limits.

Short-term memory: session history

The current conversation is held in a Vec<Message> in the cc-query loop. It accumulates user messages, assistant responses, tool use blocks, and tool result blocks as the session progresses. Sessions are persisted to disk at ~/.claude/conversations/<uuid>.json after each completed turn via cc_core::history::save_session(). The ConversationSession struct carries:
pub struct ConversationSession {
    pub id: String,                 // UUID v4
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub messages: Vec<Message>,
    pub model: String,
    pub title: Option<String>,
    pub working_dir: String,
}
Previous sessions can be resumed with --resume <session-id> on the CLI.

Long-term memory: memdir

Long-term memory is stored as markdown files with YAML frontmatter in a per-project directory:
~/.claude/
  projects/
    <sanitized-git-root>/
      memory/
        MEMORY.md           # Entrypoint index (always loaded into the system prompt)
        <topic-file>.md     # Individual memory files with frontmatter
        team/               # Team-shared memories (when team memory is enabled)
          MEMORY.md
          <topic-file>.md
Every memory file has YAML frontmatter:
---
name: No mocks in integration tests
description: Integration tests must use a real database, not mocks
type: feedback
---

**Rule:** All integration tests connect to a real PostgreSQL instance.
**Why:** Mocks hid a class of serialization bugs that only appear against real DB drivers.
**How to apply:** Whenever writing or reviewing integration tests.
The four memory types are user, feedback, project, and reference. The type field controls how the memory is scoped in combined (personal + team) mode. The MEMORY.md entrypoint index is always loaded into the system prompt. It is kept under 200 lines / ~25 KB by the AutoDream pruning phase.

Memory scanning

Before each query, Claurst scans the memory directory:
  1. scanMemoryFiles() reads the frontmatter of every .md file (first 30 lines only) to build a MemoryHeader[] manifest without loading full content.
  2. The manifest is passed to a side-query (selectRelevantMemories()) using a Sonnet model call with max 256 tokens. It returns up to 5 filenames that are clearly relevant to the current query.
  3. The selected files are read in full and injected into the context. Memories older than 1 day include a <system-reminder> freshness caveat warning that citations may be outdated.

AutoDream consolidation

AutoDream is a background memory consolidation process. It runs as a forked sub-agent and performs a reflective pass over the memory files to synthesise recent signal into durable, well-organised memories.
AutoDream uses a three-gate trigger to prevent both over-dreaming and under-dreaming. All three gates must pass before a dream run begins:
  1. Time gate — at least 24 hours have elapsed since the last dream.
  2. Session gate — at least 5 sessions have occurred since the last dream.
  3. Lock gate — a consolidation lock can be acquired (prevents concurrent dreams).

The four dream phases

1

Orient

The dream agent runs ls on the memory directory, reads MEMORY.md, and skims existing topic files to understand the current state of memory before making any changes.
2

Gather recent signal

The agent searches for new information worth persisting. Sources are checked in priority order: daily logs (KAIROS mode) → drifted memories → transcript search. Relative dates are noted for later conversion to absolute dates.
3

Consolidate

The agent writes new memory files or updates existing ones. It converts relative date references to absolute dates, deletes facts that have been contradicted, and merges redundant entries.
4

Prune and index

The agent ensures MEMORY.md stays under 200 lines and approximately 25 KB. Stale pointers to files that no longer exist are removed. Contradictions between files are resolved. The index is updated to reflect the current set of topic files.
The dream prompt that drives this process states:
“You are performing a dream — a reflective pass over your memory files. Synthesize what you’ve learned recently into durable, well-organized memories so that future sessions can orient quickly.”
The dream sub-agent is given read-only bash access. It can observe the project (run ls, git log, grep) but cannot modify source files. Memory consolidation is the only write operation it performs, and it is confined to the memory directory.

Memory index constraints

The MEMORY.md entrypoint is kept within strict limits by the prune phase:
ConstraintLimit
Maximum lines200
Maximum bytes~25 KB (25,000 bytes)
When either limit is exceeded, truncateEntrypointContent() line-truncates first, then byte-truncates at the last newline before the cap. A warning is appended naming which cap fired.

What not to store in memory

The memory system is designed for information that is not derivable from the codebase itself. The following should not be saved as memories:
  • Code patterns, architecture, or file structure (read the code directly)
  • Git history or recent changes (use git log)
  • Debugging solutions or fix recipes (the fix is in the code)
  • Anything already in CLAUDE.md
  • Ephemeral task details or in-progress work

Build docs developers (and LLMs) love