Architecture

Last verified against the code: 2026-11-13 (0.9.0)

One Python package, one SQLite file, five stages. No service, no server, no dependencies.

 ~/.claude/projects/<project>/*.jsonl            the raw stream (Claude Code transcripts)
            │
            ▼  remem ingest          transcripts.py → ingest.py
 ┌─────────────────────────────┐
 │  ~/.remem/memory.db    │  episodes (session / error / correction / surprise / environment / note), sessions,
 │                             │  lessons, predictions            store.py, embed.py
 └─────────────────────────────┘
      │              │
      │ recall       │ sleep (nightly)      sleep.py: decay → lessons → verify → predict
      ▼              ▼
  recall.py      render.py ──▶ ~/.claude/projects/<project>/memory/   om-<id>.md + a section of MEMORY.md
  (CLI, MCP)                ──▶ ~/.remem/lessons.jsonl           the wire format
                            ──▶ ~/.remem/morning.md              the owner's report

Components

Component File Role
Paths remem/paths.py Every location, each overridable by an environment variable
Transcripts remem/transcripts.py Claude Code JSONL → Session of Turns (mid-turn messages included, harness lines left out); tool calls paired with their results; corrections, refusals, error classes and stated surprises read
Store remem/store.py SQLite schema and all reads and writes; strengths, touches, predictions
Embed remem/embed.py A local embedding model through Ollama when there is one, else 256-dimension hashed word and bigram vectors; each vector tagged with its space; cosine, relevance, centroid
LLM remem/llm.py Optional local model over an OpenAI-compatible API; every call fails soft to None
Ingest remem/ingest.py Sessions → episodes; deterministic gist or a model-written one
Recall remem/recall.py Scoring (relevance, recency, strength), touching, formatting
Sleep remem/sleep.py The six nightly passes (embed, decay, lessons, merge, verify, predict) and the morning report text
Prime remem/prime.py Three hooks, one command: lessons a prompt bears on (UserPromptSubmit), correction lessons a hand-back at the end of a turn bears on (Stop), error lessons a tool call bears on (PreToolUse); once per session, half the sessions held out, all logged
Delegation remem/delegation.py Counts "asked, told to act" (a correction after a hand-back) and "acted, stopped" (a refused call) by kind of action; shown to the owner in morning.md, not to agents (0.8.0)
Setup remem/setup.py Wires every installed agent: Claude Code hooks and MCP; MCP for Claude Desktop, Cursor, Windsurf, Gemini CLI, Codex; the nightly cron
Chats remem/chats.py Conversations from any model (OpenAI, Anthropic, Gemini message formats) → Session, for the same detectors
Events remem/events.py The open event format (PROTOCOL §0) → episodes; MCP remember, --events, the inbox, the proxy
Proxy remem/proxy.py OpenAI- and Anthropic-compatible proxy: memory into every system prompt, conversations recorded; the /memory/* HTTP API
Ed25519 remem/ed25519.py RFC 8032 signatures in pure Python, for signed sharing
Codex remem/codex.py Codex CLI's session files → Session (experimental)
Installer site/install-src/install.sh, scripts/build-site.mjs One-line install on another machine from /install/ (token-gated): checksummed wheel, uv, setup, commons
Release check scripts/release-check.py Every release step checked mechanically; a release is done only when it passes
Commons src/commons.js The Worker's /commons/ route: one signed file per memory in KV, writes verified with WebCrypto Ed25519
Share remem/share.py Lessons between memories: export with hash and origin, receive as candidates (safety checks, corroboration by hash or meaning), confirmations back, revocations, sync through a folder
Experiment remem/experiment.py Controlled tests on a model: behaviour, mechanism, loop (tools), boundary (where asking is right); training pairs
Goals remem/goals.py Goals A1–A10 checked from the kept experiments, the store and the adapters
Adapter scripts/adapter.py Compiled memory: a LoRA adapter trained on the reminder pairs, tested with no reminder (outside the stdlib CLI)
Compare remem/compare.py Replays the history: Remem against retrieve-similar memory on repeated corrections, and what each injects
Measure remem/measure.py Goal 10: the repeat-yourself and repeated-error rates, prediction accuracy, themes, by day
Render remem/render.py Lesson files, the managed section of MEMORY.md, vetoes, lessons.jsonl
MCP remem/mcp.py JSON-RPC over stdio: initialize, tools/list, tools/call (recall, remember)
CLI remem/cli.py status, setup, ingest, recall, sleep, measure, compare, experiment, goals, prime, morning, serve, proxy, share, context, tools, call, hook, paths

The store

Five tables in memory.db (SCHEMA in store.py):

Table Columns Notes
episodes id, session_id, cwd, kind, title, gist, detail, at, created, strength, recalls, last_touched, archived, embedding kind is session, error, correction, surprise, environment or note; id is a hash of session, kind and title (stable across re-reads; notes keep random ids); embedding is a JSON list (hashed) or {"s": model, "v": [...]} (a model's space)
sessions id, path, mtime, ingested, episodes, offers Makes ingest idempotent; a changed mtime re-reads the session. offers (0.2.3) is JSON: each reply that offered to act, its kind and how the person answered (corrected, declined, approved, other), and how many replies waited on the person
lessons id, text, kind, cwd, strength, seen, sources, created, updated, embedding, origin, hash, origins sources is a JSON list of episode ids (empty for a lesson from another memory); origin the memory it came from, hash its identity across memories, origins the memories that corroborated or confirmed it (0.4.0)
predictions id, lesson_id, text, made, resolved, outcome, embedding outcome is confirmed or failed once resolved
aliases old, new, at, created A lesson merged into a theme (old) and the theme it lives on in; created is when the old lesson was made, so the measure knows how long the theme has been in mind

Timestamps are ISO 8601 UTC with microseconds, so "created after this prediction was made" is unambiguous.

Data flow in detail

  1. Ingest lists every top-level *.jsonl under every project folder (subagent transcripts in subfolders are skipped). For each file whose mtime is new, parse() builds turns: user text (meta lines and slash-command records stripped), assistant text and tool calls merged across the streamed records of one turn, and tool results attached to the assistant turn that made the call. episodes_of() yields one session episode and one per surprise. Each episode's embedding is of its title and gist, except a correction's, which is of the person's words alone; one batch per transcript.
  2. Recall scores every unarchived episode and every lesson: 0.6·cosine + 0.25·2^(−age/30d) + 0.15·min(strength,2)/2, returns the top k, and touches the episodes it returned (+0.1 strength, +1 recall).
  3. Sleep first embeds again whatever is not in the current space, then runs decay (strength × 2^(−days since last touch / 45); below 0.15 → archived), consolidation (surprises join the lesson whose sources they resemble, by mean cosine ≥ 0.62 in a model's space or 0.55 hashed, or cluster into a new one; one correction suffices, an error or a stated surprise must repeat; environment episodes are never consolidated), merging (lessons of one kind whose sources mean the same thing, by average linkage, become one theme; the others become aliases), verification (open predictions matched against episodes of the lesson's kind that happened since, cosine ≥ 0.5 hashed or the same-surprise cut; failed after 14 days), prediction (one per lesson with strength ≥ 1 and no open prediction).
  4. Render writes one remem-<id>.md per lesson into each project's memory folder (lessons with no cwd go everywhere) and rewrites only the section of MEMORY.md between the markers. written.json records what was written; a lesson whose file is missing on the next render is added to vetoed.json.

Where it runs

On the person's machine only. The CLI runs on demand; sleep is meant for cron; serve is started by the agent (Claude Code) as an MCP server; ingest --quiet is meant for the agent's SessionEnd hook. See OPERATIONS.md.

What is designed but not built

The commons (sharing lessons between agents under verification), compiled memory (lessons as a model's attention state) and the raw stream beyond the terminal are described in the paper §5, §6 and §3.2, the protocol in PROTOCOL.md, and the order of work in ROADMAP.md.