[BUG] Silent context degradation — tool results cleared without notification on 1M context sessions this issue documents three separate mechanisms (microcompact, cached microcompact, session memory compact)

Open 💬 22 comments Opened Apr 2, 2026 by Sn3th

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Silent context degradation — tool results cleared without notification on 1M context sessions

What's happening - Deal breaker for Claude Opus not sour grapes but you literally pushing us back to GPT , Deepseek, GLM and Kimi 2.5 with this! I have been fighting dumber agents for the past 48 hours!

Since ~v2.1.89/2.1.90, tool result content from earlier in a session is being silently replaced with [Old tool result content cleared]. No compaction notification is shown. No /compact was triggered. The agent and user have no indication this is happening.

Sessions do heavy tool use — 50+ file reads, greps, bash commands per session. We're observing:

  • Token counter showing ~80k on a 1M context window, with early tool results already gone
  • Agent making confident statements from internalised summaries because the source material was silently stripped
  • Context visibly shrinking across multiple independent sessions (persistent and one-shot)
  • No autocompact threshold was hit (we set CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=70, threshold would be ~686k)

Root cause (from source)

Three mechanisms in src/services/compact/ run silently on every API call:

  1. Time-based microcompact (microCompact.ts:422) — if the gap since the last assistant message exceeds a threshold, old tool results are content-cleared. Threshold comes from GrowthBook (getTimeBasedMCConfig()).
  1. Cached microcompact (microCompact.ts:305) — uses cache_edits API to delete old tool results from server cache. Count-based trigger/keep thresholds from GrowthBook (getCachedMCConfig()).
  1. Session memory compact (sessionMemoryCompact.ts:57) — runs before autocompact, keeps only ~40k tokens of recent messages. Gated by tengu_session_memory GrowthBook flag.

None of these show any UI notification. None trigger PreToolUse/PostToolUse hooks. The user sees no "Compacting..." message.

Problem:

  • No transparency. The agent and user don't know context is being stripped. There's no opt-in, no notification, no setting to control it.
  • DISABLE_AUTO_COMPACT=true doesn't help. It only disables autocompact — microcompact still runs on every API call.
  • DISABLE_COMPACT=true is a sledgehammer. It kills manual /compact too, which we rely on.
  • GrowthBook controls mean this changed server-side without any CLI update or changelog entry. We didn't enable any new features — the behaviour appeared on its own.
  • 1M context is the product we're paying for. If the effective usable context is 40-80k due to silent trimming, the value proposition of Claude Max with 1M context is fundamentally undermined.

Environment:

  • Claude Code v2.1.90
  • Opus 4.6 with [1m] context
  • CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=70

What Should Happen?

Fix:

  1. An env var to disable microcompact independently (e.g. DISABLE_MICROCOMPACT=true) — let users who want their full context window keep it
  2. UI notification when tool results are cleared — same as autocompact shows "Compacting..."
  3. Changelog transparency when GrowthBook flags change context management behaviour — silent server-side changes to how context is managed are not acceptable for paying customers running production workloads
  4. A --no-microcompact flag or settings.json option — let power users opt out without losing manual /compact

Error Messages/Logs

Error message?! the result speaks for itself. the agent is effectively dumber. "microcompact independently"

Steps to Reproduce

Reproduce:

  1. Start a session with --model opus[1m]
  2. Read 20+ files, run grep/bash commands, do multi-file work
  3. After ~30-40 minutes of tool-heavy work, try to reference file contents from the first 10 minutes
  4. The agent will paraphrase from memory rather than quote — the original tool results are gone (Agent distilled effectively useless now!)
  5. Token counter will show far less than expected for the amount of work done (dishonest!)

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

v2.1.81

Claude Code Version

v2.1.90

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Other

Additional Information

Guys... this is a deal breaker for me! the Opus has been heavily distilled and effectively broken! there was no need for this change it adds absolutely no value what so ever.

View original on GitHub ↗

22 Comments

github-actions[bot] · 3 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/42394
  2. https://github.com/anthropics/claude-code/issues/31828
  3. https://github.com/anthropics/claude-code/issues/18264

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

Sn3th · 3 months ago

This is NOT a duplicate of any of these issues. Those report autocompact misbehavior. This issue documents three separate mechanisms (microcompact, cached microcompact, session memory compact) that run silently on every
API call, bypass DISABLE_AUTO_COMPACT entirely, and are controlled by server-side GrowthBook flags. The source code paths are cited. Please review before auto-closing.

