[FEATURE] Hook write access to conversation history for in-session context eviction
[FEATURE] Hook write access to conversation history for in-session context eviction
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
Tool outputs are the #1 context consumer in long Claude Code sessions — and once they're in context, they're permanent until a full /compact.
A concrete example from our codebase: reading a 200-line file to edit one line costs ~4000 tokens, permanently. A "quick edit" session with five file reads consumes ~25% of the context window before a single line of code is written. There's no way to say "I'm done with that file — compress it."
The current options:
/compact— all-or-nothing. Summarizes everything. You lose precision on recent context to reclaim old context.- Sub-agent delegation — helps, but adds latency and coordination overhead for what should be simple operations.
- Don't read the file — not realistic.
What's missing: a way to selectively evict or summarize specific tool outputs after they've served their purpose.
Proposed Solution
Extend the PostToolUse hook response format with an optional context_directive field:
{
"context_directive": "summarize",
"summary": "Read posts-data.php: 64 blog entries, post 61 has pending flag",
"retain_turns": 3
}
Three directives:
| Directive | Behavior |
|-----------|----------|
| summarize | Replace the tool output in context with the provided summary string |
| trim | Reduce output to first/last N lines (useful for command outputs where only the tail matters) |
| retain_turns | Keep full output for N more turns, then auto-apply the directive (deferred eviction) |
The hook has full context: tool type, file path, turn number, output size. It can implement any eviction policy — LRU, type-based, age threshold, importance scoring, or project-specific logic. Claude Code provides the mechanism; the hook decides the policy.
Alternative Solutions
Current workarounds all fall short:
/compactis all-or-nothing — it summarizes the entire conversation, trading precision on recent context to reclaim space from old context. There's no surgical option.- Sub-agent delegation offloads work to a fresh context window, but adds latency and coordination overhead for what should be simple read-then-edit operations.
- Lazy-loading (community workaround, see #19105) — architectural pattern to delay tool calls, but doesn't help once outputs are already in context.
- Context virtualization via MCP (see #34391) — third-party server approach that works around the limitation rather than addressing it.
Six related issues show the community has been circling this problem from multiple angles:
- #28984 — Increase effective context window / reduce compaction overhead
- #14245 — Surgical context compaction (
/shrinkcommand) - #24058 — Let Claude trigger context compaction via tool call
- #27298 — Layered memory system for persistent cross-session context
- #19105 — Lazy-Loading Architecture for Token Optimization
- #34391 — Context Mode (third-party MCP server for context virtualization)
All of these work around the inability to modify conversation history from outside the model. Context directives would make them composable — a hook-based eviction policy could implement any of these strategies without requiring model-side changes or new slash commands.
Priority
High - Significant impact on productivity
Feature Category
Configuration and settings
Use Case Example
Step-by-step scenario showing the full lifecycle of context eviction in a real editing session:
- Turn 1: Agent reads
config.php(200 lines) to find the value to edit. Claude Code adds the full file output to context: ~4000 tokens. - Turn 2: Agent edits line 47. The file read has served its purpose — but those 4000 tokens remain in every subsequent API call.
- Turn 3: The next tool call fires. PostToolUse hook runs. Hook logic: "Turn 1 output was a
Read, it's 2 turns old, and the edit is complete — summarize it." - Hook returns:
``json``
{
"context_directive": "summarize",
"summary": "Read config.php (200 lines): DB config, cache settings, module options. Line 47 edited."
}
- Turn 4 onward: The next API call sends ~30 tokens for that message instead of 4000. The full output is preserved in a sidecar log for debugging.
Multiply this by five file reads in a session — typical for any non-trivial task — and the difference between 80% context remaining and 5% context remaining is hook-managed eviction.
The hook author decides the policy. The examples above use age-based eviction, but the same mechanism supports LRU, type-based rules (always summarize Read outputs, never summarize Write confirmations), importance scoring, or any project-specific logic.
Additional Context
Proof of concept — between-session compression
We've already built and open-sourced this pattern for between-session memory (Digital-Process-Tools/claude-remember):
- Haiku summarizes verbose session data into one-line memory entries
- Near-Duplicate Compression merges repeated entries about the same work
- Layered retention: recent data stays detailed, older data gets progressively compressed
- Production result: 81% token reduction in memory files loaded at session start
The architecture works. The gap is applying it within a session — evicting tool outputs that have already served their purpose, not just between sessions.
Implementation notes
PostToolUse hooks already fire after every tool call — no new hook point is needed.
Changes required:
- Add optional
context_directivefield to the PostToolUse hook stdout JSON schema - Claude Code processes directives between turns (after hook fires, before next API call)
- Apply the directive to the current tool call's output before it's included in the next request
Safety constraints:
- Directives only affect tool outputs, never user messages, assistant turns, or system prompts
- Each directive targets the current tool call's output only — no cross-message modification
- Original output preserved in a sidecar log for debugging
- Backward compatible: hooks that don't return
context_directiveare unaffected
---
This proposal comes from a team running Claude Code in production: 3 AI agents (dev partner, QA investigator, code quality sweeper), 146 custom skills, and a codebase with 111K commits. We've already built the between-session half of this system. Happy to share implementation details or collaborate on a prototype if that's useful.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