Skip to content

fix: preserve Codex request-tier pricing across forks - #2863

Merged
steipete merged 10 commits into
mainfrom
fix/codex-fork-cost-overcount
Aug 11, 2026
Merged

fix: preserve Codex request-tier pricing across forks#2863
steipete merged 10 commits into
mainfrom
fix/codex-fork-cost-overcount

Conversation

@steipete

@steipete steipete commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Problem

Fork children can retain copied parent-prefix usage rows even when canonical per-file/day/model token ownership has already removed that prefix. When the physical rows exceeded canonical totals, the report rejected row pricing and priced the whole canonical day/model aggregate as one request. For GPT-5.6 Sol, that let many sub-272K requests cross the 272K long-context threshold only after aggregation and nearly doubled the estimate.

Synthetic red proof on e5528d4: two independent 200K-input requests should cost $2.006; the fallback priced their 400K aggregate at $4.009, a $2.003 overcount.

Root cause

buildCodexReportFromCache concatenated physical pricing rows across files, then used only a global token-total guard. Once that guard rejected fork-inflated rows, request-scoped threshold pricing received day/model aggregates. Project and session rollups happened to price smaller groups, so grouping changed the result. Existing SQLite rows already retained the full request boundaries needed to repair the report on read.

Fix

  • Reconcile persisted rows independently for each cached file/day/model against canonical usage.days ownership, using persisted array/SQLite row_index order. Exact token-bearing sets retain order; inflated sets may retain only the newest contiguous exact suffix. Zero-owned groups use the empty suffix.
  • Fail closed for irreconcilable groups, incomplete pricing evidence, unstable request identity, ambiguous copied cost-only prefixes, or Standard/Fast ownership mismatches. Genuine retained long requests and zero-token authoritative costs inside an owned suffix remain authoritative.
  • Trust request rows only when every positive-token row prices and Standard+Fast tokens exactly equal canonical tokens. Preserve all retained row metadata and the Standard/Fast split.
  • Price aggregates only when exact: linear models always qualify, and thresholded models qualify only when aggregate input is at or below the threshold. Above-threshold aggregates without request boundaries remain unavailable.
  • Build each project's primary totals from one project-scoped canonical cache so unresolved ownership for the same day/model cannot disappear through per-file merging. Source detail remains file-scoped, and distinct-model partial-cost semantics are unchanged.
  • Adopt the shipped b975eb705f905b9a predecessor store in place only when its derived version, quick_check, and incremental auto-vacuum all validate. Validation and metadata/version rotation run under one BEGIN IMMEDIATE transaction, so concurrent openers cannot observe a torn adoption pair. Unknown, mismatched, or corrupt stores still rebuild.
  • Preserve price-on-read. There is no SQLite schema change, no new persisted field, and no persisted catalog-derived USD.

Proof

  • Red: swift test --filter CostUsageScannerForkSplitTests failed on current main with the synthetic $2.006 request sum versus $4.009 aggregate result.
  • Green: swift test --filter CostUsageScannerForkSplitTests — 14/14 tests.
  • Green: swift test --filter CostUsagePricingTests — 48/48 tests.
  • Green: swift test --filter CostUsageScannerPriorityTests — 17/17 tests.
  • Green: swift test --filter CostUsagePerformanceGateTests — 26/26 tests, including zero session-head reparses during compatible warm adoption.
  • Green: swift test --filter CostUsageStoreTests — 64/64 tests, including 16 concurrent predecessor openers with zero rebuilds and preserved tables/metadata.
  • Green: pricing-race, cutover, failure-injection, scanner breakdown, project/session, subagent, fetcher, and round-trip suites.
  • Green: make check and current generated parser-hash check.
  • Green: make test — 840 selections, 70/70 groups, no retries, failures, or timeouts.
  • Green: git diff --check and configured Codex branch autoreview through P2.
  • Warm SQLite reload matches the cold in-memory report while retaining full usage_rows request payloads without a schema change.

Fixes #2858

@clawsweeper

clawsweeper Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

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

@steipete

Copy link
Copy Markdown
Owner Author

@clawsweeper review