ArkNill · 3 months ago

This is excellent investigative work — the three compaction mechanisms you identified (microCompact.ts:422, microCompact.ts:305, sessionMemoryCompact.ts:57) could be a missing piece of the puzzle.

Here's how this connects to the token drain bug:

Cache invalidation chain: Anthropic's prompt caching works by matching exact token prefixes. If microcompact silently strips or modifies tool results mid-conversation, the cached prefix no longer matches → cache miss → every token billed at full price (the core symptom in #40524/#34629/#41788).

So the sequence would be:

  1. Microcompact triggers silently (GrowthBook flag, no user notification)
  2. Old tool results get replaced with [Old tool result content cleared]
  3. The conversation prefix changes → prompt cache invalidated
  4. Next API call: 0% cache read → full-price billing on entire context
  5. Usage burns 5-10x faster than expected

This would explain why:

  • v2.1.90 fixed the cache bug in some setups but not others (depends on whether microcompact triggers)
  • CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=70 doesn't help (microcompact bypasses it entirely)
  • The bug appears intermittent (GrowthBook A/B testing controls who gets hit)

The fact that these are controlled by server-side GrowthBook flags means Anthropic can change the behavior without a client update — which aligns with #37394's finding that old Docker versions (never updated) also started draining recently.

Have you been able to capture the actual GrowthBook config values (getTimeBasedMCConfig(), getCachedMCConfig()) to see what thresholds are being applied?

Sn3th · 3 months ago

@ArkNill yeah, you can pull those. The CLI caches the GrowthBook payload to ~/.claude.json under cachedGrowthBookFeatures. Gets synced on init and refreshes periodically during a session.

Quick way to extract the relevant flags:

python3 -c "import json; gb=json.load(open('$HOME/.claude.json')).get('cachedGrowthBookFeatures',{}); [print(f'{k}: {json.dumps(gb.get(k,\"NOT PRESENT\"),indent=2)}') for k in ['tengu_slate_heron','tengu_session_memory','tengu_sm_compact','tengu_sm_compact_config','tengu_cache_plum_violet']]"

We checked two separate machines, different accounts, both Claude Max, v2.1.90, Linux:

| Flag | Machine 1 (dev) | Machine 2 (prod, different account) |
|---|---|---|
| tengu_slate_heron | {"enabled": false, "gapThresholdMinutes": 60, "keepRecent": 5} | identical |
| tengu_session_memory | false | identical |
| tengu_sm_compact | false | identical |
| tengu_sm_compact_config | {"minTokens": 2000, "maxTokens": 20000, "minTextBlockMessages": 5} | identical |
| tengu_cache_plum_violet | true | identical |

All three mechanisms showing as "disabled" on both machines. Cache timestamps differ by ~5 hours (both today), same values.

But we're still seeing tool results silently replaced with [Old tool result content cleared] mid-session. No compaction notification, no hooks firing the exact symptom from the original report.

We've also set DISABLE_CLAUDE_CODE_SM_COMPACT=true across every spawn path in our system as a belt-and-suspenders measure. So session memory compact is blocked by env var AND by GrowthBook. Time-based MC shows disabled. Cached MC appears to be gated behind a compile-time feature flag that isn't active in external builds so that path likely doesn't exist in the binary Max users are running.

Every silent in-flight mechanism we've been able to identify is either off by env var, off by GrowthBook, or gated out of the build. And context is still being silently stripped.

So either there's a path we haven't traced yet, or GrowthBook evaluates differently in-session than what gets written to the disk cache (it uses per-session attributes for remote eval).

One thing worth noting the SM compact thresholds in the remote config are more aggressive than the code defaults: minTokens: 2000, maxTokens: 20000 vs defaults of 10000/40000. If that gate gets flipped on for anyone, it'll keep less context than you'd expect.

If others are experiencing this, run the script above and share your values if someone shows tengu_sm_compact: true or tengu_slate_heron.enabled: true, that'd confirm the A/B angle and explain why it's intermittent.

Sn3th · 3 months ago

Operational impact agent quality degradation under microcompact

We've been running Claude Code for 4 months previously GPT and Kimi 2.5. The silent context trimming is now our single biggest quality bottleneck. Some real-world
observations:

