Skip to content

fix(spend): refresh independent history after token publications - #3239

Merged
steipete merged 1 commit into
mainfrom
codex/spend-dashboard-freshness
Aug 27, 2026
Merged

fix(spend): refresh independent history after token publications#3239
steipete merged 1 commit into
mainfrom
codex/spend-dashboard-freshness

Conversation

@steipete

@steipete steipete commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Summary

Regular token-history refreshes could leave an already-populated Usage & Spend dashboard unchanged: the regular publication advanced, but the independent dashboard configuration still compared equal. Adding the regular revision alone would not fix the refresh-missing decision and could let a short menu snapshot stand in for the dashboard's year of history.

Track the regular publication incorporated by each independent 365-day scan, separately from failed attempts and authoritative dashboard data revisions. Refresh only missing/outdated independent sources, coalesce publications arriving during a suspended scan, and preserve cancellation, ownership replacement, confirmed-empty, and stale-last-known behavior. Failed automatic attempts wait for newer data, relevant configuration changes, or explicit refresh rather than spinning.

Codex account-cache/catch-up and provider-derived spend ownership stay unchanged. The token-cost logging helper moves unchanged into its existing extension; architecture catalog edits only relocate existing anchors. Docs and changelog explain the behavior. Thanks @vinschger for the investigation context.

Verification

The regression was executed against the pre-fix implementation: four assertions failed because configuration stayed unchanged, loader calls remained [365, 30] instead of [365, 30, 365], and the dashboard retained cost 12 instead of 15. It passes with this fix.

  • 418 tests across 27 suites pass, covering independent publication/provenance, forced reconciliation, scanner/cache behavior, cancellation, account-scope replacement, Codex account ownership, provider-derived projections, and architecture gates.
  • A separate 11-test freshness repeat passes. Temporary Claude JSONL append and date-boundary data exercise the real cancellable scanner and snapshot projection, persisted JSON reload after memo eviction, retained older rows, and no idle rescans.
  • make check passes with zero violations across 2,016 files; git diff --check is clean.
  • Independent Codex review of the complete patch reports no actionable P0–P2 findings.
  • Full make test exits successfully: 945 selections across 79 groups. 77 groups passed first time; one cost-scanner group exceeded its 180-second group budget and all 12 selections passed in isolation, and a Gemini fake-fnm PID-file assertion passed on its group retry. These recovered failures are recorded, not presented as a first-pass clean run; their unchanged harness paths are queued for a separate repair.
  • Exact-head CI run 33074636815 passes all eight jobs, including both macOS test shards and all three Linux builds. GitGuardian passes. No workflow rerun was needed.

Maintainer review disposition: the bot's late P3 request to remove the changelog entry is not accepted. The maintainer instructions for this work require a changelog entry for user-facing fixes, and this is a maintainer-authored fix. The one-line entry stays. No code/security finding remains accepted or unresolved.

Commands:

env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 swift test --filter 'SpendDashboard|CostUsageScannerClaudeMemoTests|CostUsageScanExecutorTests|UsageStoreManualTokenRefreshTests|ProviderArchitectureGatekeeperTests|GrokXAISpendCatalogTests|GrokTokenSnapshotProjectionTests|CodexAccountScopedRefreshTests' --skip 'SpendDashboardScreenshotRenderTests'
env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 swift test --skip-build --filter 'SpendDashboardFreshness'
env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 make check
env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 make test
git diff --check

The new freshness regressions use isolated test data; no live provider, account, browser, Keychain, or app UI proof is claimed. The broader suite exposed existing fixture-isolation gaps: some cost tests permit public pricing refreshes and default local trace/Pi paths. Those paths are unchanged by this patch and are queued for a fixture-only repair; the full-suite result is not a claim that every existing test is hermetic. There is no layout/rendering change. The new scanner clock and model projection use explicit fixture dates, not a real midnight scheduler test.

Investigated alongside #3209 and #3176, but does not close them: #3209's owner-confirmed screenshot is the regular provider-menu chart, not this independent dashboard, and its Claude root cause remains unproved. No claim to resolve #3194's quota/persistence issue or #3207's separate scanner fairness work.

