Skip to content

Repository files navigation

contextbudget

Measure Claude Code context pressure, delegation, and token distribution from the transcripts already on your machine.

Tests Python License

contextbudget is a local, dependency-free CLI for the questions only your own transcripts can answer:

  • How often do sessions cross 100k or 150k tokens of context?
  • How much work happens in the main conversation versus subagents?
  • Which model families carry the token load?
  • Are lower-cost specialist agents actually reducing frontier-model work?
  • What would the same work cost at frontier list price?

It also includes an optional Claude Code workflow kit: context guards, specialist-agent definitions, return contracts, and a session-handoff protocol. The analyzer works on its own; the kit is the set of controls used in the field study below.

Token counts and context distributions are the primary output. Dollar figures are a configurable list-price proxy, useful for comparing slices rather than reconciling a bill.

Quick start

git clone https://github.com/jfkconstruct/contextbudget
cd contextbudget

python -m contextbudget --since 2026-06-01 --by month

Python 3.9 or newer, standard library only, nothing to install; pip install contextbudget once the package is on PyPI. The default scan root is ~/.claude/projects.

Restrict the scan to one or more projects:

python -m contextbudget --since 2026-06-01 --until 2026-09-01 --project my-project

Emit machine-readable JSON:

python -m contextbudget --by week --json

Override model-family prices (comma-separated group=in/out pairs, merged over the defaults):

python -m contextbudget --prices fable=10/50,sonnet-5=2/10

What it measures

For each month, week, or complete scan, contextbudget reports:

  • Session, main-turn, and subagent-turn counts
  • Input and output tokens by model family
  • Cache-creation and cache-read tokens
  • Peak main-conversation context per session (median, p90, max)
  • Sessions exceeding 100k and 150k context
  • Agent calls by subagent_type and the lower-cost share
  • Main-versus-subagent token distribution
  • Actual subagent price proxy versus the same work at the frontier flagship rate
  • Raw transcript lines versus deduplicated logical messages
  • Malformed lines skipped during the scan

The pipeline is deliberately small:

Claude Code JSONL transcripts
            |
            v
   allowlisted metadata
            |
            v
 logical-message deduplication
            |
            v
 main/subagent + model grouping
            |
            v
 context, token, and price metrics
            |
            +----> text report
            |
            +----> JSON

Peak context per session is the maximum over that session's assistant turns of input_tokens + cache_creation + cache_read_input_tokens. That definition matches what hooks/context_guard.py counts, so the tool and the hook agree on what "context" means.

Prices per million tokens, by model family (list prices as of 2026-08): Fable 5 / Mythos 10/50, Opus 5 and Opus 4.5-4.8 5/25, Opus 4.1 and earlier 15/75, Sonnet 5 2/10, older Sonnet 3/15, Haiku 1/5. Cache reads 0.1x input; cache writes 1.25x (5-minute TTL) or 2x (1-hour TTL) when the transcript says which, 1.25x otherwise.

Why deduplication matters

Claude Code may write one assistant message as several JSONL lines, one per streamed content block. Each line can repeat cumulative usage for the same logical message. Summing those lines directly overcounts tokens.

contextbudget deduplicates assistant events on (message.id, requestId) and keeps the final cumulative usage record. In the production dataset behind this project, the naive implementation inflated sum-based measurements by roughly 50 to 70 percent.

The scanner also handles:

  • Current subagent transcripts under <session>/subagents/agent-*.jsonl
  • Older inline isSidechain records
  • Repeated Agent or Task tool-use blocks
  • Forked subagents, which inherit the parent conversation, model, and cache, and are therefore excluded from the lower-cost delegation metric
  • Five-minute and one-hour cache-write pricing when the transcript provides the breakdown

See contextbudget/scan.py for the parsing rules.

Privacy boundary

The scan runs locally. It performs no network calls and makes no transcript changes.

Each JSONL record is decoded locally, but the analyzer uses only the structured fields needed for aggregation:

  • Event type and timestamp
  • Sidechain marker
  • Opaque message and request identifiers used for deduplication
  • Model and usage fields
  • Agent or Task tool name, identifier, and subagent_type

No message text, prompts, tool descriptions, or transcript contents are used or emitted, and the JSON output carries no session identifiers. Every value leaving the scanner is an aggregate, model-family label, subagent-type label, window label, count, or token number.

Synthetic fixtures contain a content sentinel that the test suite verifies never appears in text or JSON output.

Example output

From the included synthetic fixtures (python -m contextbudget --root fixtures/sample-projects --by month):

=== 2026-07 ===
sessions: 1  main turns: 6  sub turns: 3
main dedup: lines with usage=6, deduped messages=6
sub dedup: lines with usage=3, deduped messages=3
main tokens by tier (in+out+cache_creation): {sonnet: 98,900}
main cache_read by tier: {sonnet: 116,000}
sub tokens by tier: {haiku: 2,700, sonnet: 2,001,498}
sub cache_read by tier: {haiku: 300, sonnet: 1,000,199}
agent calls: total=4  cheap_share=75.0%
  top subagent types: forge=1, gauge=1, general-purpose=1, scout=1