Operator review is broken. When I scroll back through a session to review what the agent did, tool results are gone. I can't audit the agent's work because the evidence it acted on has been silently replaced with [Old tool
result content cleared]. For anyone using Claude Code in a supervisory capacity reviewing AI-generated commits, verifying investigation quality this is a fundamental problem. The audit trail is destroyed mid-session.

Agent recovery from mistakes is impossible. When an agent hits a debugging rut (wrong approach, misread error, bad assumption), recovery depends on the agent seeing its own prior failed attempts. With microcompact silently
stripping those attempts, the agent re-tries the same failing approach because it can't see that it already tried it. We had a concrete case this week: an agent spent hours circling a routing bug model upgrades, config
tuning, trigger enrichment while the actual root cause was a simple filter mismatch. A different engine (OpenAI Codex, full context preserved) found it in minutes with fresh eyes. The Opus agent wasn't less capable it
was operating on 40-50K of degraded context while believing it had 1M.

Effective context under load is ~40-80K, not 1M. During heavy tool use (which is the entire point of Claude Code file reads, greps, bash commands), microcompact kicks in aggressively. The token counter shows 80K on a 1M
window. That's not "80K used" that's "everything else was silently trimmed." For tool-heavy workflows, the 1M context advantage over smaller windows is largely theoretical.

The competitive gap this creates is real. We now run a standing order: if an agent fails twice on the same problem, switch to a different engine. Not because Opus is less capable it's because Opus inside Claude Code can't
maintain the context it needs to work through complex problems. The same model with its full context would likely succeed. The CLI's context management is the bottleneck, not the model.

The asks from the original issue still stand. An env var to disable microcompact independently (DISABLE_MICROCOMPACT=true) would let power users who are paying for 1M context actually use it. We'll manage our own compaction we already have the infrastructure for it.

arizonawayfarer · 3 months ago

This is from my windows machine:

tengu_slate_heron: {
  "enabled": false,
  "gapThresholdMinutes": 60,
  "keepRecent": 5
}
tengu_session_memory: false
tengu_sm_compact: false
tengu_sm_compact_config: {
  "minTokens": 2000,
  "maxTokens": 20000,
  "minTextBlockMessages": 5
}
tengu_cache_plum_violet: true
ArkNill · 3 months ago

@Sn3th Really appreciate you sharing this — the GrowthBook extraction method and the two-machine comparison are exactly what this thread needed.

I ran the same check on my machine (ZBook Ultra, Max 20, v2.1.90, Linux):

tengu_slate_heron: {"enabled": false, "gapThresholdMinutes": 60, "keepRecent": 5}
tengu_session_memory: false
tengu_sm_compact: false
tengu_sm_compact_config: {"minTokens": 2000, "maxTokens": 20000, "minTextBlockMessages": 5}
tengu_cache_plum_violet: true

Identical. So that's 3 machines, 3 accounts, all showing disabled — and context is still being stripped.

Your runtime vs disk cache theory makes the most sense to me. GrowthBook evaluates per-session attributes (user ID, plan tier, session ID, etc.) at runtime, and what lands in ~/.claude.json is just a snapshot of the last eval. If the CLI re-evaluates mid-session with different attributes — say, after crossing a token threshold or based on session duration — the disk cache would never show it. That would explain why everything looks "off" on disk while something is clearly running.

This should be testable: intercept the GrowthBook SDK calls (or the remote eval API endpoint) during a session where stripping is actively happening, and diff against the disk cache values.

The SM compact thresholds bother me regardless of the gate being off. minTokens: 2000, maxTokens: 20000 vs code defaults 10000/40000 — 5x lower floor, 2x lower ceiling. When (not if) that gate flips on via A/B, sessions will retain far less context than anyone paying for 1M expects.

One more thing worth checking: when you see [Old tool result content cleared], is that string present in the raw API response coming back from Anthropic, or is the CLI inserting it locally? If it's already in the response, that's server-side clearing — no GrowthBook gate would matter because the content never reaches the client in the first place.

Added this finding to the analysis repo: MICROCOMPACT.md

Sn3th · 3 months ago

@ArkNill 3 machines confirmed identical on our end too.

We dug further and found additional context mutation paths beyond the three in the original report. These run in the pre-request pipeline and are NOT controlled by any DISABLE_* env var:

