Conversation
Claude Code writes locally generated messages with the pseudo-model name `<synthetic>` and no token evidence. Both Claude adapter paths treated these as real model executions, so a session containing one reported: - `primary_model` as `<synthetic>` instead of the real model - a phantom `<synthetic>` entry in the session model list - `context.latest` as 0, collapsing real context into a measured zero - one extra execution, inflating per-execution derived metrics Skip records that have both the pseudo-model name shape and no token evidence. Requiring both conditions keeps a record that does carry billable tokens priced normally, so the guard cannot hide real usage. The existing zero-usage synthetic test is extended with the model, context, and execution assertions rather than duplicated. Its cache fixtures gain the `cache_creation` duration breakdown now required by duration-aware normalization. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Claude Code writes locally generated messages into the session transcript with the pseudo-model name
<synthetic>and no token evidence. Both Claude adapter loops counted these as real model executions.aggregates.pyalready drops a zero-usage<synthetic>row from the Models page (placeholder_model), and cost coverage is correct. The defect is upstream of that, in the Claude adapter itself, so the session's own evidence is wrong:primary_model<synthetic>claude-sonnet-4-6models['<synthetic>', 'sonnet-4-6']['sonnet-4-6']context.latest010010executions21Two consequences worth calling out:
context.latestbecomes a measured zero. A real 10,010-token context is reported as 0 because the trailing synthetic record overwrites it. This is the caseAGENTS.mdandCONTRIBUTING.mdboth name directly: "Unavailable evidence must not become a measured zero."executionsfeeds Output/execution on the Efficiency page, so a session's fragmentation signal is skewed by a record that never called a model.Cost,
cost_approx, andtotal_costare not affected — that part is already correct onmain.What changed
token_meter/runtimes/claude.py— skip a record when it has both the pseudo-model name shape (<...>) and no token evidence acrossinput_tokens,output_tokens,cache_read_input_tokens, andcache_creation_input_tokens.Requiring both conditions is deliberate: a record that does report billable tokens is still priced normally, so the guard cannot silently hide real usage. The guard sits before the
input_complete/output_completetracking so a non-execution cannot degrade completeness flags either.Tests
I extended the existing
test_claude_summary_ignores_zero_usage_synthetic_marker_for_cost_coveragewith the model, context, and sample assertions rather than adding a near-duplicate test, plus two new cases:test_claude_recompute_keeps_cost_available_with_synthetic_records— covers therecomputepath and the execution count.test_claude_summary_prices_pseudo_model_records_that_report_tokens— asserts a pseudo-model record that does carry tokens is still priced. This one passes both before and after; it is a regression guard on the guard's scope, not a bug demonstration.Verified red-to-green by running the updated test file against unmodified
main:Both pass with the fix.
Note on fixtures: the cache fixtures in the touched tests gained the
cache_creationephemeral_5m/1hbreakdown. Without it, duration-aware normalization correctly reports cost as unavailable, which masked what these tests were meant to assert. Token totals are unchanged.Validation
Installed runtime (macOS 15.6,
./scripts/install):/health→ok: true,state_ready: true,inventory_ready: true, 69 sources, noruntime_adapter_failures/menubar→ valid compact payloadcom.token-meter.serverandcom.token-meter.menubarboth running, exit status 0token_meter/runtimes/claude.pyLimitations
main, unrelated to this change:PiDocumentationTests.test_docs_explain_pi_evidence_and_privacy_boundariesasserts"Pi coding-agent sessions"appears inREADME.md, but that content now lives inspecs/USER_GUIDE.md. Reproduced on a cleanmaincheckout before these edits. Left untouched to keep this PR focused — happy to open a separate issue or fix it.