Please review exact head 2b773e990a146531ba9a931f7b82a3429ab6b5eb through P2. Focus on request-scoped threshold pricing, per-file fork-prefix suffix reconciliation, stable row identity, Standard/Fast ownership, safe aggregate fallback, and warm SQLite usage_rows parity. Do not merge.

@clawsweeper

clawsweeper Bot commented Aug 11, 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 repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@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 11, 2026
@clawsweeper

clawsweeper Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed August 11, 2026, 2:28 PM ET / 18:28 UTC.

ClawSweeper review

What this changes

This PR reconciles forked Codex usage rows at request granularity, avoids unsafe threshold pricing of aggregates, and safely adopts compatible SQLite caches under contention.

Regression provenance

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

Merge readiness

⚠️ Ready for maintainer review - 1 item remains

Keep open for normal maintainer merge handling. The exact head addresses the prior SQLite-lock blocker and still supplies the requested fix for the linked Codex pricing defect.

Priority: P2
Reviewed head: b392c5669162d1f7c40c39b2b123395dd0747d63

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The patch has a coherent conservative design and extensive focused regression coverage; normal exact-head macOS validation remains the merge gate.
Proof confidence 🌊 off-meta tidepool Not applicable: This maintainer-authored internal pricing and SQLite change is covered by supplied focused regression results; the external-contributor proof gate does not apply.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: This maintainer-authored internal pricing and SQLite change is covered by supplied focused regression results; the external-contributor proof gate does not apply.
Evidence reviewed 6 items Request-boundary reconciliation: The new reconciliation retains an exact persisted row set or a contiguous suffix matching canonical input, cached, and output totals; otherwise it marks the group unresolved.
Safe aggregate fallback: Report construction uses reconciled rows only when their token ownership is trusted, and aggregate pricing returns unavailable above a model threshold rather than inferring a long-context rate from a day aggregate.
Persisted order is defined: SQLite cache reads order retained request payloads by file path and row_index, matching the suffix-reconciliation assumption.
Findings None None.
Security None None.

How this fits together

CodexBar scans Codex sessions into a local usage cache, reconciles forked rows into canonical daily/model usage, and produces CLI and menu-bar cost reports. The changed cache-open path also controls whether existing local usage history is reused or rebuilt.

flowchart LR
A[Codex session files] --> B[Local usage cache]
B --> C[Fork ownership reconciliation]
C --> D[Request-level cost calculation]
D --> E[Daily and project reports]
B --> F[Cache compatibility validation]
F --> B
Loading

Before merge

  • Resolve merge risk (P1) - Existing local cost caches now take a conditional adoption path; merge safety depends on the exact-head lock and cache-adoption regressions continuing to pass on macOS.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Changed surface 14 files; 1 new reconciliation module and 2 new test files The patch crosses report pricing, project rollups, and persistent-cache opening.
Regression coverage production +307 net lines, tests +1,115 net lines Most growth is focused coverage for pricing boundaries, warm-cache adoption, and lock contention.

Merge-risk options

Maintainer options:

  1. Complete exact-head cache validation (recommended)
    Require the in-progress macOS test shards to pass the fork-pricing and concurrent cache-open regressions before merge.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Require the exact-head macOS test shards to pass, including CostUsageStoreTests and CostUsageScannerForkSplitTests.

Technical review

Best possible solution:

Keep request-level prices where ownership is provable, leave thresholded aggregates unavailable when boundaries are lost, and preserve locked compatible caches for retry rather than rebuilding them.

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

Yes—source fixtures deterministically combine two 200K requests under a 272K threshold and exercise copied fork prefixes; this read-only review did not execute them.

Is this the best way to solve the issue?

Yes. The patch preserves request boundaries when evidence is exact and fails closed for thresholded aggregates when those boundaries cannot be established.

AGENTS.md: found and applied where relevant.

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