session max-context: n=1 median=155,000 p90=155,000 >100k=1 >150k=1 share>100k=100.0% share>150k=100.0% max=155,000
scope  tier                     in          out  cache_creation      cache_read      cost($)
main   sonnet               88,000        9,400           1,500         116,000         0.45
sub    haiku                 2,000          700               0             300         0.01
sub    sonnet            1,000,999    1,000,499               0       1,000,199        18.31
total cost (list-price proxy): $18.76
subagent-scope cost: $18.32 (97.6% of total)
subagent-scope cost if run at the frontier flagship rate (Fable 5): $61.09
delta (frontier flagship - actual) for subagent work: $42.77

A production field study

The repository includes a field report covering one developer, one repository, and two operating periods. Between June and August 2026, three workflow changes landed together:

  1. Fixed-contract specialist agents replaced ad hoc delegation.
  2. Hooks warned when the main context crossed absolute token thresholds.
  3. Sessions ended at task completion, with a durable written handoff.
Metric June 2026 August 2026
Sessions 58 389
Frontier tokens per session, main conversation 850,251 185,156
Agent calls routed to lower-cost fixed-contract agents 2.9% 94.6%
Sessions crossing 150k context 55.2% 33.4%
Sessions crossing 100k context 70.7% 83.5%
Subagent share of tokens (input + output + cache writes) 16.5% 56.4%
Subagent share of list-price proxy 5.6% 17.8%
Delegated work, priced as run versus at frontier list 36.9% 22.1%

Scanned 2026-09-02 with August closed, so the column is frozen. Reproducing these numbers requires --project; unscoped, June reads 60 sessions because two other repositories were active that month.

The practical result: lower-cost agents carried most of the delegated token volume while staying a small share of the price proxy. The remaining problem: 83.5 percent of August sessions still crossed 100k context. Delegation reduced what entered the main conversation, and main-context accumulation is the next thing to fix.

These numbers describe a change in workload shape. The interventions landed together, the model mix changed, and there is no task-completion denominator, so read them as a case study. The full methodology, failures, and caveats are in REPORT.md.

Optional workflow kit

The pieces that produced the August column, extracted from a running setup and stripped to the mechanism.

Context guards

File Purpose
hooks/context_guard.py UserPromptSubmit hook. Reads the transcript tail, warns at 100k and 150k absolute tokens in every UI (the terminal statusline never renders in the VS Code extension). Silent below 100k.
hooks/context_guard_posttool.py Same warning on PostToolUse, so a long autonomous turn hears it too.
hooks/orchestrate_default.py Injects the orchestrate-by-default directive on every prompt, about 60 tokens.
hooks/wake_budget_gate.py SessionStart gate that warns when the files read at wake exceed the wake budget (~10k estimated tokens).

Thresholds can be overridden with environment variables:

CONTEXT_GUARD_YELLOW=80000
CONTEXT_GUARD_RED=120000
CONTEXTBUDGET_WAKE_BUDGET=8000

Specialist agents

The included Claude Code agent definitions divide work by function:

Agent Role Default model
scout Locate files, code, configuration, and facts Haiku
gauge Measure behavior and test quantitative claims Sonnet
forge Apply a precise implementation specification Sonnet
distill Condense long material for the main conversation Sonnet
skeptic Adversarially test a claim or proposed conclusion Inherited

Each agent has a hard return contract with a line budget. The contracts keep delegation cheap and keep raw exploration from re-entering the main context.

See:

The example hook configuration in examples/settings.json uses Bash command wiring; adapt the shell configuration when installing it in a different environment.

Scope and limitations

contextbudget intentionally has a narrow scope.

  • Claude Code transcript formats are undocumented and can change; schema changes may require scanner updates.
  • Malformed JSONL records are skipped and counted, so a damaged transcript cannot abort a scan and schema drift stays visible: the report notes how many lines were skipped, and JSON output carries a top-level skipped_records field.
  • Unknown model families remain visible in the output but contribute to the price proxy only once a price is supplied via --prices.
  • The lower-cost delegation metric classifies calls from subagent_type; interpret custom agent names alongside the actual model-family totals.
  • Dollar figures use model-family list prices, and subscription billing or actual invoices will differ.
  • Calendar windows are UTC. A session spanning two windows contributes turns to both.
  • The published field study covers one developer and one operating style.

Tests

python -m unittest discover -s tests -v

Fixtures under fixtures/sample-projects/ are synthetic and include a three-line duplicated message and a content sentinel that must never appear in output. CI runs on Linux and Windows using Python 3.9 and 3.13.

Repository map

contextbudget/               Analyzer and CLI
tests/                       Unit and integration tests
fixtures/sample-projects/    Synthetic Claude Code transcripts
hooks/                       Optional context-management hooks
agents/                      Optional specialist-agent definitions
docs/                        Return contracts and operating playbooks
examples/                    Hook configuration and installation notes
REPORT.md                    Production field study

Status

Current version: 0.1.0. The project is usable directly from a clone; PyPI packaging is configured and publication is pending.

License

MIT.

About

Where your Claude Code tokens go: peak context, threshold shares, main vs subagent split, measured from your own transcripts. Aggregates only.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages