Feature request: let a hook redact/replace an in-context tool_result (shrink the window without /compact)
Summary
Allow a hook (PostToolUse, or a new dedicated event) to replace an already-in-context tool_result with a smaller digest + an opaque pointer, so the live context window can be shrunk mid-session without /compact.
Problem
On a long, multi-turn session the per-turn cost is (fixed floor + accumulated history) × cache-read rate. History grows monotonically: every large tool_result that entered context many turns ago is re-read every subsequent turn. A high cache hit-rate helps (you don't re-write it) but you still re-read all of it, every turn.
Today the only way to reclaim already-spent history is /compact (or /clear) — a summarization boundary that loses fidelity and interrupts flow. There's no in-between for users who want long, continuable sessions: either carry the full prefix (expensive) or compact (lossy + disruptive).
Why hooks can't solve this today
The hook model is append-only. A PostToolUse hook can emit additionalContext (adds tokens) and allow/deny/advise — but it cannot rewrite or remove a record already in the transcript/context window. So you can digest a big output alongside the original, but you can't replace the original. The bytes stay and are re-read indefinitely.
(The same wall blocks a hook-level idempotent read cache: a hook can only deny-and-point, which re-injects the same bytes.)
Proposed primitive
A hook may return, for a given tool_use_id, a redaction directive:
{
"redact": {
"tool_use_id": "toolu_…",
"replacement": "‹digest: 1,145-row table → 8 anomalies kept verbatim; full original retrievable via <tool>›",
"pointer": "opaque-id-the-hook-owns"
}
}
Semantics:
- The harness replaces the stored
tool_resultcontent for thattool_use_idwithreplacement(much smaller), for all future turns — the next turn re-reads the digest, not the original. pointeris opaque to the harness; the model can page the original back in on demand via a tool the hook/MCP server owns.- Scoped to the issuing session's own tool_results only.
- Idempotent + reversible: re-fetching restores fidelity. Redaction is a window optimization, not data loss.
Why it's safe / bounded
- Opt-in, hook-gated — nothing redacts unless a hook explicitly asks, scoped to oversized results past a budget.
- Lossless underneath — the original lives in a store the integrator owns (the model can retrieve it).
- No new exposure — the hook already sees the full
tool_resultat PostToolUse; redaction only shrinks what persists.
Impact
This is the missing primitive for flat-cost long sessions: with it, a disciplined session (delegate heavy ops to subagents, crush at write-time, lean fixed floor) can page out old bulk and run at a near-constant floor indefinitely — continuing long multi-turn work without ever compacting or clearing. Integrators already have the digesters and retrievable stores; the only missing piece is the harness-side swap of the in-context copy.
Interim
Lean on what hooks can do: prevent growth by delegating heavy ops to subagents (only small digests return), tighter write-time eviction of oversized outputs, and a leaner always-loaded floor. These slow growth; only the proposed primitive reclaims it.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