Harness re-injects identical context blocks (task-list snapshots ×15, 18k tool-schema delta ×2, skill bodies ×5) with no change detection

Status Closed — not planned
Maintainer reply ✓ Yes — bcherny
Activity 4 comments · opened Jul 1, 2026 · closed Sep 15, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Summary

Analyzing token flow across four real sessions (~1.2M injected tokens measured from transcript JSONL), several harness-injected context blocks are re-sent verbatim, with no change detection, inside single sessions. Each injection is appended to the conversation, so identical re-injections permanently grow the input carried by every subsequent request in the session — pure cost with no information gain.

Observed duplicate classes (one session each unless noted)

  1. Task-list reminder snapshots — the periodic "task tools haven't been used recently" reminder embeds all task subjects+descriptions verbatim every time. Observed: the same snapshot ×15, ×6, ×6, ×6, ×4 within one session; 178 snapshots across 4 sessions ≈ 559k tokens (46% of all dynamically injected content). A hash/change check — or injecting only changed tasks — would eliminate most of it.
  1. Deferred-tool schema deltas (ToolSearch) — an 18.1k-token schema delta was injected twice, byte-identical, in one session. Already-delivered schemas could be tracked per session.
  1. Invoked-skill content — the same skill body re-injected ×5 in one session (≈20k tokens) when the skill was re-invoked; a "already in context" check would cover it.
  1. Skill-availability lists — 61 re-injections across 4 sessions (≈64k tokens), most identical to the previous injection (no skill set change).

Environment

Claude Code v2.1.198+, macOS (darwin). Measurements: category-classified <system-reminder>/attachment records from session JSONL; tokens estimated chars/3.5 (relative ranking, not exact).

Suggested direction

Per-session content-hash de-dup for harness injections (task snapshots, tool-schema deltas, skill bodies, skill lists), or delta-only injection for the task list. Even a "skip if identical to last injection of same class" check removes the worst offenders (×15 identical snapshots).

View original on GitHub ↗

3 Comments

kcarriedo · 3 months ago

The numbers here are striking: 559k tokens across 178 task-list snapshot re-injections, 46% of all dynamically injected content, zero information gain after the first injection.

The core issue is change-blindness in the injection layer. The harness is treating "has the session received this block before?" as outside its responsibility, so it re-sends verbatim copies without checking whether anything changed. At 1.2M injected tokens per session, a large fraction is pure padding.

A few things worth considering for the fix path:

  1. Content hash on the injection site, not at request construction time. Before appending a block to the conversation, hash it and compare against a per-session "already-sent" set. If unchanged, skip. This covers the task-list snapshot and skill-body cases directly.
  1. Delta injection for task lists specifically. Instead of re-sending all task subjects and descriptions on each periodic reminder, send only a header ("N tasks in scope, [X] newly updated since last injection") and the diffs. Most sessions would drop to a single full snapshot plus small deltas.
  1. Tool-schema change detection. The 18k delta being re-sent twice sounds like the schema is rebuilt from scratch on each injection cycle rather than compared against the previously-sent version. A simple equality check before schema re-injection would catch this.
  1. Injection budget tracking as a first-class metric. The 559k / 1.2M ratio (46%) is a useful number. Surfacing "injected token overhead this session" in the session summary would make regressions visible before they compound.

The harness-level fix is probably the highest-leverage place to act -- it is upstream of everything else and the cost reduction compounds across all sessions.

junaidtitan · 3 months ago

559k tokens of identical re-injections out of ~1.2M measured — 46% of all dynamically injected content being task-list snapshots alone — is a carefully documented audit. The category breakdown is genuinely useful for prioritizing where CC's de-dup would have the most impact.

Worth noting what this pattern does structurally: each re-injection isn't just wasted tokens at request time. Each one is a new JSONL entry that permanently increases the token mass every subsequent turn has to carry — and the compaction event doesn't clear them either, it summarizes them. So a session with ×15 identical task-list snapshots is carrying roughly 15× the overhead on every turn and polluting the compaction summary with repetitive operational noise instead of actual task narrative. The practical effect is that compaction fires earlier than it should, and when it does, the summary has less real content to preserve.

The accumulated identical entries in the JSONL are something cozempic can trim between sessions. cozempic treat current --diagnose shows the breakdown by category (system-reminder payloads, tool results, etc.) and estimates what's pruneable; --execute applies it. It doesn't have per-class hash-dedup — it prunes based on size thresholds and staleness — but duplicate task-list injections and repeated system-reminder payloads tend to fall squarely in its scope. The effect is keeping the JSONL lean despite the re-injection pattern, so sessions stay under the compaction threshold for more turns.

The root fix is clearly CC-side — hash-check before injecting, or delta-only for the task list (as you suggest). Cozempic is the "clean up the mess" side of that while the fix lands.

bcherny collaborator · 1 month ago

Thanks for the detailed measurements. Two of the four classes you list have been addressed: re-invoking a skill that's already loaded no longer appends a second copy of its instructions (v2.1.202), and the deferred-tool reminder being sent twice after a skill invocation was fixed (v2.1.228). Changelog: https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md

The task-list reminder snapshots and skill-availability list re-injection are still worth looking at, so I'll leave this open for those.

🤖 Generated with Claude Code

Showing cached comments. Read the full discussion on GitHub ↗