[FEATURE] Session-scoped working memory tool (MemoryWrite/MemoryRead) — compact-proof constraint anchoring

Resolved 💬 6 comments Opened Apr 4, 2026 by woolkingx Closed Apr 19, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

During long sessions, the model progressively loses track of user-stated constraints, premises, and architectural decisions after compaction. This is the single most common frustration in long Claude Code sessions — users must repeatedly re-state the same things.

The root cause is simple: the model has no compact-proof read/write storage.

Everything the user says exists only as natural language in conversation context. Compaction is lossy. Key constraints get summarized away. The model drifts from user intent.

Current mechanisms all fail to solve this:

| Mechanism | Why it fails |
|-----------|-------------|
| CLAUDE.md | Static, pre-session. Cannot capture session-specific decisions |
| MEMORY.md | Cross-session index. Model must "remember" to check it — and often doesn't |
| Tasks | Tracks progress ("what to do"), not knowledge state ("what is true") |
| Conversation context | Lost on compact. No way to mark importance |
| Hooks (workaround) | Fragile state-machine hacks in UserPromptSubmit to detect compaction and re-inject. Works but shouldn't be necessary |

613 issues match "memory context compact" in this repo. Many are different facets of this one problem.

Proposed Solution

A new native tool pair: MemoryWrite / MemoryRead — session-scoped working memory that survives compaction.

MemoryWrite({ key: "auth-approach", value: "JWT only, no session cookies", type: "constraint" })
MemoryWrite({ key: "target-arch", value: "monorepo, not microservices", type: "premise" })
MemoryWrite({ key: "phase1-scope", value: "backend only, don't touch frontend", type: "scope" })
MemoryWrite({ key: "parser-finding", value: "bug is in parser, not lexer", type: "finding" })

Entry types

| Type | Purpose | Example |
|------|---------|---------|
| constraint | User-stated hard rules | "no ORMs, raw SQL only" |
| premise | Architectural decisions already made | "monorepo, not microservices" |
| scope | What's in/out for current task | "only backend, don't touch frontend" |
| finding | Intermediate conclusions during work | "bug is in parser, not lexer" |
| context | Background facts affecting decisions | "deploying to edge, no Node.js" |

Behavior

  • Native tool — model can read/write at any time during reasoning (like Tasks)
  • Compact-proof — entries are excluded from summarization and re-injected verbatim after compaction
  • Key-value with upsert — update existing key, no duplicates
  • Session-scoped by default — optional persist: true flag to promote to cross-session storage
  • Hook integration — allow user hooks to react to memory writes (e.g., persist to external DB, trigger validation)

The key innovation: inject after compact, not into compact

Before compact: 200 messages + 12 memory entries
Compact runs:   200 messages → summary (lossy)
After compact:  summary + 12 memory entries (intact, verbatim)

Memory entries bypass the summarization pipeline entirely. This is fundamentally different from hoping the summary model preserves important information.

Example session flow

User: "We're building a CLI in Rust, must work on Windows, no async runtime"
Model: MemoryWrite({ key: "lang", value: "Rust", type: "premise" })
       MemoryWrite({ key: "platform", value: "Windows required", type: "constraint" })
       MemoryWrite({ key: "no-async", value: "no tokio/async-std", type: "constraint" })

... 50 messages later, compact happens ...

Post-compact context: [summary] + [3 memory entries verbatim]
→ Model still knows: Rust, Windows, no async — without user re-stating

Why one tool solves what 600+ issues couldn't

The root problem is: compact loses things the model needs to remember.

Every proposed workaround attacks a different symptom:

  • Static rulebook files (#41279) — protects pre-defined rules, but can't capture session-specific decisions
  • PostCompact hook injection (#41224, #14258) — one injection point, no structured storage
  • Two-tier context architecture (#29760) — lets the model decide what's important (unreliable)
  • INVARIANT.md (#34716) — elevates trust level, changes security boundary
  • Context deduplication (#40646, #41810) — reduces waste, doesn't prevent loss

A single read/write tool with compact-proof storage unifies all of these. The model writes what matters. Compaction can't touch it. Done.

Alternative Solutions

  1. Improve compaction quality — delays the problem, doesn't solve it. Lossy compression is lossy by definition.
  2. Larger context windows — same. Compaction still happens eventually.
  3. Hook-based workarounds — I've built this. It works (hooks + external DB + state machine for dedup). But it requires significant setup, is fragile, and shouldn't be necessary when the solution is this simple.
  4. Static protected files (Rulebook/INVARIANT.md) — solves one slice (pre-defined rules) but misses session-specific decisions, findings, and scope.

Priority

High - Addresses the most common failure mode in long sessions

Feature Category

Core functionality / Context management

Additional Context

I've implemented a working prototype of this concept using hooks + ArangoDB + a state machine for deduplication. The results validate the approach:

  • Constraint anchoring: user-stated rules persist through unlimited compactions
  • Progressive context loading: related knowledge injected incrementally (5 entries per turn, deduped by state machine), so context builds naturally as the conversation deepens
  • Model stays on track: no more repeated corrections after compact

The prototype proves the concept works. Native tool support would eliminate the external infrastructure requirement and make this accessible to all users.

Related issues (same root problem, partial solutions)

  • #41279 — Compaction-protected Rulebook (static rules only)
  • #41224 / #14258 — PostCompact hook context injection
  • #42542 — Silent context degradation (14 comments, problem report)
  • #41217 — Opus 4.6 fails to follow behavioral constraints across sessions
  • #40930 — Claude ignores CLAUDE.md instructions
  • #42121 — Model ignores governance rules within same session
  • #29760 — Two-Tier Context Architecture
  • #34716 — INVARIANT.md
  • #40646 / #41810 — Context window deduplication

View original on GitHub ↗

This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