Additional GrowthBook flags to check (add these to the extraction script):

python3 -c "import json; gb=json.load(open('$HOME/.claude.json')).get('cachedGrowthBookFeatures',{}); [print(f'{k}: {json.dumps(gb.get(k,\"NOT PRESENT\"),indent=2)}') for k in ['tengu_hawthorn_window','tengu_pewter_kestrel','tengu_summarize_tool_results','tengu_pebble_leaf_prune','tengu_tool_result_persistence']]"

Our values:

| Flag | Value | What it does |
|---|---|---|
| tengu_hawthorn_window | 200000 | Aggregate tool result budget 200k token cap across all tool results |
| tengu_pewter_kestrel | {"global": 50000, "Bash": 30000, "Grep": 20000, ...} | Per-tool result size caps |
| tengu_summarize_tool_results | true | System prompt telling model to expect tool result clearing |

The aggregate budget (applyToolResultBudget()) runs before microcompact and autocompact in the request pipeline. Once your total tool results exceed 200k tokens, older results get replaced. On a heavy session with 50+ file reads, greps, and bash commands, 200k goes fast. The per-tool caps are even tighter Grep results hard-capped at 20k tokens, Bash at 30k, global at 50k per individual result.

Important correction to our earlier analysis: /export is NOT proof of what the API receives. It reads from context.messages (in-memory conversation state), but the request pipeline creates a separate working copy and mutates it through budget enforcement, microcompact, and context collapse before sending. A clean export doesn't mean the API got clean context.

We also confirmed DISABLE_COMPACT=true doesn't touch these paths it only gates autocompact and manual /compact. The pre-request budget enforcement runs regardless.

We tried overriding these values by editing the disk cache directly GrowthBook overwrites from in-memory remote eval within seconds. Made the config file immutable (chattr +i) CLI won't start. Built a file watcher to re-apply on every sync in-memory values take priority over disk anyway.

There is no external override. These flags are controlled server-side via GrowthBook remote eval, the CLI reads them from memory, and no env var, config edit, or filesystem trick can change them from outside the process.

The ask from the original report should be expanded: we don't just need DISABLE_MICROCOMPACT we need a way to disable the tool result budget enforcement and per-tool caps too. A single DISABLE_ALL_CONTEXT_MUTATION=true that actually stops everything in the pre-request pipeline would be ideal. Right now users paying for 1M context have no way to use it.

arizonawayfarer · 3 months ago

This is what I see (Windows again):

tengu_hawthorn_window: 200000
tengu_pewter_kestrel: {
  "global": 50000,
  "Bash": 30000,
  "PowerShell": 30000,
  "Grep": 20000,
  "Snip": 1000,
  "StrReplaceBasedEditTool": 30000,
  "BashSearchTool": 20000
}
tengu_summarize_tool_results: true
tengu_pebble_leaf_prune: true
tengu_tool_result_persistence: true
Sn3th · 3 months ago

@arizonawayfarer thank you. I am convinced its happening server side. we disabled telemetry and nuked the tengu_ settings from the claude json files. it should force the system back to default however the content is being pruned at server side. they forcing the settings on us. the end users experience with claude code has been distilled. I stand by my comments.

Anthropic have either severely over played their hand on this or this is an unintentional bug. either way the opus is in a state of useless for all affected. x20 account means nothing. x5 means nothing. lets see if it gets resolved in the coming days. its impossible to work with right now. nobody can review any code, the agent spirals and completely disillusioned, easily loses focus.

Hoping whoever introduced this terrible function gets chopped from the team.

arizonawayfarer · 3 months ago

@Sn3th I tend to agree - I've been trying many things on my side out of all of the open issues there are about model degradation and availability. Everything I've adjusted on my side has had impacts, but not enough of an impact to overcome how unusable the product is now.

We're only seeing half of the picture, there could be any number of things happening outside of what we can see on the client side. Given the lack of attention to the matter or even communication about it by Anthropic, I've come to accept that this is just how they want it to be now or are too incompetent to fix it themselves.

The fact that the community is the one troubleshooting and making strides on the issue, only because the source code was accidentally leaked, really speaks volumes about the whole thing.

ArkNill · 3 months ago

Follow-up: proxy-based testing results (April 3)

Ran systematic tests with an enhanced monitoring proxy (cc-relay) across v2.1.90 and v2.1.91. Here's what we found:

