Skip to content

About

Audit local Claude Code and Codex session transcripts, measure Context Rent per tool output, and replay counterfactual autoCompactWindow policies offline.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

compactsim

compactsim logo

Zero-dependency profiler and counterfactual autoCompactWindow replay simulator for local Claude Code (~/.claude/projects) and Codex (~/.codex/sessions) JSONL transcripts.

compactsim real run across 147 local sessions

Install & Run

npx compactsim

No API keys, no network calls, and no dependencies. By default it scans ~/.claude/projects/**/*.jsonl and ~/.codex/sessions/**/*.jsonl.

# Run against a specific directory or JSONL transcript
npx compactsim --dir ~/.claude/projects

# Run against the bundled 24-turn sample transcript
npx compactsim --demo

# Emit machine-readable JSON or a standalone dark-mode HTML report
npx compactsim --json > report.json
npx compactsim --html report.html

Why this exists

On 1M-context models, Claude Code waits until roughly 967K tokens before compacting the conversation. Every turn between 200K and 967K resends the full transcript history. Across 147 real local sessions (2,284 deduplicated API turns, 255.79M total input tokens) on my machine, 47.8% of weighted token spend happened on the 307 turns where the window had already crossed 200K tokens.

Setting "autoCompactWindow" lower cuts that tail cost, but compacting too aggressively triggers 65-second summary pauses, invalidates the prompt cache prefix on the turn after compaction, and causes post-compaction amnesia where the agent immediately re-reads files it had read 10 turns earlier because the summary dropped implementation details.

compactsim parses your actual local session history and replays every turn under candidate compaction windows (400K, 250K, 150K) and sliding tool-output eviction (slide-tools@15t) so you can pick a threshold backed by your own workload instead of a guess.

What it measures

  1. Streaming-aware turn deduplication (1.4x to 3.0x overcount correction): My first parser summed message.usage on every type: "assistant" line in ~/.claude/projects and overcounted a single 11-turn Claude Code session (4baee81b) by 3.0x (33 records for 11 API turns). Claude Code writes separate JSONL lines for the thinking block, text block, and each tool_use block of a single API response, all sharing one message.id and repeating the turn's input_tokens. Codex similarly emits duplicate event_msg:token_count frames when total_token_usage.total_tokens has not changed. compactsim collapses chunks by message.id and total_tokens before computing any totals.
  2. Context Rent (payload_tokens * turns_carried): A 10,053-token shell dump at turn 2 that stays in the window until turn 151 costs 1.51M token-turns of context rent. compactsim pairs every tool_use / custom_tool_call with its tool_result and ranks the exact commands and file reads that occupied the most cumulative window area.
  3. Redundant Reads & Post-Compaction Amnesia: Tracks every Read and shell file inspection (cat, head, tail, sed -n) per session. Flags files read multiple times without an intervening Edit/Write, and separates out post-compaction re-reads where a file read before compaction is re-read again after the summary reset.
  4. Counterfactual Policy Replay: Weights tokens by API billing ratios (1.0x uncached input, 1.25x cache write, 0.10x cache read, 5.0x output) and replays each session at 400,000, 250,000, and 150,000 token thresholds, charging both the summary generation overhead and the post-compaction cache-write rebuild.

Honest limitations

  • Counterfactual replay cannot predict new agent mistakes: When compactsim simulates an earlier compaction at 250K tokens, it charges the summary generation call and cache-prefix rebuild, and scales subsequent turns in that segment by the reduced window size. It cannot know whether a real live summary at turn 18 would have caused the model to take 3 extra turns re-reading files.
  • Tool payload tokens are byte-estimated (ceil(chars / 4)): Per-turn input, cache-read, cache-write, and output totals come from exact API usage records in the JSONL logs, while individual tool_result shares inside a turn use character-to-token estimation because the API does not break down token counts per tool block.
  • Weighting uses standard relative ratios, not your custom enterprise contract: Cost deltas are reported in weighted input-token equivalents (1.0x / 1.25x / 0.10x / 5.0x) rather than USD because a single JSONL corpus often mixes Opus, Sonnet, Haiku, and Codex models across different subscription and API tiers.

License

MIT · Prince Jain

About

Audit local Claude Code and Codex session transcripts, measure Context Rent per tool output, and replay counterfactual autoCompactWindow policies offline.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages