Feature request: let a hook redact/replace an in-context tool_result (shrink the window without /compact)

Open 💬 1 comment Opened Jun 28, 2026 by yakimoto

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_result content for that tool_use_id with replacement (much smaller), for all future turns — the next turn re-reads the digest, not the original.
  • pointer is 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_result at 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