Description
cost-state is the only real USD figure either format carries and it also gives lines added and removed. It is cumulative for the session and present in only a minority of sessions, so treating it as a summable counter overcounts and treating its absence as zero undercounts.
Model keys can carry a context-window suffix such as a 1m marker, so the key does not always equal message.model.
Acceptance Criteria
- #1 cost-state populates model.Cost as a last-value observation, never summed across records
- #2 hasUnknownModelCost is carried through as Cost.Incomplete
- #3 Model keys are normalised so a context-window suffix does not create a second model
- #4 system:compact_boundary populates a compaction item with trigger, pre/post tokens, dropped tokens and duration
- #5 isApiErrorMessage, apiErrorStatus, system:api_error and system:model_fallback produce error items with a bounded kind and status class
- #6 A session with no cost-state emits no cost, rather than zero
Definition of Done
- #1 just check passes: fmt-check, lint, build, test-short, probe-ci, dashboard-check and docs-links all clean
Implementation Plan
Wave 1 lane 4: write table-driven synthetic-fixture tests first, implement the Claude decoder across all documented record types, then run focused decoder tests; root integrates and runs the final gate.
Final Summary
Claude last-value cost, incomplete cost, compaction, and bounded error decoding are implemented with absent values preserved; tests passed.