Context · Measurement contract

Accounting rules

For users and implementers: defines how the bottom Context panel reports actual totals, categorized content and differences that cannot be reconstructed directly.

Status: implemented Scope: shared Web / App API Excluded: new UI styling

01 · The result must answer three questions

How much context is occupied?

Prefer actual input tokens returned by the provider; use local estimates only when no measurement is available.

Where does the content come from?

Show system, tools, MCP, skills, memory and messages as mutually exclusive categories; never count them twice.

What cannot be reconstructed?

Show the positive difference between the measured total and categorized estimates as “Other context (estimated)”; do not hide it.

02 · A single snapshot

Current branch
Read compacted rendered history, the latest system prompt and the frozen tool set.
Local categorization
Calculate message structure, tool schemas, Skills and Memory; subtract nested items from their parent categories.
Provider calibration
Combine the latest measured total for the same HEAD and calculate the uncategorized difference.

Calculate the local breakdown only once per API response. The panel must not reread the dynamic tool registry within that response, or the categories and estimated may refer to different moments.

03 · Mutually exclusive categories

CategorySourceAccuracy and boundaries
MessagesRendered history; visible text, thinking, tool input/result and memory prefetchText can be reconstructed; original images that were not persisted contribute to the difference.
System promptThe latest complete system prompt actually recordedCalculate the full value first, then subtract Skills, resident Memory and the deferred catalog to avoid duplication.
Skills / MemoryIndexes and resident blocks actually injected into the system promptThese are components of the System prompt and must not increase the total again.
System tools / MCP toolsProvider schemas for the tool set frozen for this turnAssign each tool according to its _mcp_server to one of the two categories.
Deferred toolsTool-name catalog within the system promptCount the name catalog actually sent, not the full descriptions/schemas.
Other context (estimated)provider total - classified estimateIncludes content that cannot be reconstructed reliably: non-persisted images, provider wrapping overhead and temporary surface prompts.

04 · Calculation rules

classified = system_other + skills + memory + tools + mcp + deferred + messages other = max(0, provider_total - classified) displayed_used = provider_total if measured else classified free = max(0, window - displayed_used)

If local category estimates exceed the provider measurement, retain the provider total as the occupancy value and scale displayed categories down proportionally. The response retains raw estimates and the calibration factor; never display a negative difference.

05 · Acceptance criteria

06 · Implementation evidence

Record actual input

system_prompt_node.py reads the actual system prompt by branch HEAD; tool_snapshot_node.py stores the frozen tools for the turn and their calculated cost.

Shared calculation and calibration

session_stats.py handles categorization, deduplication and calibration against the provider total; budget.py estimates the frozen tool schemas.

Consume the same API

tree.py calculates the breakdown once; App and Web use context-breakdown-panel.tsx to display the same response.

test_session_stats_accuracy.py Coverage includes structured messages, uncategorized differences, overestimate calibration, branch ancestry, old-snapshot compatibility, child Agents that do not advance HEAD, frozen tools, dynamic registries and model switches; all 51 focused Context tests passed.