fix(usage): count initial Codex requests with inherited totals#23729

merged1
main
GitHub fork: pixpmusic/fix-codex-initial-counter-baseline
opened19d agobyAAlex
View on GitHubTwo-way sync enabledPR last imported 19d ago

Problem

Codex fork/subagent rollouts and paginated continuations can start with inherited cumulative usage but no local counter snapshot. The parser treats that missing baseline as zero, rejects the first real request, and reports a skipped record. Reproduced on current main in 11 fork/subagent rollouts and one continuation, including after #22558.

The inherited totals are real history: each local cumulative - last matches a parent snapshot. The continuation's metadata references an earlier history boundary; its remainder matches that boundary, and its per-response usage record confirms the latest request. Codex also restores usage from inherited history.

Change

When no baseline exists, validate cumulative - last with the existing six-counter schema and bill only last. Keep exact delta validation once a baseline exists, including copied fork snapshots and legacy requests. Existing fork-copy suppression, stale-snapshot deduplication, compaction/reset behavior and tier attribution stay in place.

Cache v9 reparses v8 Codex entries with skipped records so unchanged files recover too. Clean v8 entries retain their incremental positions; older migrations, deleted-rollout history and old cache files are preserved. Previously omitted requests cannot be recovered from deleted transcripts.

Scope and approval

Small, focused correction to existing usage reconciliation and its cached results. No product defaults, contracts or UI changes; the backend serves web, desktop and mobile across connection modes. Based directly on main, independent of #23411. #22392 addresses replay of a known sequence's first snapshot, a separate case; this does not incorporate that PR.

Verification

  • New continuation/fork/subagent regressions failed on main (null instead of the latest request). Reader-tail regressions and the v8 invalidation regression also failed before the fix.
  • TMPDIR=/private/tmp vp run check:changed: passes format, lint, knip, GraphQL generation checks, affected typechecks and all 88 tests across four files. Canonical TMPDIR avoids existing macOS /var versus /private/var test-path mismatches.
  • Tests cover invalid inherited counter remainders, duplicate snapshots, following exact deltas, buffered/streaming parsing, persisted resume, unterminated tails, tiers, unchanged-file cache repair, clean-cache resume and deleted history.
  • Read-only replay of all 12 original transcripts through the actual reducer and both reader modes:
text
1main: 337 accepted, 12 skipped
2branch: 349 accepted, 0 skipped
3Exactly 12 latest requests recovered: 632,899 input + output tokens.
4All 337 previously accepted records unchanged; inherited totals excluded.

Personal transcripts and investigation artifacts remain outside the repository. No live app/browser verification; this is a server parser/cache fix.

Model: GPT-6.1 Sol | Harness: Codex in T3 Code

Checks

22 successful · 10 skipped · 1 neutral
All checks passed
e822931

Added 1 commit

  • fix(usage): count initial Codex requests with inherited totalse822931
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This production change alters Codex token-usage reconciliation and cache recovery, causing previously skipped requests to appear in usage totals. Because it directly affects metering, the change warrants human review.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between f05599504ae10c395a6a39f5e7db31b7810ac239 and e8229311ba4996dee8cccae94f7947126c0a4dce.

📒 Files selected for processing: 6
  • apps/server/src/provider/Drivers/codexUsage.test.ts
  • apps/server/src/provider/Drivers/codexUsage.ts
  • apps/server/src/usage/UsageService.test.ts
  • apps/server/src/usage/usageScanCache.test.ts
  • apps/server/src/usage/usageScanCache.ts
  • apps/server/src/usage/usageTranscriptReader.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

📝 Walkthrough

Codex cumulative usage reconciliation now validates an initial inherited prefix and handles valid first-request usage. The usage scan cache advances to version 9, with migration behavior for malformed and clean version 8 Codex entries.

Changes: Codex usage handling

Layer / File(s)Summary
Cumulative usage reconciliation
apps/server/src/provider/Drivers/codexUsage.ts, apps/server/src/provider/Drivers/codexUsage.test.ts, apps/server/src/usage/usageTranscriptReader.test.ts
Reconciliation validates the unseen prefix when no prior cumulative snapshot exists. Tests cover first-request billing, invalid inherited baselines, and buffered and streaming transcript resume behavior.
Usage scan cache v9
apps/server/src/usage/usageScanCache.ts, apps/server/src/usage/usageScanCache.test.ts, apps/server/src/usage/UsageService.test.ts
The cache version advances to 9. Malformed version 8 Codex entries receive legacy reset handling, while clean version 8 entries remain eligible to resume. Upgrade tests cover versions 4 through 8.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Possibly related PRs

  • pingdotgg/t3code#21863: Introduced the Codex cumulative-counter validation and malformed-record tracking that this change extends.

Suggested reviewers: t3dotgg, juliusmarminge

Merge Risk: ⚪ Minimal · up to e8229

The cache migration preserves the reparse path needed to recover skipped Codex requests. No merge-blocking issue remains identified; merge after normal checks.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely identifies the usage fix: counting initial Codex requests with inherited totals.
Description checkPassedThe description covers the problem, change, scope justification, approval rationale, focused verification, test results, limitations, and agent details. It is complete and aligned with the repository …
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description covers the problem, change, scope justification, approval rationale, focused verification, test results, limitations, and agent details. It is complete and aligned with the repository template.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.