fix(server): include archived Codex sessions in usage#22774

draft5
main
fix/issue-7090
opened9d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 7d ago

Codex transcripts archived before the first usage scan are omitted from Usage. This addresses #7090 (GitCafe #7090).

On main 6490a9e874, the running app reports 480 tokens for two active transcripts and 120 tokens from the identical uncached fixture with one transcript archived. Warm scan history preserves previously scanned usage and masks the omission. Reproduction transcript.

Status: fix, regression tests and before/after proof are done. Both independent reviews returned FIX_FIRST: the committed evidence scripts under apps/server/scripts/evidence/ and their knip.jsonc entry must be dropped before merge. Scope: include archived_sessions in the Codex transcript reader; no client or wire changes.

Validation: two regression cases fail on main (120 vs 480; 0 vs 360). Scoped lint, formatting, server typecheck passed.

Unverified surfaces: desktop, mobile, remote/relay/tunnel clients; shared server behavior is the intended fix.

Model/harness: GPT-6.1-Sol through Codex in T3 Code; delegated review models recorded when complete.

Evidence

Runtime proof against a real server (server.getUsageSummary, awaitRefresh: true). Each row ran with a fresh isolated T3 home and server process, using a synthetic CODEX_HOME fixture. Codex itself was never run, and no real ~/.codex or ~/.t3 was touched. Driver and fixture builder: apps/server/scripts/evidence/codex-archived-usage/. Matrix: matrix.md. Transcript: transcript.txt.

Before = 6490a9e874 (merge-base on main). After = 0ce8d72485 (the fix merged with main), driven from 74be12a8e6, which adds only the evidence scripts. The same committed driver ran both sides. Synthetic fixtures: active rollout a = 120 tokens and archived rollout b = 360 tokens, with distinct session IDs.

RowSynthetic fixtureBefore (tokens / sessions)After (tokens / sessions)
Aactive only120 / 1120 / 1
Bactive + archived120 / 1 (archived dropped)480 / 2
Carchived only0 / 0360 / 1
D1B + archived record with inconsistent totals120 / 1480 / 2, archived source partial (1 malformed record skipped)
D2B + archived file holding truncated JSON120 / 1480 / 2, archived source ok (1 file skipped)
D3B + unreadable archived file (chmod 000)120 / 1480 / 2, archived source partial ("1 transcript path(s) could not be read")
D4B + unreadable archived subdirectory (chmod 000)120 / 1480 / 2, archived source partial (same message)

No call returned an error, and the server stayed up after every call on both sides.

Environment: fs-17, Linux 6.1.102 x64, Node v24.22.1, server started via node apps/server/src/bin.ts start (desktop bootstrap), Codex instance disabled and pointed at the fixture, HOME set to a scratch directory.

What else changed:

  • After reports a second Codex usage source, archived_sessions, in every row; Before reports only sessions.
  • Row A: the new source shows missing ("No transcript directory on this environment."), and totals are unchanged.
  • D1, D3 and D4 surface a partial warning on the archived source. D2 stays ok because invalid JSON lines are dropped without being counted as malformed (existing parser behavior). The locked 999-token rollout in D3 and D4 is excluded from totals.
  • The sessions source is identical on both sides in every row.
  • Unrelated and identical on both sides: one "Resource telemetry operation 'refresh' failed" warning per server log, and GET / returns 503 because no web bundle was built.
Verification log
  • Proof audit pass 1 (Claude Opus 5.5): derived the matrix above, rows A–D4.

  • Evidence capture (Claude Opus 5.5): captured all 14 Before/After runs, and every one matched the expected values.

  • Proof audit pass 2 (Claude Opus 5.5): SUFFICIENT.

    • The transcript, raw results and matrix agree row by row.
    • All SHAs match.
    • 0ce8d72485..74be12a8e6 touches only the evidence scripts, and the only non-test change against main is the codexUsage.ts hunk.
    • The auditor rebuilt all After rows and the B and C Before rows from the committed driver, with identical results.
  • Main was merged in with a merge commit (0ce8d72485), with no rebase and no force-push.

  • Tests on the merged head: vp test run src/usage/UsageService.test.ts passed 40/40, and src/provider/Drivers/codexUsage.test.ts passed 17/17.

  • CI: on the previous head, Lint and Check failed. Locally, knip:check flagged the new evidence driver as an unused file. 1f7e43b7aa registers it as a knip entry; knip:check and scoped fmt/lint now pass locally. CI on 1f7e43b7aa is pending.

  • Unverified rows: none from the matrix. The optional warm-scan-cache row was not captured; the PR's reproduction transcript covers it. Desktop, mobile and remote clients were not exercised; this is a server-only change with no wire changes.

  • Model/harness: Claude Opus 5.5 through Claude Code in T3 Code (evidence lead, auditors and capturer).

  • Independent review round 1 on 1f7e43b7aa (read-only, diff excluding evidence scripts and knip.jsonc):

    • Reviewer A (Claude Sonnet 5.5): FIX_FIRST.
    • Reviewer B (Claude Opus 5.5): FIX_FIRST.
    • Both found the codexUsage.ts change to be the smallest correct fix.
    • Both traced the edge cases and found them safe:
      • A session moved or copied from sessions/ to archived_sessions/ is counted once (sharedSessionsAcrossFiles plus the global aggregator dedupe).
      • A missing archived_sessions folder reports as missing and nothing visible changes.
      • Malformed or unreadable archived files go through the existing partial handling.
      • A symlinked archived_sessions folder is resolved with realPath and deduped.
      • No change to auth, permissions, runtime modes, sandboxing, trust or the MCP surface.
    • Performance: each refresh costs one readdir plus a stat per archived file. Files older than the window are never read, and archiving keeps mtime, so a newly archived file is re-read only once.
    • Blocking finding (both): 74be12a8e6 and 1f7e43b7aa commit the PR-only evidence driver (apps/server/scripts/evidence/codex-archived-usage/) and its knip entry. AGENTS.md says not to commit PR-only assets. Fix: drop both and keep the uploaded evidence links.
    • Nits (low): no test moves a session from sessions/ to archived_sessions/ between two scans. Every Codex instance now reports one extra source, missing when the folder is absent.
    • Neither reviewer ran tests: the review worktree had no node_modules, and installing was out of scope.
    • Model/harness: Claude Opus 5.5 through Claude Code in T3 Code (review lead).

Fixes #7090 GitCafe: https://git.cafe/pingdotgg/t3code/issues/7090

Checks

22 successful · 9 skipped
All checks passed
1f7e43b

Added 2 commits

  • test(server): add takeover tests for archived Codex usagea10d146
  • fix(server): include archived Codex sessions in usageb0dec57
Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire4.9 KiB5.0 KiB+30 B (+0.6%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB+30 B (+2.5%)2.0 KiB✅
CodexLive turn WebSocket decoded20.8 KiB20.9 KiB+41 B (+0.2%)29.3 KiB✅
CodexLive turn messages12+1 (+100.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB+7 B (+0.1%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB+7 B (+0.6%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: 8d3b061 · PR result: 1f7e43b · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Added 3 commits

  • Merge main into fix/issue-70900ce8d72
  • test(server): add archived Codex usage evidence driver74be12a
  • chore(server): register codex usage evidence driver as a knip entry1f7e43b