Skip to content

Keep priced Cursor days when some events omit totalCents - #3005

Merged
steipete merged 4 commits into
steipete:mainfrom
Yuxin-Qiao:fix/spend-dashboard-cursor-partial-days
Aug 17, 2026
Merged

Keep priced Cursor days when some events omit totalCents#3005
steipete merged 4 commits into
steipete:mainfrom
Yuxin-Qiao:fix/spend-dashboard-cursor-partial-days

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep priced Cursor days visible even when some events omit totalCents.
  • Fix the case where one missing totalCents zeroed the whole Cursor 30-day cost.

Note

  • Privacy-sensitive screenshots were removed from this PR description.

A missing totalCents on one usage event no longer voids that day's priced siblings or the rest of the 30-day window.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper

clawsweeper Bot commented Aug 17, 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 merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 17, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0425dde33b

ℹ️ 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".

Comment on lines +893 to +895
var hasPartialCost: Bool {
let values = self.providers.map(\.totalCost)
return values.contains { $0 != nil } && values.contains { $0 == nil }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark retained Cursor subtotals as partial

When a Cursor subscription contains both priced and unpriced events, its retained subtotal is non-nil, so a group containing only that subscription makes this predicate return false. The dashboard consequently renders the lower-bound subtotal without the new ~ prefix or “Partial estimate” caption, and shared currency totals are likewise marked complete. Track partiality within each provider, not only the presence of an entirely unpriced provider.

Useful? React with 👍 / 👎.

dailyPoints: dailyPoints,
totalTokens: Self.completeIntSum(providers.map(\.totalTokens)),
totalCost: Self.completeCostSum(providers.map(\.totalCost)),
totalTokens: Self.knownIntSum(providers.map(\.totalTokens)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Label partial token totals before exposing known-only sums

When one same-currency provider has invalid or unavailable token history and a peer has a valid count, this now produces only the known lower bound. Although hasPartialTokens is computed, neither the dashboard's “Tracked tokens” value nor the share card/text uses it, so both present that lower bound as an exact total. Keep the aggregate unavailable or propagate token partiality into every renderer before returning the known-only sum.

Useful? React with 👍 / 👎.

Comment on lines 537 to 541
static func checkedKnownCostSum(_ lhsUSD: Double?, _ rhsCents: Double?) -> Double? {
guard let rhsCents else { return lhsUSD }
guard rhsCents >= 0 else { return nil }
let sum = (lhsUSD ?? 0) + rhsCents / 100.0
return sum.isFinite ? sum : nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve invalid cost state across later Cursor events

If an event has a negative totalCents, or a prior addition overflows, this helper returns nil; a subsequent priced event then treats that same nil as an empty accumulator via lhsUSD ?? 0 and publishes only the later cost. Thus malformed input can produce an order-dependent, apparently valid subtotal instead of failing closed. Distinguish “no priced event yet” from an accumulator invalidated by bad data or overflow.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 17, 2026, 10:18 AM ET / 14:18 UTC.

ClawSweeper review

What this changes

The PR preserves known Cursor costs when sibling events omit totalCents, while keeping invalid price data unavailable.

Merge readiness

Blocked until stronger real behavior proof is added - 5 items remain

Keep open: malformed Cursor prices can still be mistaken for intentionally omitted prices when they occur in a different model, so the dashboard may publish a lower-bound cost despite the PR’s fail-closed intent. The supplied screenshot also does not show the requested Cursor mixed-event behavior after the fix.

Priority: P2
Reviewed head: 9f5d9f7f5173c222e1395bdcf45624824d4ec751

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The patch has useful focused coverage but a cross-model correctness hole and insufficient real behavior proof.
Proof confidence 🦪 silver shellfish (2/6) Needs stronger real behavior proof before merge: Focused tests and a stacked-branch dashboard screenshot support the intent, but the inspected screenshot shows Codex and Claude rather than the PR’s mixed Cursor-event behavior; add redacted after-fix runtime evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦐 gold shrimp (3/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs stronger real behavior proof before merge: Focused tests and a stacked-branch dashboard screenshot support the intent, but the inspected screenshot shows Codex and Claude rather than the PR’s mixed Cursor-event behavior; add redacted after-fix runtime evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 7 items Malformed state is only model-local: The new accumulator latches invalid cents per model, but that state is not carried into the day-level reducer.
Day reducer drops malformed provenance: A nil cost from an invalid model is treated the same as an omitted price: a priced sibling model therefore produces a non-nil day total.
Dashboard accepts the misleading subtotal: For a non-nil daily cost, validation compares only the aggregate daily total with the snapshot total; it does not inspect whether a model’s nil cost came from malformed input.
Findings 1 actionable finding [P2] Propagate invalid Cursor state across models
Security None None.

How this fits together

CodexBar aggregates Cursor usage events into per-model and per-day cost reports, then validates those reports before showing spend totals in Usage & Spend. The new Cursor logic affects whether a daily cost becomes an available or partial dashboard value.

flowchart LR
A[Cursor usage events] --> B[Per-model aggregation]
B --> C[Daily report]
C --> D[Dashboard history validation]
D --> E[Usage and Spend totals]
Loading

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: Focused tests and a stacked-branch dashboard screenshot support the intent, but the inspected screenshot shows Codex and Claude rather than the PR’s mixed Cursor-event behavior; add redacted after-fix runtime evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Propagate invalid Cursor state across models (P2) - The new costInvalid latch only lives in each model accumulator. When another model has a valid price, the day reducer treats the invalid model’s nil exactly like an intentionally omitted price and publishes the priced sibling subtotal; dashboard validation then accepts it. Carry invalid provenance into the day/summary reduction and add a two-model negative-cents regression so malformed input remains fail-closed.
  • Resolve merge risk (P1) - Merging can show a Cursor spend subtotal when a malformed totalCents in another model should make that day unavailable.
  • Resolve merge risk (P1) - The supplied screenshot does not establish after-fix behavior for the mixed Cursor-event case, so real behavior proof remains required before merge.
  • Complete next step (P2) - The invalid-provenance repair and regression are mechanical, though the contributor must separately supply real behavior proof.

Findings

  • [P2] Propagate invalid Cursor state across models — Sources/CodexBarCore/Providers/Cursor/CursorUsageEventsFetcher.swift:512-515
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production versus test delta production +56/-3, tests +140/-1 The focused regression coverage is substantial, but it currently omits the mixed-model invalid-price path.

Merge-risk options

Maintainer options:

  1. Propagate malformed-price state (recommended)
    Keep a day and its summary unavailable when any Cursor model has invalid cents, while retaining the omission-only behavior, and add a mixed-model regression.
  2. Pause for a narrower resend
    If invalid and omitted pricing cannot remain distinct in the current report model, pause this branch and redesign that provenance boundary before merging.

Technical review

Best possible solution:

Carry invalid Cursor-price provenance through daily and summary aggregation, add a mixed-model regression, then provide redacted after-fix runtime evidence for a Cursor history containing both priced and omitted events.

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

Yes, source establishes a deterministic fixture: put negative or non-finite cents in one Cursor model and a valid price in another on the same day; the reducer retains the valid model’s day total.

Is this the best way to solve the issue?

No; the same-model latch is correct, but invalidity must also survive the cross-model day and summary reductions before omitted prices may be retained.

Full review comments:

  • [P2] Propagate invalid Cursor state across models — Sources/CodexBarCore/Providers/Cursor/CursorUsageEventsFetcher.swift:512-515
    The new costInvalid latch only lives in each model accumulator. When another model has a valid price, the day reducer treats the invalid model’s nil exactly like an intentionally omitted price and publishes the priced sibling subtotal; dashboard validation then accepts it. Carry invalid provenance into the day/summary reduction and add a two-model negative-cents regression so malformed input remains fail-closed.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P2: The issue can misstate a provider’s spend estimate but is limited to Cursor cost reporting.
  • merge-risk: 🚨 compatibility: Existing Cursor histories containing malformed price events could change from unavailable spend to a misleading lower-bound total.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: Focused tests and a stacked-branch dashboard screenshot support the intent, but the inspected screenshot shows Codex and Claude rather than the PR’s mixed Cursor-event behavior; add redacted after-fix runtime evidence before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. Focused tests and a stacked-branch dashboard screenshot support the intent, but the inspected screenshot shows Codex and Claude rather than the PR’s mixed Cursor-event behavior; add redacted after-fix runtime evidence before merge.

Evidence

Acceptance criteria:

  • [P1] swift test --filter CursorUsageEventsFetcherTests.
  • [P1] swift test --filter SpendDashboardPartialCostTests.
  • [P1] make test.
  • [P1] make check.

What I checked:

Likely related people:

  • Ethan Clinick: Introduced the Cursor token-cost report and followed up on its event parsing and day grouping. (role: Cursor report introducer; confidence: high; commits: 2209a9b63945, 8f650d9b6cfe; files: Sources/CodexBarCore/Providers/Cursor/CursorUsageEventsFetcher.swift)
  • steipete: Recent history includes spend-dashboard compatibility and architecture-gate updates on the affected dashboard surface. (role: recent dashboard contributor; confidence: high; commits: 6407d3ce3346, af4430df5d7d; files: Sources/CodexBar/SpendDashboardModel.swift, Sources/CodexBar/SpendDashboardModel+ModelBreakdown.swift)
  • Yuxin-Qiao: Prior merged dashboard work covers partial spend totals and the all-time spend view adjacent to this change. (role: recent dashboard contributor; confidence: high; commits: c9f3bf729154, 0b0279c6eba2; files: Sources/CodexBar/SpendDashboardModel.swift, Sources/CodexBar/SpendDashboardModel+ModelBreakdown.swift)

Rank-up moves

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

  • Propagate malformed-price state through model, day, and summary reductions with a mixed-model regression.
  • Add redacted after-fix runtime proof that visibly exercises Cursor priced and omitted totalCents events; update the PR body to trigger re-review.

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 (3 earlier review cycles)
  • reviewed 2026-08-17T07:16:14.812Z sha 0425dde :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-17T08:24:21.683Z sha 0425dde :: needs real behavior proof before merge. :: [P2] Preserve invalid Cursor accumulator state | [P2] Mark retained Cursor subtotals as partial | [P2] Label known-only token totals before rendering
  • reviewed 2026-08-17T11:42:30.689Z sha f6395d0 :: needs real behavior proof before merge. :: none

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

After-fix proof

Did not dump live Cursor usage events (cookie/keychain). The dashboard failure mode was: one event missing totalCents made the day/window cost nil, which then fail-closed the whole USD group before #3001.

Focused tests on 0425dde33 (39 tests, CursorUsageEventsFetcherTests + SpendDashboardPartialCostTests), including:

  • reports keep priced cents when a sibling event omits total cents
  • reports keep priced days when another day omits total cents
  • established Cursor history retains priced days when some events omit total cents
  • established Cursor history keeps priced days when another day omits cost
  • unestablished Cursor history with an unresolved day keeps spend unavailable

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Aug 17, 2026
A negative totalCents now latches the accumulator closed so a later priced sibling cannot restore a lower-bound dollar total.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao

Yuxin-Qiao commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

After-fix proof

f6395d05b keeps priced sibling events when totalCents is omitted, and latches a model closed after negative cents so a later priced event cannot restore $1.00 + $0.50.

Focused: reports keep priced cents when a sibling event omits total cents and reports do not revive a model cost after an invalid cents event passed.

Live Cursor cookies were not read. Dashboard partial-group presentation is on the #3001/#3009 stack:

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6395d05b6

ℹ️ 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".

cacheCreationTokens = ModelAccumulator.checkedSum([cacheCreationTokens, accumulator.cacheCreationTokens])
requestCount = ModelAccumulator.checkedSum([requestCount, accumulator.requestCount])
costUSD = Self.checkedUSDTotal(costUSD, accumulator.costUSD)
costUSD = Self.checkedKnownUSDTotal(costUSD, accumulator.costUSD)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve invalidity when combining Cursor model costs

When one model on a day contains a negative/nonfinite totalCents and another model has a valid price, costInvalid makes the first accumulator's cost nil, but this reducer treats that nil exactly like an intentionally unpriced model and publishes the valid model's subtotal. The dashboard can then accept the malformed model as an allowed omitted-price row and present an apparently valid lower bound. Fresh evidence beyond the prior same-model issue is that later events now remain invalid, but the cross-model reducer still discards that invalid state; propagate costInvalid through day aggregation rather than passing only costUSD.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Aug 17, 2026
# Conflicts:
#	Tests/CodexBarTests/ProviderArchitectureGatekeeperTests.swift
@steipete
steipete merged commit f6606b9 into steipete:main Aug 17, 2026
9 checks passed
steipete added a commit that referenced this pull request Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants