Skip to content

The Memory Stack

Published: at 12:14 PM

Table of contents

Open Table of contents

Memory is a stack, not a switch

For a while I treated memory as a feature: flip it on, the agent remembers, done. It kept biting me. Memory was too sticky, too forgetful, or the wrong shape — a transcript when I wanted a fact, a fact when I wanted a timeline.

The fix: stop treating memory as one component. It’s a stack. Four layers, bottom to top:

The memory stack — four layers, bottom to top: provider, policy MCP, memory law, memory router

Each layer only knows the one beneath it. The provider doesn’t know your rules. The MCP doesn’t care which provider it writes to. That separation is the point: swap a provider without touching a rule.

Layer 1: The integration provider

Where memory physically lives, plus the integration that reads and writes it. Your storage engine. Like databases, providers specialize — there’s no “best” one, just the one whose strengths match your workload.

Don’t pick on vibes. Evaluate. LongMemEval and LOCOMO are the long-horizon benchmarks; trace runs with Langfuse to see what got recalled and what got dropped. Pick on numbers, not a landing page.

Evaluating a memory provider — candidates run through LongMemEval and LOCOMO, traced in Langfuse, picked on numbers

The provider is dumb storage plus retrieval. It doesn’t know what’s worth remembering. That judgment lives higher up.

Layer 2: The policy MCP

MCP (Model Context Protocol) is how the agent talks to memory. A policy MCP sits between the agent and the providers and decides how memory gets shaped, written, and searched. Same providers underneath, different memory depending on what’s on top.

The one I keep coming back to is mempalace. It doesn’t store blobs — it records entities, in a literal memory-palace structure:

Add session search — recall across past sessions — and you have what you need: write structured memories, find them across time, follow the links between them.

The MCP is policy plus structure. It turns “store this string” into “file this entity in the right drawer, link it, don’t duplicate it.”

The policy MCP files a raw string as an entity — wing, room, drawer, linked by a tunnel, with knowledge graph, taxonomy, and dedup

Daily memory vs categorized memory

This split is why you run more than one thing.

You don’t pick one. You compose: daily memory for what happened, categorized memory for what’s true, a persistence provider holding both up.

Daily memory as a time-indexed diary versus categorized memory as an entity-indexed graph

Layer 3: The memory law

The rules — what gets remembered, when, how it’s categorized. No provider, no MCP encodes your judgment. You do, in plain markdown.

The hierarchy I run, in precedence order:

  1. .hermes.md / HERMES.md
  2. AGENTS.md
  3. CLAUDE.md
  4. editor rules (e.g. cursor rules)

(SOUL.md is special — read from HERMES_HOME, not the project.)

Memory law precedence — HERMES.md over AGENTS.md over CLAUDE.md over editor rules; SOUL.md read from HERMES_HOME

These files hold the laws every layer below obeys:

They’re laws because everything underneath follows them. The MCP files what they tell it to. The provider just stores it.

When the rules don’t fit, fork them — add your own, override a built-in. The law is the one part of the stack you’re meant to edit. But a law only governs tools that already exist. New tools live one layer up.

Layer 4: The memory router

A law governs the tools that exist. The router decides which tools exist.

It’s the memory code in the harness — the part that turns “remember this” into an actual operation. By default it does one thing: append to memory.md. That’s the floor.

Fork it. Modify the source, give the router the memory tools your work needs — a custom write path, a sharper recall query, a tool that files straight into the provider or MCP instead of a flat file. Different needs, different tools.

Default memory router only writes memory.md; a forked router adds custom memory tools wired to the provider or MCP

Providers and MCPs are interfaces you adopt. Laws are text you own. The router is code you rewrite.

Putting it together

Bottom-up, the whole thing is small:

Memory isn’t a switch. It’s a stack — and a stack tells you where to look when it breaks. Too sticky? The law. Bad recall? The provider. Wrong shape? The MCP. Tool doesn’t exist? The router. One fuzzy “memory” feature, and you’re guessing. Four layers, and every problem has a floor.