Feature Request: Layered memory system for persistent cross-session context

Resolved 💬 24 comments Opened Feb 21, 2026 by unclesvf Closed May 14, 2026

The Problem

Every Claude Code session starts amnesiac. You get MEMORY.md (capped at 200 lines) and CLAUDE.md, and that's it. For anyone doing real work across multiple projects over weeks or months, this means:

  • Re-explaining your setup, preferences, and project state every session
  • Losing all context when sessions end — power outage, crash, or just context window exhaustion
  • Bloated always-loaded context — as you add more projects, MEMORY.md hits the 200-line cap and CLAUDE.md grows unbounded, wasting tokens on irrelevant context every session
  • No way to ask "what was I working on?" — Claude has to start from scratch reading the codebase

A real-world example: a power outage lasting 2 minutes killed 6 active Claude Code sessions mid-work across multiple projects. All context — gone. Not just for Claude, but for the user too, who was depending on reviewing conversation history across browser tabs and terminals.

The Solution: Layered Memory

Instead of loading everything or nothing, load context relevant to what the user is actually asking about:

Layer 1 — Slim Index (always loaded, ~60 lines)
A keyword index of all projects/topics with pointers to detail files. User preferences, voice transcription aliases, critical pitfalls that prevent repeat mistakes. Replaces the current monolithic MEMORY.md.

Layer 2 — Topic Files (loaded on demand)
Full project details in separate markdown files. A lightweight keyword search (hook on UserPromptSubmit) matches the user's message against the index and identifies which 1-3 topic files are relevant. Claude reads only those files.

Layer 3 — Semantic Search (optional)
Topic files indexed in a vector store for semantic retrieval when keyword matching isn't enough. Catches queries where the user's phrasing doesn't match exact keywords.

Proof of Concept — Built and Working

I built this as a user-space solution and the results are significant:

| Metric | Before | After |
|--------|--------|-------|
| CLAUDE.md | 700 lines (~6,241 tokens) | 83 lines (~724 tokens) |
| MEMORY.md | 188 lines (~3,259 tokens) | 86 lines (~1,036 tokens) |
| Always-loaded tokens | ~9,500 | ~1,760 |
| Reduction | — | 81% |
| Topic files | 0 (everything inline) | 18 (loaded on demand) |
| Context relevance | Everything or nothing | Top 1-3 matches per query |

How it works:

  1. MEMORY.md is a slim keyword index — each project is one line with name, status, keywords, and a file pointer
  2. A UserPromptSubmit hook (memory_search.py) greps the index against the user's message and writes matching topic file paths to a temp file
  3. Claude reads the temp file and loads only the relevant topic files
  4. Optionally, topic files are chunked and ingested into ChromaDB for semantic search

The implementation is ~100 lines of Python for the hook, zero external dependencies beyond what Claude Code already has.

Reference implementation: github.com/unclesvf/claude-memory (demonstrates the index format, hook script, and topic file structure)

Why This Should Be Built-In

The pieces already exist in Claude Code's architecture:

  • The memory directory exists
  • Hooks exist
  • The 200-line MEMORY.md cap exists (proving the team knows bloat is a problem)

What's missing is the middle layer — "I know about 18 projects but I'll only load the 2 you're talking about right now." This could ship as a built-in option without requiring any external dependencies:

  • Auto-split MEMORY.md into topic files when it approaches the cap
  • Built-in keyword/fuzzy matching on the index (no hook script needed)
  • Optional semantic search for users who want it
  • A simple "what was I working on?" command that reads the index and summarizes active projects

This would transform Claude Code from a tool that forgets everything between sessions to one that builds institutional knowledge over time — exactly what's needed for real, sustained software engineering work.

View original on GitHub ↗

24 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/14227
  2. https://github.com/anthropics/claude-code/issues/18417
  3. https://github.com/anthropics/claude-code/issues/12990

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

unclesvf · 4 months ago

