testsAndMisc/python_pkg/session_autopsy
kuhyx 5ffd035c21 session-autopsy: measure turn efficiency, the dominant token cost
Cache read is charged per API round-trip on the whole conversation so far, so a
long session's cost is driven by TURN COUNT, not message length. One measured
session spent 267M cache-read against 856k output — a ratio of 290:1. The report
priced tokens but never counted the turns spending them.

Across the 263 stored transcripts this now shows 33,508 tool turns at an 8%
batching rate, of which 4,437 (13%) decided nothing: polling a counter, running
a linter, checking whether a push landed. At 606k average context re-read per
turn that is ~2.7B cache-read tokens on turns a script could have taken.

- turns.py classifies a command as poll / lint_test / vcs_check / substantive,
  deliberately conservative: state-changing commands (git commit, push) count as
  substantive even though they are scriptable, so the reported waste is a floor.
  A turn is only mechanical when EVERY command in it is.
- Batching is grouped by requestId, not by transcript line: one API response can
  span several lines, and counting per line reports every turn as single-tool
  (0% batching where the real rate is 12%).
- records.py gains TurnEfficiency (schema v3, additive — old records read as
  zeros) with derived rates written into to_dict so readers need not recompute.
- report.py gains a "Turn efficiency" section pricing each mechanical kind.
- _TurnTracker owns both the totals and the open turn, after pylint flagged
  _Accumulator over its attribute budget; _Accumulator.turns is now a property,
  so every existing caller is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 19:29:25 +02:00
..
tests session-autopsy: measure turn efficiency, the dominant token cost 2026-07-26 19:29:25 +02:00
__init__.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
__main__.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
cli.py session_autopsy: handled candidates leave the nudge; drop explain-diff 2026-07-25 18:12:38 +02:00
config.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
detectors.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
parse.py session-autopsy: measure turn efficiency, the dominant token cost 2026-07-26 19:29:25 +02:00
records.py session-autopsy: measure turn efficiency, the dominant token cost 2026-07-26 19:29:25 +02:00
report.py session-autopsy: measure turn efficiency, the dominant token cost 2026-07-26 19:29:25 +02:00
signatures.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
stats.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
store.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
traces.py python_pkg: track session_autopsy, finishing its interrupted refactor 2026-07-25 16:56:43 +02:00
turns.py session-autopsy: measure turn efficiency, the dominant token cost 2026-07-26 19:29:25 +02:00