Labels

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: This maintainer-authored internal pricing and SQLite change is covered by supplied focused regression results; the external-contributor proof gate does not apply.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: The PR repairs materially incorrect cost estimates without evidence of an emergency outage.
  • merge-risk: 🚨 compatibility: Existing SQLite cost caches receive new parser-hash and compatible-predecessor handling during upgrade.
  • merge-risk: 🚨 availability: The cache-open path changes its behavior while another process holds a SQLite writer lock.
  • 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: This maintainer-authored internal pricing and SQLite change is covered by supplied focused regression results; the external-contributor proof gate does not apply.

Evidence

What I checked:

Likely related people:

  • steipete: Peter Steinberger’s current and historical CostUsageStore work includes the prior store-executor repair and this focused pricing/cache branch. (role: feature owner; confidence: high; commits: 27054465bd86, b392c5669162; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore.swift, Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+CacheHelpers.swift)
  • Robert: Current-main history shows Robert’s recent CostUsageStore repair adjacent to the modified cache-opening behavior. (role: recent adjacent contributor; confidence: medium; commits: b3c1bfa390a9; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore.swift)

Rank-up moves

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

  • Let the current exact-head macOS test shards complete before merging.

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 (5 earlier review cycles)
  • reviewed 2026-08-11T13:35:40.714Z sha 2b773e9 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-11T13:39:37.161Z sha 2b773e9 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-11T16:03:47.374Z sha 61d46c6 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-11T16:12:00.648Z sha 61d46c6 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-11T16:57:27.688Z sha 61d46c6 :: needs changes before merge. :: [P1] Avoid rebuilding a valid cache on a transient lock

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Aug 11, 2026
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Aug 11, 2026
@steipete

Copy link
Copy Markdown
Owner Author

@clawsweeper re-review

Please review exact head 61d46c66e8e81cb71423e807c8250fd755927533 through P2. Focus on persisted-order fork suffix ownership, cost-only and incomplete-pricing evidence, safe aggregate thresholds, project same-model propagation, and atomic compatible-store adoption. Do not merge.

@clawsweeper

clawsweeper Bot commented Aug 11, 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 repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Aug 11, 2026
@steipete

Copy link
Copy Markdown
Owner Author

Resolved the remaining SQLite lock finding at exact head b392c56691.

  • Current-schema validation now runs in one deferred read transaction, so version/hash/integrity are observed from one snapshot without taking a writer lock.
  • Compatible predecessor adoption alone uses BEGIN IMMEDIATE, re-reads compatibility under that lock, and adopts only if it is still eligible.
  • ensureDatabase now propagates SQLITE_BUSY/SQLITE_LOCKED through the existing preserve-and-retry path instead of rebuilding.
  • Real held-lock regressions prove a current store remains readable and a locked predecessor is preserved, returns a safe fallback, then adopts intact after retry.
  • The tests remain extensions of the existing CostUsageStoreTests suite, preserving the proven 840-selection / 70-group shard layout.

Final proof: CostUsageStoreTests 66/66; lock regressions 2/2; focused pricing suites green; make check green; full make test 840/840 in 70/70 groups; git diff --check green; configured branch autoreview through P2 clean with no actionable findings.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 11, 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 repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added the rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. label Aug 11, 2026
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 11, 2026
@steipete
steipete merged commit 4befde4 into main Aug 11, 2026
8 checks passed
@steipete

Copy link
Copy Markdown
Owner Author

Landed as 4befde4bbdf0cabc6db048bcc93e9bb28fb2d766.

The red repro was two 200K short requests: request-level expected cost was $2.006, while the old day-aggregate fallback produced $4.009. The final path reconciles copied fork prefixes from canonical request rows, preserves valid request-tier pricing, and refuses ambiguous long-context pricing on aggregates.

Proof: make test passed 840/840 selections in 70/70 groups; make check and git diff --check were clean; exact-head CI run 31522518443 was green; final P2 autoreview (TruffleHog clean, overall 0.86) and exact-head ClawSweeper reported no actionable findings.

Compatible shipped-predecessor SQLite caches retain complete rows/history without reparse while sidecar generation rotates. Under external writer locks, current stores remain readable and predecessor stores are preserved for safe retry/adoption. There is no schema change and no persisted estimated USD.

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

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. 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: 🐚 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 cost nearly doubles when canonical day/model fallback applies >272K long-context pricing to aggregated tokens

1 participant