This is not a duplicate of the linked issues. Those requests are about:

  • #14227 — Basic persistent memory between sessions (which already exists via MEMORY.md)
  • #18417 — Session state and conversation continuity across restarts
  • #12990 — Saving/restoring conversation history on restart

My request is fundamentally different: on-demand, relevance-scored memory loading to reduce token waste.

The problem isn't that memory doesn't persist — it does. The problem is that MEMORY.md loads everything into context every session regardless of relevance. With 15+ projects documented, that's ~9,500 tokens of mostly irrelevant context burned before the user types anything.

What I'm proposing (and have built a working implementation of) is:

  1. A slim keyword index as the always-loaded MEMORY.md (~1,760 tokens)
  2. A UserPromptSubmit hook that scores memory entries against the user's message and loads only matching topic files on demand
  3. Optional ChromaDB vector search for semantic matching

This is an architecture-level enhancement to how memory is loaded, not a request for memory to exist. The working implementation is at github.com/unclesvf/claude-memory — 81% token reduction with improved relevance.

👎

hifriendbot · 4 months ago

This is almost exactly the architecture I built and have been using in production for several weeks.

The layered approach you're describing maps closely to what I implemented:

  • Layer 1: Ai Extraction — identifies what's worth remembering from conversations (architecture decisions, bug fixes, preferences, patterns). Each memory gets typed (architecture/preference/bug/decision/pattern/dependency), categorized, and scored 1-10 for importance.
  • Layer 2: Semantic Storage — 1536-dimensional embeddings for meaning-based retrieval. Cosine similarity with deduplication at ~0.92 threshold and conflict detection (newer memory wins when content contradicts, old one archived).
  • Layer 3: Time-Aware Ranking — blends semantic relevance + importance weight + recency decay. A 3-day-old importance-5 memory outranks a 6-month-old importance-5 memory, but not a 6-month-old importance-9 core architecture decision.

On the scoping question from your issue — project memories are tied to git remote as a stable identifier (clone on a different machine = same project). Global memories (coding style, tool preferences, identity) follow you across all projects.

I wrote a technical deep-dive on the architecture: https://hifriendbot.com/building-cloud-memory-system-ai-coding/

The implementation is an MCP server: CogmemAinpx cogmemai-mcp setup

Grivn · 4 months ago

Your layered architecture proposal maps closely to what I've been running in production with mnemon — a standalone skill binary for persistent agent memory.

The approach: entities stored in a local SQLite graph (temporal, entity, semantic, causal edges), retrieved on-demand via intent-aware beam search + RRF reranking. Only relevant memories are injected per query — zero context cost for irrelevant knowledge. No 200-line MEMORY.md cap, no always-loaded bloat.

Architecture difference from the other solutions shared here: mnemon is LLM-supervised — the host LLM (Opus/Sonnet) decides what to store and retrieve, while the binary handles deterministic computation. No embedded inference, no API keys, single Go binary.

Hooks handle the lifecycle: SessionStart → inject context, UserPromptSubmit → recall, PreCompact → save before compression.

brew install mnemon-dev/tap/mnemon && mnemon setup

Portable: the same binary + skill works across Claude Code, OpenClaw, and any LLM CLI that reads markdown skills.

unclesvf · 4 months ago

@hifriendbot This is great validation — love that you arrived at essentially the same layered architecture independently. A few things from your approach I want to borrow:

Importance scoring is something we're missing. Our keyword scorer treats all memories equally, but a core architecture decision should absolutely outrank a minor preference at the same relevance level. The 1-10 scale with recency decay is elegant.

Conflict detection at 0.92 cosine similarity is clever — we've had cases where updated project notes coexist with stale ones and Claude gets confused about which is current. Archiving the old one automatically would fix that.

Git remote as project identifier is smarter than our current directory-path approach. Same project cloned to a different machine should pull the same memories.

Checking out CogmemAi now. The MCP server approach makes it pluggable, which is the right call for distribution.

The blog post link is helpful too — always good to see the design reasoning behind the implementation, not just the code.

unclesvf · 4 months ago

