Parent: #475
π What
The models breakdown panel (m) shows a <synthetic> row that contributes nothing:
Fable 5 $690 3M 39% β Opus 4.7 $22 167k 1%
Opus 5 $461 2M 26% Haiku 4.5 $15 637k 1%
Opus 4.8 $433 4M 25% <synthetic> $0 0 0%
Sonnet 5 $126 3M 7%
<synthetic> is Claude Code's own marker for assistant turns produced locally rather than by an API call. ccpulse records it verbatim β pkg/parse writes model straight from the JSONL envelope with no validation, and the only references in this repo are test fixtures.
Measured against a real state.db:
| rows |
input |
output |
cache read |
cache write |
cost |
pricing_unknown |
| 153 |
0 |
0 |
0 |
0 |
$0.00 |
153 |
Every row is zero across the board, and it is the only model in that cache with zero I/O tokens. It occupies a cell in a panel whose cells are a scarce resource (the box collapses the tail to "β¦N more").
π― Proposed rule
Not "drop <synthetic>" β hardcoding a magic id is the tabulation pkg/models deliberately avoided, and it would go stale the moment Claude Code introduces another marker.
Instead: drop canonical rows that contribute zero tokens AND zero cost.
πΉ Removes <synthetic> today, and any future zero-contribution marker automatically
πΉ Keeps genuinely unpriced-but-used models (gpt-oss:20b, β¦) visible at $0 β that was the point of the original "unpriced models are kept, not dropped" rule, whose stated premise is "they carry real token counts". <synthetic> fails that premise.
πΉ Leaves the (unknown model) bucket alone when it carries tokens; an empty-model row with real usage still shows, still forced last.
π Why this cannot break panel reconciliation
The invariant that makes p and m agree is that both aggregates sum the same rows over the same window. Dropped rows sum to zero by construction, so neither the cost total nor the token total moves. ProjectAggregates needs no matching change β it would still be summing the same zeros.
β οΈ Implementation note β CORRECTED
The original rationale in this issue was wrong. It claimed the filter must run post-fold because "filtering pre-fold could drop a zero-token dated variant that should have merged into a non-zero canonical row." That is mathematically impossible for a SUM aggregate: a raw row contributing (0 tokens, $0) cannot change whether its canonical group is non-zero. A 400-fixture randomized differential found zero cases in the claimed direction.
The real difference, and the only observable one: post-fold placement is strictly more aggressive. It additionally drops canonical groups whose raw rows cancel to zero β e.g. a model with +1000/-1000 tokens and +$5.00/-$5.00, which reaches (0, 0) from non-zero inputs and disappears from the panel.
That cancellation behaviour is the deliberate choice (such a row contributes zero to every total, and mixed-sign token counts are already malformed input), and it is the only thing a test can use to pin the placement β a "zero-token dated variant" fixture passes under both placements, which is itself the proof the original rationale was false.
π§ͺ Acceptance
β
A window containing only zero-contribution rows renders the existing no activity in this window placeholder
β
Reconciliation test still passes β totals identical before and after
β
A model with zero cost but non-zero tokens is still shown
β
Reverting the filter makes the new test fail
Parent: #475
π What
The models breakdown panel (
m) shows a<synthetic>row that contributes nothing:<synthetic>is Claude Code's own marker for assistant turns produced locally rather than by an API call. ccpulse records it verbatim βpkg/parsewritesmodelstraight from the JSONL envelope with no validation, and the only references in this repo are test fixtures.Measured against a real
state.db:Every row is zero across the board, and it is the only model in that cache with zero I/O tokens. It occupies a cell in a panel whose cells are a scarce resource (the box collapses the tail to "β¦N more").
π― Proposed rule
Not "drop
<synthetic>" β hardcoding a magic id is the tabulationpkg/modelsdeliberately avoided, and it would go stale the moment Claude Code introduces another marker.Instead: drop canonical rows that contribute zero tokens AND zero cost.
πΉ Removes
<synthetic>today, and any future zero-contribution marker automaticallyπΉ Keeps genuinely unpriced-but-used models (
gpt-oss:20b, β¦) visible at$0β that was the point of the original "unpriced models are kept, not dropped" rule, whose stated premise is "they carry real token counts".<synthetic>fails that premise.πΉ Leaves the
(unknown model)bucket alone when it carries tokens; an empty-model row with real usage still shows, still forced last.π Why this cannot break panel reconciliation
The invariant that makes
pandmagree is that both aggregates sum the same rows over the same window. Dropped rows sum to zero by construction, so neither the cost total nor the token total moves.ProjectAggregatesneeds no matching change β it would still be summing the same zeros.The real difference, and the only observable one: post-fold placement is strictly more aggressive. It additionally drops canonical groups whose raw rows cancel to zero β e.g. a model with
+1000/-1000tokens and+$5.00/-$5.00, which reaches(0, 0)from non-zero inputs and disappears from the panel.That cancellation behaviour is the deliberate choice (such a row contributes zero to every total, and mixed-sign token counts are already malformed input), and it is the only thing a test can use to pin the placement β a "zero-token dated variant" fixture passes under both placements, which is itself the proof the original rationale was false.
π§ͺ Acceptance
β A window containing only zero-contribution rows renders the existing
no activity in this windowplaceholderβ Reconciliation test still passes β totals identical before and after
β A model with zero cost but non-zero tokens is still shown
β Reverting the filter makes the new test fail