Description
response_item:custom_tool_call and event_msg:item_completed describe the same tool call. So do response_item:agent_message and event_msg:agent_message, and response_item:reasoning and the Reasoning item. Without deduplication every tool call is counted twice and nothing about the totals looks wrong.
Acceptance Criteria
- #1 Items are deduplicated on item id with item_completed preferred, because it is the only representation carrying timing
- #2 A suppressed duplicate increments dedup_drops
- #3 A response_item with no matching item_completed is still emitted, with Duration at Source absent
- #4 A test over a synthesised session proves the tool-call count matches the number of distinct calls
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 5: write table-driven tests first, implement Codex sessions/items/dedup within the frozen model, and prove duplicate representations count once; root integrates and runs the final gate.
Final Summary
Codex duplicate representations deduplicate by complete item id with completed timing preferred and drop accounting; regression tests passed.