Background compaction with user-anchored split + LLM-searchable conversation history
Proposal (for discussion, not a committed feature)
Two related capabilities that together approximate the "remember everything" experience users keep asking for, without pretending the context window is infinite. The two pieces compose: Feature 1 cleans up the wall; Feature 2 makes the durable on-disk transcript actually useful.
Filed as a single issue so the public can react to the whole vision; happy to split if that's more useful.
Feature 1 — Background compaction with a user-message anchor
Today. /compact and auto-compact at ~83% are synchronous. The user's session freezes for tens of seconds to several minutes (#46431, #43510, #52972, #33088). The summary is the only representation of the prior conversation, so even content from 5 minutes ago gets paraphrased — and is sometimes silently wrong (#19888, #26771, #1534, several closed dupes).
Proposed.
- At a soft threshold (e.g. 75%) start compaction in a background task. The user keeps typing. New turns continue against the still-full conversation — no degraded "bridged" responses.
- The compaction picks an anchor at a user-message boundary. Everything before the anchor → summary. Everything from the anchor forward → carried verbatim.
- When the background summarizer returns, the chat waits for the next "between turns" gap and swaps the model-input (what we send to the LLM):
[startup content reloaded] + [summary] + [anchor user message verbatim] + [everything since the anchor verbatim]. The visible transcript is unchanged — the user sees no jump. - If the soft threshold loses the race against a hard wall (e.g. 95%), fall back to today's synchronous behavior. That's the floor, not the goal.
Anchor selection. Auto by default (most recent user message that leaves ~15-25% of window-worth of turns ahead of it). Optionally user-pickable from past user messages — "compact from here." Anchor is always a real user message, which guarantees the post-swap conversation prefix is API-valid.
What this borrows from current Claude Code:
- Re-injecting startup content (CLAUDE.md, MEMORY.md, system prompt, MCP/skill listings) from disk after compact — not pulling them through the lossy summary.
- The structured-summary categories (intent · files touched · errors · pending · current work).
- Transcript-on-disk persistence (which Feature 2 then leverages).
What it adds: the user keeps typing during the operation, the slice from the anchor forward survives verbatim, and the visible transcript is preserved.
Failure modes worth calling out: background work fails (retry once, fall back); user types so much during compaction that Q itself fills the window (re-anchor at a new point); manual /compact while auto is in flight (manual supersedes); anchor turn edited/deleted (discard summary, recompute next time).
Hooks. PreCompact / PostCompact need a clean story for async — consider a BackgroundCompactionScheduled event on kickoff, plus PostCompact firing at swap time. Related: #44308, #50467, #47618, #46191.
Feature 2 — LLM-searchable conversation history
Today. Transcripts persist on disk in ~/.claude/projects/.../transcript.jsonl, but the model has no way to search them. Users either build external MCP memory servers (rekal, memora, cc-memory; see #48465, #14227) or paste from devlogs (#38235).
Proposed.
- Embed user/assistant message pairs at end-of-conversation (or rolling) into a local vector store under
~/.claude/projects/.... - Expose a
search_prior_conversations(query)tool to the model. Returns scored hits with timestamps and excerpts. - Optionally fan-out: on a broad match, spawn a small LLM call that re-reads the full hit and extracts the precise answer. Keeps the parent context lean.
Composes with Feature 1: the verbatim on-disk transcript that Feature 1 already preserves is the corpus. Anchored summaries can also carry transcript pointers (per #26771's "indexed transcript references" idea) so the model can recover specific blocks without going through search at all.
Why these two together
The complaint we keep hearing is "the chat compresses and kicks me out, and the summary loses stuff I cared about." Most users don't and won't internalize the LLM context-window mental model. Feature 1 means they don't notice the wall. Feature 2 means even when summary necessarily drops detail, the original is reachable on demand. Neither is "infinite memory" but together they are close enough that the complaint goes away.
Related issues
Compaction / wall: #46431, #43510, #33088, #52972, #34806 (closed-stale), #46086, #26771, #19888, #1534, #27293 (closed-stale).
Hooks for compaction: #44308, #50467, #47618, #46191, #43733, #36609.
Conversation search / memory: #14227, #48465, #38545, #38235, #30744 (closed-dup of #30599), #26730 (closed).
Adjacent: #25065 (/branch), #26125 (history viewer).
Open product questions
- Auto-anchor default vs prompt-and-confirm.
- Whether the visible transcript should also collapse, or stay intact while only the model-input is swapped.
- Trigger threshold (75%? 85%?) and
Qtoken budget before re-anchoring. - Whether
/compact(manual) becomes async-by-default or stays synchronous. - Whether summaries should carry transcript pointers from day one (#26771).
Would happily iterate this with anyone working on compaction internals — the design is intentionally underspecified on the hook surface because the public PreCompact/PostCompact contracts have known issues that should probably be addressed first.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