Repository navigation
[Bug]: Codex "Today" and "30d" show identical cost and tokens while the local scan is paused (no_progress) #755
Description
Summary
With the Codex local cost scan paused, the card shows the same cost and token count for Today and 30d, even though the cache holds separate per-day data. A value for one period appears to be returned for another.
This issue is only about the period mix-up. How cost is estimated, and why some fork parents are unresolved, are out of scope.
Environment
- Win-CodexBar 0.70.0 portable (tag
f0b45ed); the exe hash matches the release asset - Windows 11, time zone Asia/Tokyo, Codex provider
Observed facts
Displayed:
| Shown | |
|---|---|
| Today | $465.72 |
| 30d cost | $465.72 |
| 30d tokens | 677.5M |
| Latest tokens | 677.5M |
Cost cache (%LOCALAPPDATA%\CodexBar\cost-usage\codex-v1.json, schema 6):
- 2026-10-04 only: input 166,464,992 / cached input 159,182,976 / output 405,204 (166.9M input+output)
- all 27 cached days, 2026-09-05 to 2026-10-04: input 674,925,823 / cached input 649,697,927 / output 2,610,177 (677.5M input+output)
codex_scan_incomplete: true,codex_scan_pause_reason: "no_progress"codex_pending_paths: 161 entries; 160 of them havecodex_unresolved_fork_parent: true, emptydaysandparsed_bytes: 0(145 of these are markedchild, 15 have no lineage field); the remaining one has 2026-10-04 data and its file is no longer on disk- no
previous_report
The tokens shown for "Latest" equal the 30d tokens, not today's, so the mix-up is not limited to the cost. The same card's daily bar chart shows clearly different heights per day, so per-day data is present.
Manual refresh attempt (Ctrl+R / "Refresh" in the panel, once, then waited about 2.5 minutes):
- Today, 30d cost, 30d tokens and Latest tokens were unchanged
- Session / weekly usage bars did update (65% → 67%, 87% → 88%)
- the cost cache file was byte-identical afterwards (same SHA-256, same
last_scan_unix_ms);codex_pending_pathsstayed at 161,no_progressandcodex_scan_incomplete: trueunchanged
So the paused state did not recover on its own or through one manual refresh. I do not know whether that refresh requests a new cost scan or only refreshes usage limits.
Analysis from reading v0.70.0 (not confirmed at runtime)
I have not traced this with a debugger or logs. The following comes from reading the source at the tag.
commands/chart.rsscansRolling(30)andRolling(1)separately and uses the second result fortoday_costandlatest_tokens.- While paused,
scan.rscallspaused_codex_summary. reconciliation.rs: if the requested window is not "established", it returnsprevious_report, or elseJsonlScanner::cached_cost_report_from_days(cache).cached_cost_report_from_daysusesrange = None, so it sums every cached day.summary_from_cached_reportcopies those totals and only setsperiod_start/period_endto the requested range.previous_reportis one stored report with no window information, so it could be returned for a different period too (not exercised here, since none is stored).
A range-filtered builder, cached_cost_report_for_range, already exists, and the established-window branch uses it. The fallback branch does not.
Condition that leads here: codex_current_window_is_established treats a pending path as affecting the window when codex_unresolved_fork_parent is set or its days is empty. With the 160 unresolved-fork entries above, I infer that neither the Today window nor the 30d window is established. Why the parents are unresolved is not part of this report.
Expected behavior / acceptance criteria
- A value computed for one period is never returned for a different period. This covers both the all-days fallback and
previous_reportwithout matching window information. - If a partial figure is shown for a requested period (for example, only the days available in the cache for that period), the UI marks it as an incomplete scan. It must not look like a confirmed total for Today.
- If nothing can be said for the period, show "unknown" rather than a number from another period.
- Once the scan completes, the incomplete marker goes away and Today and 30d are computed from their own days.
Regression test idea: a cache with two days, one pending unresolved-fork path, no_progress pause, no previous_report. paused_codex_summary for Rolling(1) and Rolling(30) must not return the same totals, Rolling(1) must contain only the latest day, and history_coverage_established must stay false. A second case with a previous_report from a different window must not leak into Rolling(1).
Not verified
- No runtime trace; the code path is from source reading.
- No test on a fixed build.
- Whether other users with different cache states are affected.
- Whether the panel's refresh triggers an app-driven cost scan (the source suggests an app-driven scan clears the
no_progresspause, but the cache did not change here). Restarting the app and cache deletion were not tried.
Steps to reproduce
I do not have an external reproduction. This is the state I am in: Codex local cost scan paused with no_progress, 160 pending entries with unresolved fork parents, no previous_report. Open the tray panel, Codex tab, Usage details: Today and 30d show the same values. A unit-level reproduction is described under the regression test idea above.
Related
- [Bug]: ¿?¿?¿? Have the Codex graphics been lost? #616 (charts missing / $0) looks like a different symptom.
- [0.60.5] Publish validated Codex windows during historical catch-up #542 (v0.60.5, "Publish validated Codex windows during historical catch-up") introduced range-scoped cached reports; the paused fallback seems to have been left out of that scoping.
- I found no earlier report of this symptom, so I do not know whether it is a regression.
Activity
boden0002 commentedon Oct 4, 2026
Update: I pressed Settings > Usage & Spend > Refresh once and restarted the app. Today and 30d now show different values:
These match the cache (today 153.5M and all cached days 643.2M, input+output).
Cache after that:
codex_scan_pause_reasonis null, butcodex_scan_incompleteis still true andcodex_pending_pathsis 163. So the scan resumed but has not finished. The numbers changed from before (30d tokens 677.5M → 643.2M); I have not checked why.This suggests the pause is cleared by a forced rescan (the tray refresh did not do it). The fallback in
paused_codex_summaryis unchanged, so if the scan pauses withno_progressagain, Today and 30d would again receive the cache-wide total. I cannot tell whether the Refresh or the restart cleared it.