@clawsweeper

clawsweeper Bot commented Aug 27, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Aug 27, 2026
@clawsweeper

clawsweeper Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codex review: needs changes before merge. Reviewed August 27, 2026, 9:25 AM ET / 13:25 UTC.

ClawSweeper review

What this changes

The PR refreshes independent 365-day Usage & Spend histories when newer regular token publications arrive, with regression tests and documentation for the separate dashboard source.

Regression provenance

Possible regression — probable (reviewed change; reproduction). No predecessor PR is attributed.

Merge readiness

⚠️ Ready for maintainer review - 2 items remain

The refresh repair is focused and well-covered, but this owner-authored PR should remain open for maintainer flow; the exact-head macOS test shards are still running.

Priority: P2
Reviewed head: 7af637a34de772d39cd2919fd08ff66216723b96

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The bounded implementation and substantial regression coverage support a normal good patch rating, with one small policy cleanup and CI completion remaining.
Proof confidence 🌊 off-meta tidepool Not applicable: The repository owner authored this PR, so the external-contributor proof gate does not apply; its body nevertheless reports isolated scanner and publication regression coverage.
Patch quality 🐚 platinum hermit (4/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: The repository owner authored this PR, so the external-contributor proof gate does not apply; its body nevertheless reports isolated scanner and publication regression coverage.
Evidence reviewed 5 items Current-main defect: The base revision refreshes only when the independent dashboard publication is absent and falls back to a regular short-window publication when it is missing, so a newer regular publication cannot refresh an already-populated 365-day history.
Refresh implementation: The PR tracks configuration, scope, and regular-publication revisions, refreshes only unincorporated triggers, and records failed automatic triggers separately to avoid retry loops.
Regression coverage: New tests cover the initial 365-day scan, a newer 30-day publication, the follow-up scan, coalescing, cancellation, owner replacement, and automatic-failure recovery.
Findings 1 actionable finding [P3] Remove the release-owned changelog entry
Security None None.

Live Verification

Command: env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 swift test --filter 'SpendDashboardFreshnessScannerTests'

Result: FAIL (failed) — execution before step 1 expect_output: sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.24.0.tgz

sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.24.0.tgz

Assertions:

  • FAIL expect_output: Test run with

How this fits together

CodexBar publishes short-window token snapshots for provider menus and separately scans local histories for the Usage & Spend dashboard. The new trigger makes the dashboard rescan its independent 365-day source after a newer regular publication.

flowchart LR
A[Local provider history] --> B[Regular token publication]
B --> C[Dashboard freshness trigger]
C --> D[Independent 365-day scan]
D --> E[Dashboard data publication]
E --> F[Usage and Spend history]
B --> G[Coalesced later update]
G --> D
Loading

Before merge

  • Remove the release-owned changelog entry (P3) - CHANGELOG.md is release-owned under repository policy, so this normal PR should leave that entry to the release process. This was visible at the prior reviewed head as well.
  • Resolve merge risk (P1) - The two exact-head macOS test shards were still in progress in the supplied PR state.

Findings

  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:6
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Code and test growth production +115, tests +681, docs/release notes +10 The production change is bounded while most additions provide freshness, failure, cancellation, and scanner coverage.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Keep the trigger-based refresh model, remove the release-owned changelog edit, and merge once the exact-head macOS shards pass.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Keep the trigger-based refresh model, remove the release-owned changelog edit, and merge once the exact-head macOS shards pass.

Do we have a high-confidence way to reproduce the issue?

Yes—current-main source shows the independent history was considered current despite a newer regular publication, and the added deterministic fixture encodes the missed 365-day rescan.

Is this the best way to solve the issue?

Yes—the trigger is separate from dashboard data revisions, preserving the existing long-history authority and avoiding the short menu snapshot as a substitute.

Full review comments:

  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:6
    CHANGELOG.md is release-owned under repository policy, so this normal PR should leave that entry to the release process. This was visible at the prior reviewed head as well.
    Confidence: 0.98
    Late finding: first raised on code an earlier review cycle already covered.

Overall correctness: patch is correct
Overall confidence: 0.94

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against d9e950e49c95.

Labels

Label justifications:

  • P2: This fixes stale dashboard spend history with a limited provider-dashboard blast radius.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The repository owner authored this PR, so the external-contributor proof gate does not apply; its body nevertheless reports isolated scanner and publication regression coverage.

Evidence

Acceptance criteria:

  • [P1] git diff --check.

What I checked:

Likely related people:

  • steipete: The PR-head commit and retained blame boundary both identify Peter Steinberger (GitHub handle steipete) on the affected spend-dashboard code. (role: current spend-dashboard implementation author and repository owner; confidence: high; commits: 7af637a34de7; files: Sources/CodexBar/SpendDashboardController.swift, Sources/CodexBar/UsageStore+SpendDashboardTokenCost.swift, Sources/CodexBar/UsageStore+SpendDashboardPublication.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Remove the release-owned CHANGELOG.md entry.
  • Wait for the two exact-head macOS test shards to pass.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-08-27T13:07:56.089Z sha 7af637a :: needs maintainer review before merge. :: none

@steipete
steipete merged commit e02e78d into main Aug 27, 2026
9 checks passed
@steipete

Copy link
Copy Markdown
Owner Author

Landed on main as e02e78d98274832305a72f4086bf4630edf83f77. Tested PR head: 7af637a34de772d39cd2919fd08ff66216723b96. Main was fast-forwarded locally and verified clean; its source tree matches the tested tree b118ebeed69beb6da4ebce1067bcd590f05c8e7d.

The original regression was executed before the fix: regular token publication advanced, but the populated independent dashboard stayed unchanged and omitted its next 365-day scan. The fix preserves full-history ownership, acknowledges only the regular revision captured before suspension, coalesces newer updates, and separates failure suppression from successful incorporation.

Verification:

  • 418 focused tests across 27 suites pass, plus a separate 11-test freshness repeat.
  • make check: zero violations across 2,016 files. git diff --check clean before commit.
  • Full make test: 945 selections across 79 groups, exit 0. 77 groups passed first time; a cost-scanner group hit its 180-second budget and all 12 selections passed in isolation, while a Gemini fake-fnm PID-file assertion passed on its group retry. Both recovered failures remain documented; the existing fixtures' network/disk/subprocess dependencies are a separate follow-up.
  • Independent Codex review of the complete patch: no actionable P0–P2 findings.
  • Exact-head CI run 33074636815: all eight jobs passed, including both macOS test shards and all three Linux builds; no workflow rerun. GitGuardian passed.

Commands executed:

env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 swift test --filter 'SpendDashboard|CostUsageScannerClaudeMemoTests|CostUsageScanExecutorTests|UsageStoreManualTokenRefreshTests|ProviderArchitectureGatekeeperTests|GrokXAISpendCatalogTests|GrokTokenSnapshotProjectionTests|CodexAccountScopedRefreshTests' --skip 'SpendDashboardScreenshotRenderTests'
env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 swift test --skip-build --filter 'SpendDashboardFreshness'
env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 make check
env -u CODEXBAR_ALLOW_TEST_KEYCHAIN_ACCESS CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1 CODEXBAR_TEST_CODEX_FILE_ISOLATION=1 make test
git diff --check

The new regressions use synthetic snapshots and temporary Claude JSONL/cache files with explicit dates, not real accounts or UI captures. The broader suite's discovered isolation gaps are not hidden by its successful retry result. The bot's package-manager setup failure occurred before Swift testing and is not a product test failure.

The late bot P3 request to remove the changelog entry was not accepted: maintainer instructions require a one-line changelog entry for this user-facing fix. No accepted code or security finding remained at merge.

No layout change, live provider/account/browser/Keychain/UI proof, real-midnight scheduler proof, or release is claimed. This does not close #3209 or #3176; the regular-menu Claude symptom still needs reporter details and a demonstrated cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Codex automatic refresh timer never fires, while OAuth usage fetch succeeds

1 participant