Cache impact — correction to my earlier hypothesis

My April 2 comment suggested microcompact would cause cache invalidation. After measuring 158+ clearing events across multiple sessions:

| Context | Cache ratio during clearing |
|---------|---------------------------|
| Main session | 99%+ — no impact |
| Sub-agent cold start | 0-39% — significant drops |
| Sub-agent warmed | 94-99% — normal recovery |

The stable substitution (same indices, same marker text every call) preserves the prompt prefix, so the main session cache stays valid. The actual cost is context quality degradation, not cache billing — the model loses access to earlier tool results and can't reference them accurately.

Bug 5 confirmed: applyToolResultBudget() is active

Following up on @Sn3th's comment about tengu_hawthorn_window and tengu_pewter_kestrel — I enhanced the proxy to scan outgoing request bodies for tool result sizes. Results:

  • 261 budget events detected in a single session
  • Tool results reduced to 1-41 chars after the 200K aggregate threshold
  • Budget exceeded at 242,094 chars (> 200K cap)
  • Examples: file reads originally returning thousands of chars → 22 chars, 1 char, 2 chars

This is the separate pipeline @Sn3th identified — runs before microcompact, no env var override.

v2.1.91 status

Tested on v2.1.91 (npm + standalone, same proxy): 14 microcompact events + 71 budget events in short test sessions. Neither bug is fixed. The maxResultSizeChars override in v2.1.91 is MCP-only — built-in tools (Read, Bash, Grep) are unaffected.

Clearing pattern details

  • All cleared indices are even-numbered → targets tool_use/tool_result pairs specifically
  • Indices expand over time: starts with early messages, progressively includes newer ones
  • Same 7-12 indices cleared consistently on every subsequent API call
  • GrowthBook disk cache: no changes during active clearing (confirmed with 2-second polling)

Full analysis and per-request data: claude-code-cache-analysis (updated today with MICROCOMPACT.md and TEST-RESULTS-0403.md)

kolkov · 3 months ago

Confirming from a different angle — we hit the same silent context stripping and traced how it interacts with the resume pipeline.

Our session (20 MB, 5,027 lines, 444 user messages) loads as 644 tokens (0.1%) on /resume in v2.1.91. Source code analysis revealed three v2.1.91 regressions in session loading:

  1. walkChainBeforeParse removed (fork pruning for >5 MB files)
  2. New ExY timestamp fallback bridges across fork boundaries
  3. Missing leafUuids check in getLastSessionLog

Full analysis with exact source code references: #43044

Separately, we built a Go CLI tool that reads session JSONL directly — bypassing the broken resume, extracting all messages, file operations, GitHub commands, and tool actions: https://github.com/kolkov/ccdiag

go install github.com/kolkov/ccdiag@latest
ccdiag recover --latest D:\projects\myproject
ccdiag recover --output full -o recovery.md session.jsonl

Your GrowthBook flag survey is invaluable — tengu_hawthorn_window: 200000 and tengu_pewter_kestrel being active while all microcompact gates show disabled confirms there's an undocumented code path. We see the same pattern: DISABLE_AUTO_COMPACT=true does nothing for these mechanisms.

At this point we're including ready-made prompts for Claude Code in our issues (see #43044) — since it writes 100% of the codebase anyway, might as well give it proper fix instructions directly.

Background on our research (12 versions reverse-engineered + source leak analysis): https://dev.to/kolkov/we-reverse-engineered-12-versions-of-claude-code-then-it-leaked-its-own-source-code-pij

@Sn3th @ArkNill — combining your proxy data (327 microcompact events, 261 budget events) with our JSONL forensics and source code RE gives a fairly complete picture of the 5-layer problem.

junaidtitan · 3 months ago

Silent tool result clearing on 1M sessions is CC's microcompact system stripping content without notification. This often happens when sessions accumulate large tool outputs that push past internal thresholds.

Cozempic v1.4.1 has a tool-output-trim strategy that proactively trims large tool results (>8KB or >100 lines) before CC does it destructively. It's also microcompact-aware — it skips tool results already handled by CC's microcompact to avoid double-processing.

pip install cozempic && cozempic init

The doctor command can diagnose these issues: cozempic doctor

Sn3th · 3 months ago

@ArkNill check you email in the next hour.

junaidtitan · 3 months ago

