|
| 1 | +# Calibrating the bundled Claude Code overhead (`cc_builtin`) |
| 2 | + |
| 3 | +The bundled system prompt + built-in tool schemas never appear in the |
| 4 | +transcript, so `cc.billing`'s `static_overhead` lane relies on the |
| 5 | +per-version table in `src/cc_builtin.go` (`ccBuiltinByVersion`). This doc is |
| 6 | +the procedure for refreshing it on each Claude Code release — and, since the |
| 7 | +`Components` field landed, for producing the itemized breakdown the |
| 8 | +dashboard shows. |
| 9 | + |
| 10 | +## Per-release procedure |
| 11 | + |
| 12 | +1. **Capture one real request** on the new CC version, in a project with NO |
| 13 | + MCP servers connected and auto-memory disabled (so the request is almost |
| 14 | + pure bundled content). Two known-good capture paths: |
| 15 | + - [cost-xray](https://github.com/tigerless-labs/cost-xray): transparent |
| 16 | + local mitmproxy hop; the captured request body contains the full |
| 17 | + `system` block and `tools` array. |
| 18 | + - Any HTTPS-intercepting proxy with the CC CLI's proxy env vars. |
| 19 | +2. **Split the `system` block into its named sections** (identity/harness |
| 20 | + rules, security policy, memory instructions, environment template, |
| 21 | + session guidance, context management). The section headings are stable |
| 22 | + markdown headers. |
| 23 | +3. **Measure each section** with the free `count_tokens` endpoint (the |
| 24 | + plugin's own `countTokensFor` works, or `curl` — auth with |
| 25 | + `ANTHROPIC_API_KEY` or the CC OAuth token). |
| 26 | +4. **Measure the always-on `tools` array** the same way (count with and |
| 27 | + without `tools`, diff). Per-tool figures: add tools one at a time. |
| 28 | +5. Add the row: |
| 29 | + |
| 30 | +```go |
| 31 | +"2.1.180": { |
| 32 | + SystemPromptTokens: 4900, // Σ prompt sections |
| 33 | + SystemToolsTokens: 1900, // tools array |
| 34 | + SystemToolsDeferredTokens: 11300, // /context's deferred row |
| 35 | + Components: map[string]int{ |
| 36 | + "identity_and_rules": 2100, |
| 37 | + "security_policy": 300, |
| 38 | + "memory_instructions": 800, |
| 39 | + "environment_template": 200, // static template only — the dynamic |
| 40 | + // part (cwd, git status) is carved out |
| 41 | + // at runtime as the `environment` item |
| 42 | + "session_guidance": 600, |
| 43 | + "context_management": 400, |
| 44 | + "builtin_tool_schemas": 1900, |
| 45 | + }, |
| 46 | +}, |
| 47 | +``` |
| 48 | + |
| 49 | +Invariant: `Σ Components == SystemPromptTokens + SystemToolsTokens`. |
| 50 | + |
| 51 | +## Validation |
| 52 | + |
| 53 | +Run a fresh session on the new version and check the trace's |
| 54 | +`cc.billing.lanes.static_overhead.total` against `/context`'s |
| 55 | +"System prompt" + "System tools" rows (expect agreement within ~15%; the |
| 56 | +always-on tool set varies slightly per session config). The `unattributed` |
| 57 | +lane absorbs the difference either way — if it jumps after a CC release, |
| 58 | +this table is stale. |
| 59 | + |
| 60 | +## What NOT to do |
| 61 | + |
| 62 | +Do not derive these numbers as a usage residual ("call-1 usage minus known |
| 63 | +pieces") — that residual absorbs all unobserved request content (system |
| 64 | +reminders, deferred-name listings) and estimation drift; it inflated |
| 65 | +static_overhead ~3.6x when tried (see git history). |
0 commit comments