@Grivn The PreCompact hook is the standout idea here — we don't have that, and it solves a real problem. Right now when Claude auto-compresses context mid-session, useful working knowledge gets lost silently. Saving before compression means the next session can recover what the current one was about to forget. That's a big deal for the power outage / crash recovery scenario that motivated this whole thing.

RRF reranking across multiple signals is exactly the direction we want to go. Our current implementation does flat keyword scoring, but combining semantic similarity + importance + recency + entity relationships (like you're doing with the SQLite graph edges) would be significantly more accurate.

LLM-supervised storage is an interesting tradeoff — letting Claude decide what's worth remembering means the extraction is higher quality, but it adds latency and cost per interaction. For our use case (15+ projects, ~100 topic files) the deterministic keyword approach is fast enough, but I can see the LLM-supervised approach winning for smaller, higher-stakes memory sets.

The fact that mnemon works across Claude Code AND OpenClaw is a great portability story. Single Go binary with no API keys is the right distribution model.

Going to look at how you're using SessionStart for context injection — that's a hook we haven't explored yet.

unclesvf · 4 months ago

Update: Three new features shipped

Thanks to the great ideas from @hifriendbot and @Grivn — we built all three and pushed them to the repo:

1. PreCompact hook (hooks/precompact_save.py)

Inspired by @Grivn's mnemon approach. Fires before context compression and saves a session snapshot to ~/.claude/sessions/last_session.md:

  • Last 5 user messages (what was being worked on)
  • Files touched (Edit/Write/Read targets)
  • Recent tool actions (last 10 Bash/Glob/Grep calls)
  • Appends to a compaction log (compaction_log.jsonl) for history

2. SessionStart hook (hooks/session_start.py)

Pairs with PreCompact. When a new session starts or resumes after compaction, automatically injects the recovery snapshot into Claude's context. No more "what was I working on?" — Claude already knows.

  • Only fires on startup and compact sources
  • Stays silent on /clear (user wants fresh start) and resume (context already there)
  • Ignores recovery files older than 1 hour

3. Importance scoring + recency decay in search hook

Inspired by @hifriendbot's CogmemAi importance scoring. The keyword search now uses three signals:

  • Keyword match (0-15+) — exact=3, partial=2, name=2 (unchanged)
  • Importance weight (1-10) — multiplier per entry in MEMORY.md. Default 5 = neutral, 10 = 2x weight
  • Recency boost — files accessed in last hour get +3, last 4hrs +2, last 24hrs +1

Formula: final_score = keyword_score × (importance / 5) + recency_boost

Access times tracked automatically in memory_access_log.json.

MEMORY.md format update

Now supports an optional importance field:

**Project** | Status | 8 | keyword1 keyword2 | [file.md](file.md)

All three hooks are tested and documented in the README. The crash recovery loop (PreCompact saves → SessionStart loads) is the biggest win — power outages and context compression no longer mean starting from scratch.

singularityjason · 4 months ago

This thread describes the exact architecture we've been running in production with OMEGA. A few responses to the specific design points being discussed:

On importance scoring + recency decay (@hifriendbot's approach): OMEGA's retrieval uses a multi-signal ranking pipeline: cosine similarity, keyword overlap, recency decay, type-based boosting (errors weigh more during debugging, decisions weigh more during planning), and cross-encoder reranking for the final top-k. The context parameter lets the agent specify intent (error_debug, planning, review, file_edit) which shifts the scoring weights. This matters more than a flat importance score because the same memory can be critical in one context and irrelevant in another.

On conflict detection (@hifriendbot's 0.92 cosine threshold): We went further with contradiction detection. OMEGA's consolidation phase identifies near-duplicate memories and merges them, but also flags contradictions (e.g., "use PostgreSQL" vs "we switched to SQLite") and surfaces the newer one while archiving the old. This runs automatically during omega_maintain.

On the always-loaded token bloat problem (@unclesvf's core issue): OMEGA loads a slim session briefing via omega_welcome (recent decisions, active reminders, user profile) instead of dumping everything. Then omega_query retrieves on-demand per question. The briefing is typically ~500-800 tokens. Full context only loads when relevant.

On PreCompact hooks (@Grivn): OMEGA uses Claude Code hooks for PreCompact (saves checkpoint), SessionStart (loads briefing + resumes state), and UserPromptSubmit (injects relevant memories per message). The PreCompact -> SessionStart loop handles crash recovery and context compression automatically.

On the benchmark question that nobody's addressed in this thread: how do you know your memory system actually works at scale? We scored 95.4% on LongMemEval (500 questions, ICLR 2025), #1 on the leaderboard. We also built MemoryStress, a 1,000-session longitudinal benchmark, because LongMemEval only tests short-term recall. The hard problem is what happens after 6 months of accumulated memories.

Two commands: pip install omega-memory && omega setup

Full architecture docs: https://omegamax.co/docs

junaidtitan · 4 months ago

Losing context across sessions is painful — we built cozempic to help with the in-session side of this. It checkpoints agent team state (teammates, tasks, roles) to disk continuously, so even if compaction wipes the lead agent's memory, the state is recoverable.

For Agent Teams specifically, the guard daemon writes a \team-checkpoint.md\ every 30s and after every Task/TaskCreate/TaskUpdate. On compaction or reload, it injects the team state back as conversation history so Claude resumes with full awareness.

Doesn't solve cross-session memory (that needs Anthropic to build it), but it prevents the mid-session amnesia that kills long-running agent work. Open source, feedback welcome.

louis49 · 4 months ago

Different approach here with https://github.com/louis49/melchizedek: instead of curating what to remember, it indexes every conversation automatically and relies on search quality to surface the right context.

Re the "middle layer" problem: melchizedek's progressive retrieval works in 3 layers - m9k_search returns ~50 tokens/result (snippets), m9k_context ~300 (surrounding chunks), m9k_full ~1000 (complete content). Claude starts cheap and drills down only when needed.

Hook integration matches what's discussed here:

  • SessionStart → injects recent context from past sessions (similar to omega_welcome/mnemon recall)
  • PreCompact → indexes before /compact so nothing is lost to context compression
  • SessionEnd → captures the full session

Search pipeline: BM25 (FTS5) + dual vectors (text 384d + code 768d) + RRF fusion + cross-encoder reranker, with 4-level graceful degradation down to BM25-only.

The tradeoff vs notebook approaches (OMEGA, CogmemAi, mnemon): no importance scoring or contradiction detection, but nothing is ever lost — backfills your entire ~/.claude/projects/history on first install.

npm install -g melchizedek - zero config, 100% offline, single SQLite file.

hatawong · 4 months ago

Great thread — lots of sophisticated retrieval architectures here. I want to add a different angle: the quality of what you store matters as much as how cleverly you retrieve it.

Most tools discussed here treat a session as the storage unit. But a single session often covers 5+ topics — auth setup, CSS debugging, API refactoring, test fixes. When that becomes one memory blob, even perfect retrieval can't separate "what we decided about auth" from "how we fixed that CSS bug."

I built claude-recap around topic-level granularity. The Stop hook detects topic changes mid-session and archives each topic as a separate Markdown file with a summary:

~/.memory/projects/{project}/{session-id}/
  01-setup-auth.md        # "Chose JWT, set up middleware..."
  02-fix-login-bug.md     # "Root cause: stale token cache..."

The key design insight (which I think applies to all tools in this thread): the agent currently in-context writes far better summaries than any post-hoc extraction. The Stop hook captures the summary while Claude still has full context. Cold-reading from JSONL transcripts is only a fallback for compacted sessions. This is why systems that compress transcripts after the fact tend to produce hallucinated memories — the summarizer wasn't there when it happened.

Trade-off vs. the vector/graph approaches here: no semantic search, no importance scoring. Just grep over well-named files. For individual developers this scales surprisingly well. For teams or 100+ topic files, the retrieval sophistication in CogmemAi/mnemon/OMEGA would win.

I wrote up a comparison of 5 approaches (including the built-in solutions): https://dev.to/hw20200214/claude-code-forgets-everything-between-sessions-i-tested-5-fixes-199p

lgrant1234 · 4 months ago

Adding GrantAi Brain to this thread.

Years of context. Instant recall. From 2 minutes ago to 5 years ago — if it's stored, it can be recalled. Deterministic memory, not fuzzy recall.

Automatic context injection at session start — no manual prompting needed.

12ms retrieval, encrypted locally, works across Claude Code, Cursor, Windsurf, any MCP client.

solonai.com/grantai

gilbert-barajas · 4 months ago

I built a layered memory system that addresses this — it's part of a coordination platform called Mycelium.

The memory architecture has multiple layers:

  1. Context keys (namespaced key-value store) — agents read/write persistent data scoped by namespace (e.g., agent-name/session-state, project/conventions). Supports TTL, expiration, and durable vs. ephemeral categories.
  2. Savepoints — automatic state snapshots at session end. Captures what the agent was working on, session state, and recovery instructions. Next session boots from the savepoint.
  3. Calibration profiles — layered configuration (platform → customer → agent) that defines expected behavior. Agents report their CLAUDE.md state on boot, server checks it against profiles for drift detection.
  4. Boot context — one API call returns the full picture: pending tasks, unread messages, plan steps, bugs, concepts, and the agent's last savepoint.

The key insight is that different types of memory need different persistence strategies:

  • Session state → ephemeral (auto-cleaned on boot)
  • Project conventions → durable (persists indefinitely)
  • Agent identity → calibration profiles (layered, inherited)
  • Work state → savepoints (snapshots with recovery instructions)

Available as an MCP server with 61 tools — agents get the full memory layer natively through Claude Code's MCP interface.

Open source MCP server: https://github.com/SoftBacon-Software/mycelium-mcp

ThinkOffApp · 4 months ago

Your three-layer model is close to what we shipped with User Intent Kit: a two-layer system with a static profile layer (who the user is, preferences, long-lived context) and a live intent layer (what the user wants right now, per-device slots, LWW merge). The intent layer syncs across devices so every agent in the team knows the current goal. We found the key is separating "who" from "what right now": the profile rarely changes but the intent updates constantly. Built on top of GroupMind rooms at groupmind.one.

AbdoKnbGit · 4 months ago

This already exists as an open source community implementation.

I built cc-memory — a local proxy that solves exactly what you're describing:

  • Semantic search over project memory (ChromaDB + all-MiniLM-L6-v2,

same embedding model you proposed)

  • Auto-saves knowledge across sessions with dedup and contradiction detection
  • 12 MCP tools including memory_remember, memory_search, memory_save
  • Works with Claude Code today, no Anthropic platform changes needed
  • Runs fully local via Docker, free, open source

The architecture matches your proposal almost exactly:

  • ChromaDB for semantic search ✓
  • MCP server for Claude Code integration ✓
  • Auto-detection and save suggestions ✓
  • Cross-session persistence ✓

Repo: https://github.com/AbdoKnbGit/claude-code-memory

Happy to answer questions or discuss the implementation.
This might give the Anthropic team a reference implementation
to work from if they decide to build this natively.

WhymustIhaveaname · 4 months ago

I built a plugin that partially addresses this: claude-memory-manager

It adds a global memory layer at ~/.claude/memory/ (cross-project, injected at session start via SessionStart hook) and a web UI for browsing/editing/moving memories across all containers. You can drag memories between projects, export as zip, etc.

It doesn't solve the full layered system proposed here, but the global tier + visual management are usable today as a Claude Code plugin.

yosukes · 3 months ago

Real-world implementation: 3-layer classification with single-log + promotion

I've been running a similar layered memory system in production for enterprise Java development with 5+ concurrent Claude Code sessions (task management, multiple project workspaces, Slack monitoring). Sharing results that validate and extend the ideas in this issue.

The framework

Instead of the 3-tier index/topic/semantic approach above, I arrived at a 3-layer classification through iterative design:

  • Prerequisites (who & what) — user model, project-specific knowledge
  • Methods (how) — problem-solving patterns, procedures. Global only — methods don't change by project
  • Records (what happened & learned) — single append-only log file

Key design decisions:

  1. CLAUDE.md as router — reduced from 11KB to ~4.5KB by keeping only navigation (triggers → file links). Leaf procedures stay in separate files, loaded only when triggered
  2. Single log + promotion — all session records append to one log.md with tagged entries (【policy】【task】【insight】【reflection】【next】). Repeated patterns promote to stable files. This is the only organizing action
  3. Trigger-based loading — a trigger table in CLAUDE.md maps work types to files (e.g., "MySQL execution → read MySQL procedure"). Files are read only when relevant work begins, not at startup
  4. Entries as prompts — each log entry is self-contained: what happened → what to do → example. Future sessions can act on entries without additional context
  5. Timestamped backupsfilename.YYYY-MM-DD_HHMM.bak before structural changes. Agent simulation + live session verification after

Results

| Metric | Before | After | Delta |
|--------|--------|-------|-------|
| Startup context (lines) | 187 | 145 | -22% |
| Startup context (size) | 11.4KB | 7.7KB | -32% |
| Log write triggers | 0 | 5 types | New |
| Method file routing | 0 | 8 triggers | New |
| Session exit procedure | None | Backup + quality check | New |

New sessions achieve full role understanding and start working immediately without user guidance. Cross-project knowledge transfer works — patterns established in one session propagate to others.

Pain point: ~/.claude/projects/ CLAUDE.md discovery

When testing a v2 trial environment in a new subdirectory, Claude searched the project root instead of ~/.claude/projects/{encoded-path}/ and couldn't find the project CLAUDE.md. This blocked the trial and forced us back to the original directory. Related: #34941

What I'd love to see built-in

Agreeing with the OP — the building blocks exist. The missing pieces from my experience:

  1. Append-only session log — a native log.md that Claude writes to automatically with tagged entries, surviving across sessions
  2. Trigger-based file loading — declare "when doing X, read file Y" in CLAUDE.md and have the runtime handle it, instead of relying on Claude to self-enforce
  3. Reliable project config discovery~/.claude/projects/ CLAUDE.md should be found regardless of how Claude searches for it

Full anonymized framework (before/after files + design doc) available if useful for the team.

bsharvey · 3 months ago

We built a layered memory system for cross-session context:

npx archetypal-ai

Three layers:

  • recall() — session start, restore full context from previous sessions
  • remember(content) — mid-session, persist typed memories (episodic/semantic/procedural/emotional) with importance scoring
  • checkpoint() — session end, full state snapshot (auto via SessionEnd hook)

Backed by Cloudflare Durable Objects + Supabase with pgvector for semantic search. Free. No account.

We've been running this across 100+ sessions in our own system. Agents with accumulated memory produce measurably different output.

https://github.com/archetypal-ai/archetypal-ai

j-p-c · 3 months ago

Different approach here with alzheimer: instead of bypassing MEMORY.md with per-prompt search, it keeps the native index working by restructuring it into a self-balancing tree before it overflows.

When MEMORY.md exceeds 150 lines, entries are grouped by type into sub-indices in _index/. If a category overflows, it splits further by topic keyword. The tree grows in depth, not width. Claude's built-in memory loading continues unchanged — no per-prompt hook overhead, no database, no embeddings.

Trade-off vs. the retrieval-based approaches in this thread: no semantic search or importance scoring, but also zero dependencies (Python 3.6+ stdlib), zero per-query cost, and it works within the existing architecture rather than replacing it. Auto-recovers if Dream flattens the tree.

Hooks: PostToolUse, SessionStart, PreCompact. MIT-0 license. See #40614 for the feature request.

AliceLJY · 3 months ago

Built an MCP server that implements this: RecallNest

A cross-session memory and continuity system for Claude Code, designed around the exact problems discussed here.

What it does:

  • Session continuityresume_context picks up exactly where the last session left off (decisions, open loops, next actions)
  • Layered memory — short-term (session), mid-term (pinned), long-term (distilled) with automatic promotion
  • Semantic searchsearch_memory with keyword matching across all memory layers
  • Session checkpointscheckpoint_session captures full session state before closing
  • Workflow patternsstore_workflow_pattern saves reusable multi-step procedures
  • Memory drill-down — explore connected memories by entity or topic

Used daily across 1000+ sessions. Claude Code hooks auto-trigger checkpoint on session end and resume on session start.

Repo: https://github.com/AliceLJY/recallnest

yosukes · 3 months ago

Update: New discovery — reading order is the single most impactful factor

Since my previous comment on the 3-layer classification framework, I've made a significant new discovery through continued production use across 5+ concurrent projects.

The single most impactful technique turned out to be specifying an explicit numbered reading order in MEMORY.md. Not what rules you write — but explicitly telling the model when to read them.

I ran a natural experiment: three projects with identical CLAUDE.md, model, and version. Two had numbered startup reading orders, one didn't. The two with reading orders showed consistent autonomous behavior. The one without required constant user intervention — and produced hallucinated PR descriptions. After adding a numbered reading order to the underperforming project, the very next session autonomously loaded rules, identified the correct resume point, and completed work without any user prompting.

I also systematically tracked version-specific anomalies and correlated them with release notes. The v2.1.88 fix for CLAUDE.md duplicate injection confirmed the causal chain behind quality degradation I'd been observing since v2.1.87.

I've written up the full case study — 10 techniques, evidence, and 5 feature requests — as a standalone issue:

👉 #41473Case Study: Governing Stateless Sessions with a Structured Memory Framework — Reading Order Is the Single Most Impactful Factor

The framework continues to work effectively in daily production use. Hope this is useful for both the team and the community.

t49qnsx7qt-kpanks · 3 months ago

The token reduction numbers here are genuinely impressive — 81% fewer always-loaded tokens is not a rounding error, that's a structural change in how the context window gets used.

The Layer 3 ChromaDB integration is the part I find most interesting. A few things I ran into building something similar:

The L3 failure mode at scale

Semantic search over the full corpus works great until you have 6+ months of entries. Then you start getting recall results that are topically relevant but temporally stale — Claude surfaces a decision from 4 months ago that's been superseded, doesn't know it's superseded, and acts on it. The fix I landed on is importance scoring with time decay: each memory gets a composite score (base importance × recency multiplier) that decays logarithmically. Stale memories don't get deleted, they just rank lower in recall until they drop below a pruning threshold and get consolidated.

The hook-based approach vs. ChromaDB

Your memory_search.py hook approach (grep index, load matching topic files) is the right architecture for L2. For L3 semantic search, I went with a different path — an MCP server that handles retrieval so Claude is calling recall(query) directly rather than loading files into context. The difference is: with file loading, the retrieved content consumes context tokens permanently for the session. With MCP recall, Claude can query multiple times and only keep what it actually needs.

On the 200-line MEMORY.md cap

The cap is actually the right constraint forcing the right behavior — if it's painful, it means you're putting the wrong things in L1. The heuristic I use: L1 should contain pointers and nothing else. If the content itself is in L1, it belongs in L2.

If the hook-based approach is useful to look at, I open-sourced what I built at github.com/mnemopay/mnemopay-sdk. The npx @mnemopay/sdk setup command wires the Stop + UserPromptSubmit hooks automatically. The memory architecture is the part most directly relevant to what you're describing — the payment layer is a separate thing for multi-agent use cases.

The reference implementation you linked (claude-memory) is a solid starting point. Your layered approach is where this ends up heading anyway; would be great to see it native.

github-actions[bot] · 2 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

github-actions[bot] · 12 days ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.