Track cumulative annual model spend - #2469
Conversation
|
Codex review: needs changes before merge. Reviewed August 8, 2026, 1:55 AM ET / 05:55 UTC. ClawSweeper reviewWhat this changesAdds 7-, 30-, and 365-day Usage & Spend windows, fuller provider coverage disclosure, compact Overview/share summaries, and OpenRouter activity history. Merge readinessKeep open: strong native UI proof is present, but three prior correctness blockers remain on the current head. Priority: P2 Review scores
Verification
How this fits togetherProvider usage snapshots feed CodexBar’s Usage & Spend aggregation, then Settings, menu-bar Overview, widgets, and share cards. This PR expands the history data flowing through those shared consumers. flowchart LR
A[Provider snapshots] --> B[Shared cost snapshots]
B --> C[Usage and Spend dashboard]
B --> D[30-day menu and widget]
B --> E[Overview summary]
C --> F[Settings share card]
E --> G[Overview share card]
Before merge
Findings
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Copy recommended automerge instructionTechnical reviewBest possible solution: Use dashboard-local extended-history results, anchor Overview to the current time, and pass the tracked roster into the Settings share payload. Do we have a high-confidence way to reproduce the issue? Yes: select 365 days with a configured 30-day history, close the pane, and render a 30-day menu token; the stale Overview and Settings-share omissions also follow directly from current-head source. Is this the best way to solve the issue? No: the shared extended-history publication is unsafe for fixed-window consumers; dashboard-local history plus current-time anchoring and roster propagation is narrower. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 8fc67d7f04ad. LabelsLabel justifications:
EvidenceAcceptance criteria:
What I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (27 earlier review cycles; latest 8 shown)
|
1e35ae0 to
4b5b985
Compare
aad4afc to
b85cd49
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b85cd4997c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
b1ba0c7 to
cad600b
Compare
bb9d74e to
27185a6
Compare
2c8715e to
8a5b6f4
Compare
|
@clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@codex review |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dbd547ff0c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let requiredHistoryDays = self.settings.effectiveCostUsageHistoryDays | ||
| guard publication.historyDays >= requiredHistoryDays, | ||
| publication.scopeSignature == self.tokenSnapshotScopeSignature( | ||
| for: provider, | ||
| historyDays: publication.historyDays) |
There was a problem hiding this comment.
Keep dashboard history out of 30-day snapshots
When a user selects 365 days in Usage & Spend while their configured cost history is 30 days, the shared publication becomes a 365-day snapshot; after the pane closes, this >= check continues treating it as valid for 30-day consumers. menuBarLayoutCostStrings then passes last30DaysCostUSD to the .cost30d layout token, and the widget has similar 30-day presentation paths, so the annual total can be displayed as a 30-day cost until another refresh replaces it. Either isolate the dashboard's extended history or derive fixed-window values before feeding those consumers.
Useful? React with 👍 / 👎.
| snapshot: snapshot) | ||
| } | ||
| let requestedDays = self.settings.effectiveCostUsageHistoryDays | ||
| let now = inputs.map(\.snapshot.updatedAt).max() ?? Date() |
There was a problem hiding this comment.
Anchor Overview windows to the current date
When cached publications are stale, using the latest snapshot's updatedAt anchors the Overview's “last N days” window in the past rather than today. For example, an offline user with a month-old cached snapshot can still see that old period's spend presented as the current 30-day summary; the main dashboard correctly anchors retained data to the request time. Build this Overview model with the current capture time so expired entries fall outside the displayed window.
Useful? React with 👍 / 👎.
| model: SpendDashboardModel, | ||
| subscriptionNames: [String: ShareStatsSubscriptionName] = [:]) -> ShareStatsPayload? | ||
| subscriptionNames: [String: ShareStatsSubscriptionName] = [:], | ||
| providerRoster: [ShareStatsProviderRosterEntry] = []) -> ShareStatsPayload? |
There was a problem hiding this comment.
Include tracked access in the Settings share payload
When Settings → Usage & Spend shows a configured or enabled provider that has no dashboard model row—for example Gemini, Grok, or an unavailable key—the pane's ShareStatsBuilder.make call omits providerRoster, so this empty default silently drops that source from the resulting card even though the adjacent Tracked Access panel keeps it visible. Pass the pane's tracked roster into the builder so its Share Stats action preserves the full roster just as the new Overview share action does.
Useful? React with 👍 / 👎.
Summary
Makes Usage & Spend useful for a genuinely multi-provider setup while keeping incomplete data honest:
$0~$…) with reporting coverage when only some services expose cost history+Noverflow, currency separation, and reporting coverageRoot cause
Tracked Access used
enabledFirstPartyProvidersForDisplay()as its roster. That helper is intentionally filtered by refresh-time availability, so a provider disappeared exactly when auth, CLI, or provider availability needed explanation.The dashboard now derives visibility from provider enablement and continues to derive aggregation from token-cost capability plus active-account state. Overview display selection remains a presentation preference; its combined total and share payload are derived from all enabled providers.
Refs #2695, #2290, and #1674. Model canonicalization remains scoped to #2257, and month-to-date semantics remain scoped to #2087.
Native runtime proof
All values and labels below are synthetic. No real account data, keys, or usage values are included.
All-provider Overview at the production 310-point width
Local share card opened from Overview
Settings proof:
Current-head evidence
Exact head:
66dcfdc8694c07b713331828639cd751a058101a.Validation
git diff --check./Scripts/lint.sh lint-macos(22 locale catalogs and SwiftFormat green)swift build --product CodexBargreen with a temporary local compatibility shim for this Mac's missingSwiftUIMacros.EntryMacro; the shim and proof launcher were removed before commitswift testremains toolchain-indeterminate locally because the active CLI toolchain lacks the repository'sTestingmoduleScope
This PR does not claim to solve cross-provider model canonicalization (#2257) or calendar month-to-date reporting (#2087). It establishes the truthful provider roster, longer history, compact Overview, and shareable aggregate needed for those follow-ups.