Silent tool result clearing is CC's microcompact stripping content without notification. Cozempic v1.6.11 prevents it by keeping sessions lean before microcompact triggers. The tool-output-trim strategy is also microcompact-aware — it skips tool results already handled by CC.

pip install cozempic && cozempic init

Auto-detects 1M context for Opus/Sonnet 4.5/4.6.

Sn3th · 3 months ago

@junaidtitan thanks man but I don't think you understand the issue. This is the second time you're pushing a lean session strategy as a solution for what is clearly a context degradation bug on Anthropic's side. Cozempic does not address the problem being raised here.

My sessions are already as lean as they need to be. I have custom controls that already do what Cozempic is attempting to do. I don't spam back to the API. I already curate my input streams meticulously. After your first comment I actually went through the CC source code to rule out any doubt. There are literally no markers or warnings when content gets silently stripped.
Direct Response to Cozempic: the core issue in this bug report is that CC silently prunes content from 1M context sessions without user consent or notification. Recommending a tool whose primary strategy is to pre-prune tool results before CC's pruner kicks in is not a solution to unwanted pruning. It's accepting the pruning and doing it yourself first. That's the opposite of what this issue is asking for.

The issue is hidden GrowthBook feature flags pruning content without notification. No amount of session hygiene fixes that.

I appreciate you building a tool and trying to help, but relative to what we've already built to protect our sessions, Cozempic covers a very small subset of the problem. The real fix needs to come from Anthropic's side.

arizonawayfarer · 3 months ago

I'm unsure if this is going to provide value, because I don't have a solid grasp on the bigger picture issue.. but with the conversations around microcompaction and tool history I did some analyzing of my jsonl files in ~/.claude/projects directory.

I'm noticing heavy duplicated tool re-use in most of my sessions. One of my larger sessions has a 35% tool duplication rate (of all tool calls, 35% were duplicates). At first I thought these were from the same agent, because I'm not instructing Claude to spawn subagents, but it turns out that Claude is deciding on its own to spawn subagents.

Each of these new subagents is re-running tools that have already been run instead of the parent agent frontloading the subagent's context. I haven't yet diagnosed the implications for things like caching, context size, etc, but in my view the content a subagent needs should be injected into it in lieu of having the subagent do work that has already been done.

Theres a main agent, and a number of 'acompact' agents running in the same session. These acompact agents can have different IDs, but they're all prefixed with acompact followed by a unique ID

The biggest offender is the reading of source files. In one session, the same source file was read 6 times by the main and subagents. Example anonymized output:

SessionId : xxxx
Slug      : session-slug
AgentId   : main
Tool      : Read
Count     : 3
Input     : {"file_path":"path\to\file.cs"}

SessionId : xxxx
Slug      : session-slug
AgentId   : acompact-xxxx
Tool      : Read
Count     : 3
Input     : {"file_path":"path\to\file.cs"}

Would appreciate any thoughts you all might have on drilling further into this in order to make a determination if this is part of the problem or if this is a PEBKAC issue.

