Summary
TokenTracker massively overcounts Codex Cache Read when a subagent rollout file contains the parent thread history copied by a thread_spawn fork.
This is separate from the local dashboard refresh problem in #67. Refreshing more reliably makes the inflated number visible sooner, but does not correct the accounting.
Observed behavior
A single multi-agent workflow produced six subagent rollout files. Each file replayed roughly 4,300 parent token_count records before the child actually began.
Sanitized evidence from one local-only investigation:
| Measurement |
Value |
| TokenTracker reported cached input |
3,286,382,336 |
| Corrected estimate after excluding fork replay |
27,568,640 |
| Approximate inflation |
120x |
| Replayed cached tokens across six child files |
3,295,807,232 |
| Share caused by replayed history |
99.17% |
Root cause
A spawned Codex subagent rollout begins with:
session_meta.payload.source.subagent.thread_spawn
The file then contains copied parent history, followed by a deterministic boundary:
inter_agent_communication_metadata
TokenTracker's rollout parser currently accepts and accumulates every token_count record. It does not inspect session_meta.source.subagent.thread_spawn, and its prefilter skips inter_agent_communication_metadata. As a result, copied parent counters are treated as newly consumed tokens in every child file.
In all six inspected rollouts, every replayed parent token_count record was before the boundary and every genuine child record was after it.
Expected behavior
For a rollout identified as a subagent thread_spawn:
- Do not ingest replayed parent
token_count history.
- Begin accounting only after
inter_agent_communication_metadata.
- Reset the cumulative-token baseline at that boundary.
- If the boundary is not present yet because the file is partially written, fail closed: do not ingest replay and do not advance the cursor beyond data that can be safely retried.
- Continue handling ordinary non-subagent rollouts exactly as today.
Avoid time-based heuristics; the rollout provides explicit structural markers.
Suggested implementation
- Detect
session_meta.payload.source.subagent.thread_spawn at the start of a rollout.
- Preserve the boundary record in the initial line prefilter so the parser can switch from replay mode to child mode.
- Reset per-file cumulative totals after the boundary.
- Add regression fixtures for:
- normal rollout;
- complete subagent fork;
- partially written fork without boundary;
- resumed parse after the boundary appears;
- multiple subagents forked from the same parent.
- Add an idempotent one-time migration/rebuild for affected Codex queue and project aggregates so already-inflated local history is corrected without altering other providers.
Privacy and deployment requirement
The fix, migration, tests, and normal operation must remain strictly local-only. No rollout contents, token records, project metadata, telemetry, diagnostics, or derived usage data may be sent to any cloud or third-party service.
Acceptance tests should include a no-network run that proves parsing and migration complete using only local files and local storage.
Workaround vs. fix
Reducing the context passed to subagents (fork_turns=none or a small explicit number plus a compact brief) reduces actual token usage. However, TokenTracker still needs this parser fix because existing and future forked rollout files must be accounted for correctly.
Summary
TokenTracker massively overcounts Codex Cache Read when a subagent rollout file contains the parent thread history copied by a
thread_spawnfork.This is separate from the local dashboard refresh problem in #67. Refreshing more reliably makes the inflated number visible sooner, but does not correct the accounting.
Observed behavior
A single multi-agent workflow produced six subagent rollout files. Each file replayed roughly 4,300 parent
token_countrecords before the child actually began.Sanitized evidence from one local-only investigation:
Root cause
A spawned Codex subagent rollout begins with:
The file then contains copied parent history, followed by a deterministic boundary:
TokenTracker's rollout parser currently accepts and accumulates every
token_countrecord. It does not inspectsession_meta.source.subagent.thread_spawn, and its prefilter skipsinter_agent_communication_metadata. As a result, copied parent counters are treated as newly consumed tokens in every child file.In all six inspected rollouts, every replayed parent
token_countrecord was before the boundary and every genuine child record was after it.Expected behavior
For a rollout identified as a subagent
thread_spawn:token_counthistory.inter_agent_communication_metadata.Avoid time-based heuristics; the rollout provides explicit structural markers.
Suggested implementation
session_meta.payload.source.subagent.thread_spawnat the start of a rollout.Privacy and deployment requirement
The fix, migration, tests, and normal operation must remain strictly local-only. No rollout contents, token records, project metadata, telemetry, diagnostics, or derived usage data may be sent to any cloud or third-party service.
Acceptance tests should include a no-network run that proves parsing and migration complete using only local files and local storage.
Workaround vs. fix
Reducing the context passed to subagents (
fork_turns=noneor a small explicit number plus a compact brief) reduces actual token usage. However, TokenTracker still needs this parser fix because existing and future forked rollout files must be accounted for correctly.