Description
Claude Code writes one record per message with a parentUuid chain. A turn is a walk from a user prompt to the next stop_reason of end_turn, and there is no explicit turn id anywhere.
message.usage is finer than anything the native exporter emits: thinking tokens, the 1h versus 5m ephemeral cache split, and a per-iteration breakdown inside one response.
Acceptance Criteria
- #1 Reconstructs sessions and turns from the parentUuid chain and promptId, with isSidechain turns attributed to their agentId
- #2 Populates Usage including reasoning/thinking tokens and the CacheWrite5m and CacheWrite1h split
- #3 Carries model, effort, permissionMode, entrypoint, version, cwd, gitBranch and the attribution fields
- #4 stop_reason and service_tier reach the model as bounded values
- #5 usage.iterations is decoded or its omission is recorded as deliberate in docs/transcript-formats.md
- #6 Table-driven tests over synthesised fixtures; no real transcript is committed
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 sessions, turns, usage including iterations and cache splits, attribution, and bounded fields decode from synthetic fixtures; corpus gate passed.