``` powershell
$projectsRoot = '~\.claude\projects'
$jsonlFiles = Get-ChildItem -LiteralPath $projectsRoot -Recurse -Filter *.jsonl -File |
Select-Object -ExpandProperty FullName

$calls = foreach ($path in $jsonlFiles) {
if (-not (Test-Path -LiteralPath $path)) {
continue
}

foreach ($line in Get-Content -LiteralPath $path) {
try {
$row = $line | ConvertFrom-Json -ErrorAction Stop
} catch {
continue
}

if (-not ($row.message -and $row.message.content)) {
continue
}

$sessionId = if ($row.sessionId) { "$($row.sessionId)" } else { [IO.Path]::GetFileNameWithoutExtension($path) }
$slug = if ($row.slug) { "$($row.slug)" } else { '' }
$agentId = if ($row.agentId) { "$($row.agentId)" } else { 'main' }

foreach ($item in $row.message.content) {
if ($item.type -eq 'tool_use') {
$input = $item.input | ConvertTo-Json -Compress -Depth 30
[pscustomobject]@{
SessionId = $sessionId
Slug = $slug
AgentId = $agentId
Tool = "$($item.name)"
Input = $input
Signature = "$sessionId|$agentId|$($item.name)|$input"
}
}
}
}
}

$dupes = $calls |
Group-Object Signature |
Where-Object Count -gt 1 |
ForEach-Object {
[pscustomobject]@{
SessionId = $_.Group[0].SessionId
Slug = $_.Group[0].Slug
AgentId = $_.Group[0].AgentId
Tool = $_.Group[0].Tool
Input = $_.Group[0].Input
Count = $_.Count
}
}

$dupes |
Group-Object SessionId,Slug |
ForEach-Object {
[pscustomobject]@{
SessionId = $_.Group[0].SessionId.ToString()
Slug = $_.Group[0].Slug
DuplicateSignatures = $_.Count
AgentsWithDupes = ($_.Group.AgentId | Sort-Object -Unique).Count
DuplicateCalls = ($_.Group | Measure-Object Count -Sum).Sum
}
} |
Sort-Object DuplicateSignatures -Descending |
Format-Table -AutoSize

$targetSession = "{worstoffendingsessionid}"

$dupes |
Where-Object SessionId -eq $targetSession |
Sort-Object Count -Descending |
Format-List SessionId,Slug,AgentId,Tool,Count,Input

ArkNill · 3 months ago

@arizonawayfarer Not PEBKAC — you're seeing a real thing.

The acompact-* agents are part of Claude Code's auto-compaction
system, not something you triggered. When compaction kicks in, it
spawns these sub-agents to summarize context, and the problem is
exactly what you noticed: they re-run the same tools instead of
picking up where the parent left off.

We've been measuring subagent overhead on the proxy side — not
acompact-specific, but subagents in general across 279 sessions
(v2.1.91, Apr 1–6):

  • Subagents consume 62% of cache_create tokens but only account

for 17% of cache_read — they appear to rebuild context from
scratch rather than inheriting it

  • Median cold start: ~13K cache_create tokens per spawn

Your 35% tool duplication rate is measuring the same problem from a
different angle — call count vs token cost, but same underlying
pattern. There's also a separate issue tracking duplicate compaction
agents specifically: #41607.

On the budget interaction: applyToolResultBudget() runs client-side
on each agent's own context, so acompact tool calls burn their own
200K cap, not the main session's. The waste is real — redundant API
calls, cache rebuilds, raw token spend — but it doesn't directly
accelerate tool result clearing in your primary context.

More context on subagent overhead and microcompact mechanics:

johnzfitch · 3 months ago
I'm unsure if this is going to provide value, because I don't have a solid grasp on the bigger picture issue.. but with the conversations around microcompaction and tool history I did some analyzing of my jsonl files in ~/.claude/projects directory. I'm noticing heavy duplicated tool re-use in most of my sessions. One of my larger sessions has a 35% tool duplication rate (of all tool calls, 35% were duplicates). At first I thought these were from the same agent, because I'm not instructing Claude to spawn subagents, but it turns out that Claude is deciding on its own to spawn subagents. Each of these new subagents is re-running tools that have already been run instead of the parent agent frontloading the subagent's context. I haven't yet diagnosed the implications for things like caching, context size, etc, but in my view the content a subagent needs should be injected into it in lieu of having the subagent do work that has already been done. Theres a main agent, and a number of 'acompact' agents running in the same session. These acompact agents can have different IDs, but they're all prefixed with acompact followed by a unique ID The biggest offender is the reading of source files. In one session, the same source file was read 6 times by the main and subagents. Example anonymized output: `` SessionId : xxxx Slug : session-slug AgentId : main Tool : Read Count : 3 Input : {"file_path":"path\to\file.cs"} SessionId : xxxx Slug : session-slug AgentId : acompact-xxxx Tool : Read Count : 3 Input : {"file_path":"path\to\file.cs"} ` Would appreciate any thoughts you all might have on drilling further into this in order to make a determination if this is part of the problem or if this is a PEBKAC issue. ` powershell $projectsRoot = '~\.claude\projects' $jsonlFiles = Get-ChildItem -LiteralPath $projectsRoot -Recurse -Filter *.jsonl -File | Select-Object -ExpandProperty FullName $calls = foreach ($path in $jsonlFiles) { if (-not (Test-Path -LiteralPath $path)) { continue } foreach ($line in Get-Content -LiteralPath $path) { try { $row = $line | ConvertFrom-Json -ErrorAction Stop } catch { continue } if (-not ($row.message -and $row.message.content)) { continue } $sessionId = if ($row.sessionId) { "$($row.sessionId)" } else { [IO.Path]::GetFileNameWithoutExtension($path) } $slug = if ($row.slug) { "$($row.slug)" } else { '' } $agentId = if ($row.agentId) { "$($row.agentId)" } else { 'main' } foreach ($item in $row.message.content) { if ($item.type -eq 'tool_use') { $input = $item.input | ConvertTo-Json -Compress -Depth 30 [pscustomobject]@{ SessionId = $sessionId Slug = $slug AgentId = $agentId Tool = "$($item.name)" Input = $input Signature = "$sessionId|$agentId|$($item.name)|$input" } } } } } $dupes = $calls | Group-Object Signature | Where-Object Count -gt 1 | ForEach-Object { [pscustomobject]@{ SessionId = $_.Group[0].SessionId Slug = $_.Group[0].Slug AgentId = $_.Group[0].AgentId Tool = $_.Group[0].Tool Input = $_.Group[0].Input Count = $_.Count } } $dupes | Group-Object SessionId,Slug | ForEach-Object { [pscustomobject]@{ SessionId = $_.Group[0].SessionId.ToString() Slug = $_.Group[0].Slug DuplicateSignatures = $_.Count AgentsWithDupes = ($_.Group.AgentId | Sort-Object -Unique).Count DuplicateCalls = ($_.Group | Measure-Object Count -Sum).Sum } } | Sort-Object DuplicateSignatures -Descending | Format-Table -AutoSize $targetSession = "{worstoffendingsessionid}" $dupes | Where-Object SessionId -eq $targetSession | Sort-Object Count -Descending | Format-List SessionId,Slug,AgentId,Tool,Count,Input ``

Great report, here's what's going on: https://claude.ai/public/artifacts/79918902-1564-4227-8fe2-90a5805c4f09

cnighswonger · 3 months ago

We can corroborate the microcompact and budget enforcement findings from a different angle — real-time detection via fetch interception rather than post-hoc JSONL analysis.

Our cache-fix interceptor (v1.2.0+) monitors outgoing API requests for context degradation markers on every call:

  • Microcompact detection — counts [Old tool result content cleared] markers in outgoing tool_result blocks and logs the ratio (cleared vs total)
  • Budget threshold warning — alerts when aggregate tool result characters approach the 200K tengu_hawthorn_window cap
  • GrowthBook flag dump — logs the relevant tengu flags on first API call so you can see exactly what's active in your session

Across 4,700+ intercepted calls over 8 days (multiple agents, Opus 4.6, Max 5x, 1M context):

  • 0 microcompact events detected — we haven't yet seen [Old tool result content cleared] in our outgoing requests, despite heavy tool use sessions. This aligns with @ArkNill's April 3 correction that microcompact may be more conservative than initially feared.
  • 84 budget warnings — tool result characters hitting 150K+ of the 200K threshold. One agent is currently at 154K. We haven't crossed the threshold to trigger actual clearing yet, but we're close.
  • GrowthBook flags confirmed identical to what @Sn3th and @arizonawayfarer reported: tengu_hawthorn_window: 200000, tengu_pewter_kestrel with per-tool caps (Bash: 30K, Grep: 20K, global: 50K).

We also confirmed in the CC source (v2.1.92) that there is no DISABLE_MICROCOMPACT environment variable — agreeing with @Sn3th's point that DISABLE_AUTO_COMPACT doesn't cover these mechanisms and DISABLE_COMPACT is too broad.

The interceptor doesn't prevent microcompact (it's applied server-side before our response arrives, and client-side before our request-side hook can intervene), but the detection logging gives you visibility into when it fires. CACHE_FIX_DEBUG=1 writes events to ~/.claude/cache-fix-debug.log.

junaidtitan · 2 months ago

Silent context clearing is one of the most frustrating issues — you lose tool results with no notification and the model starts hallucinating from stale memory. Cozempic includes doctor checks that detect exactly this kind of degradation (orphaned tool results, corrupted entries, oversized sessions) and 18 pruning strategies that proactively trim bloat before the runtime's silent microcompact kicks in. The guard daemon runs in the background and auto-prunes at 4 thresholds so you stay under the compaction trigger. pip install cozempic && cozempic doctor to diagnose, or cozempic guard for continuous protection. Would love to hear if it helps preserve your context.