Three agent projects independently built the same memory structure: layers of summary at coarsening resolution, with the raw material at the bottom. A fourth declined to build one at all and shipped a plugin interface with eight backends behind it.
I read the source of all four. I have run only my own, so everything below about Headlong, Hermes and OpenViking is what their code and design docs say, not how they behave under load.
Headlong’s pyramid is Bash
Headlong (Laude Institute) runs an agent that never sleeps. Its short-term memory was a hard 20-step tail, and one identity hit 2,176 steps on its first day. The problem statement in design/tiered_memory.md names the constraint better than I have seen it named elsewhere: raising the tail “doesn’t fix it, it just moves the cliff”, because a linear tail cannot both show recent detail and cover a whole life.
The fix is a logarithmic pyramid over the trajectory, in bin/recap:
WINDOW=100 # max filtered steps per episode
MIN_GAP_WINDOW=10 # never gap-cut a window smaller than this
FANOUT="${ROLLUP_FANOUT:-10}" # tier k covers F^k steps
Blocks are keyed by filtered-step index range, sealed immutable, and cached forever. Only the frontier gets built on each run. The staircase budget is derived from the context window of the model in use, so a bigger window buys more detail at every level rather than a longer tail.
That doc is marked Status: COMPLETE. A second one, unified_progressive_resolution_memory.md, is marked NOT YET IMPLEMENTED, and the two are easy to confuse. The pyramid shipped. What has not shipped is the join between it and Headlong’s other memory store, the curated mem entries, which are markdown files with id, summary, type and created in frontmatter. Retrieval over those is a brute-force LLM scan, linear in entries.
So the pyramid solved episodic recall and left semantic recall O(n). The unified doc exists to close that.
OpenViking calls it a filesystem
OpenViking from Volcengine describes itself as a context database for agents, and its README frames the design against the alternative: an agent browses context with “ls, tree, and find instead of querying a black-box vector store”. Everything lives under a viking:// scheme.
Content is written at three resolutions and loaded on demand: an abstract of about 100 tokens, an overview of about 2,000, and the full original underneath. Retrieval is hybrid, and the README describes it as vector search locating the highest-scoring directory first, then drilling down layer by layer.
Directories carry their own abstract and overview, so a whole branch can be ruled out before any file inside it is opened. That is the one thing here the other three do not have: everyone else summarises time spans, where OpenViking summarises containers.
Their published LoCoMo figures move Hermes from 33.38% to 82.86% and Claude Code from 57.21% to 80.32%, with input tokens down between 34.3% and 91.0%. Those are vendor self-reported, and the memory evaluation ran on Volcengine’s own Doubao models, so I would not assume the deltas transfer to another provider until someone reruns them.
Mine is deterministic on purpose
I wrote about shipping the ladder in ai-coworkers already. The part worth repeating against this comparison is the divergence, which is in the header of src/tools/mem_walk.ts:
// PURITY - divergence from Headlong, per ADR-0008: Headlong's design has the
// *model* navigate each ladder level in its own context. We keep this tool
// pure: deterministic SQL + TypeScript navigation, ZERO LLM calls inside the
// tool.
Most ticks in this runtime never reach the model. A navigation scheme that spends a model call per level would put the model back in the loop for every recall, which is the cost the tick loop exists to avoid. So the model issues one call and gets the whole pre-navigated trace back.
The tunables ship as fixed values rather than config:
| Constant | Value | Reason |
|---|---|---|
CONFIDENCE_THRESHOLD | 0.5 | half the distinct query tokens must match before walking |
CANDIDATES_PER_LEVEL | 3 | Headlong’s cost model allows ~10; three keeps the trace readable |
RAW_EVENT_CAP | 40 | ceiling across every branch of one walk |
MAX_WALK_DEPTH | 8 | the ladder is acyclic by construction; this catches corrupted links |
Hermes made it somebody else’s decision
Hermes has no memory architecture. agent/memory_provider.py defines an abstract base class and plugins/memory/ holds the implementations: byterover, hindsight, holographic, honcho, mem0, openviking, retaindb, supermemory. agent/memory_manager.py allows one external provider at a time, and the docstring gives the reason as preventing “tool schema bloat and conflicting memory backends”.
The lifecycle a provider implements is a useful list in its own right, because it enumerates every point where memory can attach to an agent loop: initialize, system_prompt_block, prefetch(query), sync_turn(user, asst), get_tool_schemas, handle_tool_call, shutdown. Then optional hooks including on_session_end, on_delegation, and on_pre_compress.
on_pre_compress is the one I want. It hands memory a chance to extract before the compressor destroys the material. agent/context_compressor.py is 8,692 lines, more than any single memory plugin in the tree, which is where the engineering went in a project that declined to decide what to remember.
The OpenViking plugin in that directory is 5,395 lines. The Hermes row in OpenViking’s benchmark table is measuring a first-party plugin in the Hermes tree.
All three built an audit trail
Every project that built a memory structure also built a way to see how an answer was reached, and the three mechanisms have nothing in common except the goal.
OpenViking preserves the directory-browsing trajectory of each query. Mine returns an ordered trace with one row per node visited, each carrying a why. Headlong’s staircase is itself the audit trail, since the rollups cite the step ids they summarise and the agent reads them in the prompt.
Same diagnosis in three codebases: a store that returns chunks without a reason cannot be debugged when it returns the wrong ones.
What each one refuses
The refusals separate these projects more than the structures do, and they are all written down.
OpenViking refuses a graph. Nothing in the design has cross-cutting edges; every node has exactly one parent, and navigation is ls and tree. That buys deterministic traversal with no extraction pass, and it costs the multi-topic question whose answer lives in the relationship between two branches.
Headlong refuses nearest-neighbour search. Their unified design doc is explicit about which property of an HNSW index they are declining: “Our ‘queries’ are natural language interpreted by an LLM at each level, not vector distances. The hierarchy just bounds how many entries the LLM has to scan at each step.” It also, so far, leaves its two stores unjoined, which is what keeps mem search linear.
ai-coworkers refuses embeddings (ADR-0008 lists them under “Not doing”) and refuses to walk below 0.5 confidence, returning {refused: true, reason} instead. It also refused to delete: the retention prune now moves rows to events_archive, because a ladder whose bottom rung is gone cannot be walked.
Hermes refuses to pick. That is coherent for a project with a large plugin community and a lot of disagreement about memory, and it means the quality of recall depends entirely on which backend is active and how it was set up.
What I am taking
Container abstracts, from OpenViking. My rollups summarise time spans, and the entity notes at state/entities/people/<key>.md have no summary line at all, so nothing can be skipped unopened. One summary line per note would give the reader something to skip on.
Budgets derived from the model’s context window, from Headlong. Mine are fixed caps, which means a larger window buys nothing.
on_pre_compress, from Hermes. src/runtime/compact.ts has no equivalent extraction point, so anything compaction drops is gone unless the weekly ritual happened to catch it first.
The measurement I want does not exist yet. OpenViking published LoCoMo rows for Claude Code, OpenClaw and Hermes, all three of which were running memory with no ladder in it. Headlong and ai-coworkers both ship one. Nobody has run LoCoMo against either.