Skip to content

ADR-024: Memory tiers — a graded ladder over the à-la-carte backend, with a parked RAG rung

  • Status: Accepted
  • Date: 2026-06-26
  • Implements: spike #478 (define the memory-tier model)
  • Relates to: ADR-004 (Obsidian docs integration), ADR-009 (Graphify memory preset / LightRAG removal), ADR-017 (per-surface generator / capabilities), ADR-020 (memory backend is à-la-carte), ADR-022 (toolchain gate map), ADR-023 (wizard explanation standard)
  • Supersedes: the LightRAG-migration parts of ADR-009 (see "LightRAG" below)

Context

ADR-020 made the memory backend à-la-carte (--memory none|obsidian-only|obsidian-graphify, derived through overlay_layers(memory_stack=...)). What it did not give is an explicit "when do I use which layer", a story for corpus-scale semantic recall (RAG — the one gap 2026 research keeps flagging, treating RAG and wiki-memory as complements: "RAG retrieves, wikis compile"), or a deterministic answer to staleness. Spike #478 closes those.

The repo also bundles two things in one overlay that serve different needs: .agents/memory/ (small structured agent facts) and .agents/vault/ (an Obsidian human workspace). They are separable, and separating them yields a cleaner ladder where each rung is a strict superset of the one below.

Decision

1. The memory-recall ladder (five states, each a superset of the last)

Tier memory_stack Adds External install Use it when…
none nothing (the core preset) none You bring your own memory, or want none.
0 auto .agents/memory/ flat facts + SCHEMA.md + lint_memory.sh none (pure files) You want durable agent facts/decisions with zero tooling and no human vault to curate.
1 obsidian-only + .agents/vault/ (sessions/decisions/design/knowledge) optional Obsidian app A human will curate notes/ADRs alongside agent facts.
2 obsidian-graphify + Graphify structural code knowledge graph uv tool install graphifyy → run setup_graphify.sh "How does the code fit together?" recall matters — agents should query the graph before grepping.
3 …-rag + semantic / vector retrieval over a corpus uv tool install 'cocoindex-code[full]' → run setup_rag.sh (keyless, on-device; see §4, ADR-026) Multi-project / multi-repo / monorepo scale, where cross-corpus semantic recall beats per-repo grep. Opt-in only.

Tiers 0–1 are the split of today's obsidian overlay (#497); tier 2 is unchanged from ADR-009; tier 3 is now built on cocoindex-code (§4, ADR-026).

2. Composition rule (resolves the overlap between layers)

  • memory/ is authoritative for facts — durable user/feedback/project/reference notes, human- and agent-curated, indexed by MEMORY.md.
  • Graphify is authoritative for code structure — a derived, regenerated cache; never a source of truth, never hand-edited.
  • RAG (when it lands) is authoritative for nothing — it is a recall surface over the corpus (vault + memory + code), additive only. Higher tiers never relocate the anchors (.agents/memory/MEMORY.md, .agents/docs/adr/, .agents/vault/); they only add surfaces.

3. The documentation axis is separate from the recall axis

"Docs that stay current with the code" is not a memory rung — it is an orthogonal documentation axis (the repo already separates docs via ADR-022's --no-docs). It does not exist today: docstrings are enforced (ruff D) but never surfaced, and there is no drift gate. It is specified and tracked separately as a low-token "what does what" code-map (#496), the deterministic counterpart to tier-3 RAG.

4. RAG (tier 3) — accepted as a seam, now built on cocoindex-code (#495, ADR-026)

RAG is the place to be disciplined: ADR-009 deleted LightRAG precisely because it pinned a fast-moving dep, needed Anthropic+OpenAI keys, and put every upstream change on us. Any tier-3 overlay must therefore meet hard constraints. It was first shipped as a seam (#505), then the engine was wired (ADR-026); the constraints that gated it:

  • Positioning (owner): tier-3 RAG is not worth it for small/medium single projects — vault + the code graph + grep cover recall there. Its payoff is multi-project / multi-repo / monorepo scale. Wizard guidance must say so.
  • Hard constraints (non-negotiable, from ADR-009's lesson): upstream-maintained tool/plugin/MCP (never hand-rolled ingestion here); no API key on the default path (Graphify's AST mode is the bar); tool-level install only; scaffolder renders docs + a user-run setup_*.sh + rules only; index is a gitignored derived cache.
  • Candidate tools and the open A-vs-B question (distinct rung vs. one tool that replaces Graphify and toggles graph-only/graph+vector — the latter would supersede ADR-009) are recorded in #495, to be decided with a hands-on test before any build.

Update (2026-06-26, #495 un-parked): the engine decision is made in ADR-026 — the engine is cocoindex-code (keyless, on-device sqlite-vec; no container, no API key), wired as option A (a distinct vector surface alongside Graphify, not replacing it). The seam from #505 becomes a real setup_rag.sh installer; tier 3 is now built, still opt-in.

5. External memory frameworks (Mem0 / Zep / Letta / Cognee) — rejected as bundled overlays

All are hosted services or heavy pipelines/stores; they violate the repo's "stay small / no long-running service / deterministic file-ops only" rule. The scaffolder will not ship them. Users may wire them by hand; project-init will not template them.

6. Staleness — deterministic lint only

Extend lint_memory.sh (tracked in #497) with deterministic checks: a git-age "review-by" warning, and a dangling-reference check (a fact naming a backtick path/file that no longer exists — the most common, mechanically-detectable form of staleness). Semantic contradiction detection needs an LLM and therefore stays out of the linter (no LLM in tooling) — it belongs to a consolidate-memory-style agent pass, not the deterministic gate.

LightRAG

ADR-009 already removed the LightRAG overlay/preset/flags. This ADR records the further decision to drop migration support for old obsidian-lightrag-recorded projects when that upgrade.py branch is next touched — ADR-009 confirmed the project has no users, so the compatibility argument is void. ADR-009 stays in the log as history; this ADR supersedes only its migration affordance.

Consequences

  • The wizard gains a clearer, graded story with explicit per-rung install cost (ADR-023; #497).
  • Tier 0 (auto) makes a memory-without-vault project possible, below obsidian-only.
  • No new dependency lands now: tier 3 is a documented seam, not code. The repo does not repeat the LightRAG maintenance trap while it still has no users.
  • Follow-up work is tracked, not bundled: #496 (documentation axis / code-map), #497 (memory/vault split + wizard install-cost + staleness lint), #498 (Agentic-OS memory descriptor, gated on spike #479), #495 (tier-3 RAG — parked).