Skip to content

fix: bound Codex cost scans on giant session corpora - #2452

Open
D4ilyHub wants to merge 6 commits into
steipete:mainfrom
D4ilyHub:fix/cost-scan-giant-session-budget
Open

fix: bound Codex cost scans on giant session corpora#2452
D4ilyHub wants to merge 6 commits into
steipete:mainfrom
D4ilyHub:fix/cost-scan-giant-session-budget

Conversation

@D4ilyHub

@D4ilyHub D4ilyHub commented Jul 25, 2026

Copy link
Copy Markdown

Summary

  • Bound Codex local token-cost scans so giant rollout corpora cannot monopolize a CPU core for hours.
  • Process newest rollout files first and cap newly read bytes per refresh.
  • Resume oversized files from persisted per-file progress until every complete JSONL record is covered; no rollout is permanently omitted from cost history.
  • Keep account and rate-limit probing unchanged. This work only affects local session cost history.

Resumable parsing

The cache now records the rollout file identity, target size, byte offset, reducer state, and any partial JSONL record needed to continue safely. Each refresh consumes at most the configured per-file slice and remaining global byte budget. A changed identity or size invalidates incompatible progress instead of mixing histories.

Ordinary rollouts publish accumulated complete records as they advance. Subagent rollouts retain compact relevant events until the final chunk establishes their copied-prefix ownership boundary, then publish the same result as an unbounded parse. Completed files follow the existing warm-cache path.

Contributor evidence

@D4ilyHub diagnosed the original scan storm and validated the bounded/newest-first machinery against a real 276 GiB corpus containing 1,322 rollouts. Before the change, the scanner could pin a core for hours and immediately resume after relaunch. The contributor's cold proof completed in about 16 seconds wall time and 6 seconds CPU under a 512 MiB refresh budget, while account and rate-limit display continued independently.

The maintainer follow-up replaces the initial permanent 256 MiB file skip with resumable bounded parsing while preserving that bounded-refresh behavior.

Verification

  • Focused scanner suites cover bounded multi-refresh convergence, cache round-trip persistence, a single JSONL record larger than the slice, newest-first ordering, budget admission, JSONL edge cases, and compact subagent accounting.
  • Local scanner proof: 34 tests passed across the performance, JSONL, and compact-subagent suites.
  • Repository format and lint checks pass.
  • Hosted CI is the authoritative full-suite proof for this PR.

Local token-cost history walks Codex rollout JSONL under ~/.codex/sessions.
On machines with multi-GB rollouts this can peg a core for hours on the
cost-usage-scan queue while quitting/relaunching only restarts the same
backlog. Rate-limit/account usage probes are a separate path and are
unaffected.

- Cap per-file cold/full scan work (default 256 MiB)
- Cap newly-read bytes per refresh (default 512 MiB) and defer the rest
- Prefer newest session files first so recent usage lands before catch-up
- Add performance gates for oversized skip, budget deferral, and fork work sizing

@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: e2ffbf5807

ℹ️ 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 +2833 to +2834
if cached.mtimeUnixMs == metadata.mtimeUnixMs, cached.size == metadata.size {
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Account for forced full rescans in pending work

When an unchanged cached file must nevertheless be rescanned—such as after a history-window expansion, pricing/project-metadata change, or a priority-turn invalidation—keepCachedCodexFileIfFresh rejects it, but this equality branch reports zero pending bytes. The budget therefore admits even a multi-GB file and records zero bytes after rescanCodexFile reads it completely, bypassing both new limits and recreating the CPU-thrashing behavior this change is intended to prevent.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed — valid hole. Fixed in 49d0966.

pendingCodexScanWorkBytes is only used after keepCachedCodexFileIfFresh fails. The old size/mtime-equality branch could still report 0 for forced full rescans (window/pricing/project-metadata/priority invalidation), so the budget admitted multi-GB files and then charged nothing after rescanCodexFile.

That zero branch is gone. Unchanged-but-must-rescan files now charge full file size; only true grow+non-fork incremental tails charge the delta.

Comment on lines +2792 to +2794
let pendingWorkBytes = Self.pendingCodexScanWorkBytes(metadata: metadata, cached: cached)
if let budget = context.scanBudget {
switch budget.admit(workBytes: pendingWorkBytes) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply scan limits to fork-parent snapshot reads

When an admitted small fork/subagent rollout references an oversized parent, its rescan calls CodexInheritedTotalsResolver, whose snapshotResolution reads the entire parent through parseCodexTokenSnapshots. This outer-file admission does not charge or limit that dependency read, so a parent that was skipped by its own top-level scan can still be parsed in full while processing the child, allowing the same multi-GB CPU-bound scan on a cold corpus.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed — also valid for fork/subagent corpora. Fixed in 49d0966.

CodexInheritedTotalsResolver now shares the same CodexScanBudget. Before parseCodexTokenSnapshots on a parent, we admit the parent file size; oversized/deferred parents return an unresolved baseline (existing fork path) instead of a full multi-GB dependency parse. Successful parent reads consume budget so they count toward the per-refresh cap.

Added a performance gate covering small-child + oversized-parent.

Address Codex review P1s on steipete#2452:

- pendingCodexScanWorkBytes no longer reports zero for unchanged
  size/mtime entries after keepCached fails. Forced full rescans
  (window/pricing/priority invalidation) now charge the full file.
- CodexInheritedTotalsResolver shares the scan budget and skips or
  defers oversized parent baseline snapshot reads instead of parsing
  multi-GB parents while processing small fork/subagent children.
- Add gates for forced-rescan work sizing and oversized-parent skip.
@D4ilyHub

Copy link
Copy Markdown
Author

Follow-up: addressed Codex P1 review comments

Pushed 49d09668 on this branch.

P1 — forced full rescans not charged

  • Fixed. pendingCodexScanWorkBytes no longer returns 0 for size/mtime-matched cache entries after keepCached rejects them.
  • Forced rescans now charge full file bytes against per-file and per-refresh budgets.

P1 — fork parent snapshot reads unbounded

  • Fixed. CodexInheritedTotalsResolver uses the shared scan budget.
  • Oversized/deferred parents skip the full baseline parse and surface as unresolved (existing fork handling).
  • Successful parent reads consume budget.

Tests added

  • forced-rescan work sizing for unchanged multi-GB cache entries
  • small fork child + oversized parent completes quickly without thrashing

Local verification

  • swift build --target CodexBarCore passes on this machine
  • Full CostUsagePerformanceGateTests still needs Xcode CI here (CLT-only host)

Thanks for the sharp catches — both were real bypasses of the original protection.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 25, 2026
@clawsweeper

clawsweeper Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed July 26, 2026, 12:22 PM ET / 16:22 UTC.

ClawSweeper review

What this changes

The PR bounds local Codex JSONL token-cost scans with a 256 MiB per-file limit, a 512 MiB per-refresh budget, newest-first ordering, and focused performance coverage for deferred and fork-parent scans.

Merge readiness

⚠️ Ready for maintainer review - 4 items remain

Keep this PR open for maintainer review. The bounded scanner and its real-corpus proof credibly address the CPU-saturation failure, but the default 256 MiB hard skip can permanently omit newly created large rollout files from local token-cost history; that intentional compatibility tradeoff needs an explicit product decision before merge.

Priority: P1
Reviewed head: 49d0966838363fe636011d708017ff583cdf6e5e
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The patch is well-scoped and unusually well-supported by real-corpus proof, but merge readiness depends on an explicit decision about permanently incomplete local cost history.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (live_output): The contributor provided redacted after-fix live output on the actual 276 GiB local corpus and a public-API oversized-file integration run; it directly demonstrates bounded scanner work and improved completion time.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The contributor provided redacted after-fix live output on the actual 276 GiB local corpus and a public-API oversized-file integration run; it directly demonstrates bounded scanner work and improved completion time.
Evidence reviewed 5 items Scanner defaults create a permanent omission path: The proposed Options defaults cap a Codex session file at 256 MiB and describe oversized files as skipped; a completed rollout does not normally shrink, so a newly created file above that threshold can remain absent from local cost history indefinitely rather than merely being deferred.
Focused tests cover the bounded-work behavior: The PR adds performance gates for oversized-file skipping, per-refresh deferral, forced-rescan work sizing, and an oversized fork parent, which supports the availability objective but does not establish eventual accounting for a skipped large rollout.
Prior review identified the same unresolved compatibility choice: The preceding completed review on the same head explicitly noted that the 256 MiB default can omit a newly created large rollout indefinitely and changes the completeness received after upgrade; the follow-up added proof but did not change that behavior.
Findings None None.
Security None None.

How this fits together

CodexBar’s local cost-usage subsystem scans Codex rollout JSONL files and stores daily token-cost totals for the menu bar. It uses cached file results and fork-parent resolution while account rate-limit polling follows a separate provider-RPC path.

flowchart LR
    A[Codex rollout JSONL files] --> B[Cost scan refresh]
    B --> C[Cache freshness and fork lookup]
    C --> D[Per-file and refresh budgets]
    D --> E[JSONL parsing and daily totals]
    E --> F[Cost-usage cache]
    F --> G[Menu bar cost history]
    H[Account rate-limit RPCs] --> I[Rate-limit display]
Loading

Decision needed

Question Recommendation
Should local token-cost history eventually include every completed Codex rollout by using resumable bounded parsing, or is permanent omission of rollouts above 256 MiB an acceptable default behavior? Require eventual accounting: Replace the permanent oversized-file skip with resumable or chunked bounded parsing so each refresh remains safe while completed rollout costs eventually enter history.

Why: The implementation makes a deliberate user-visible accuracy tradeoff rather than a purely mechanical bug fix. Repository evidence proves the availability benefit, but cannot determine whether incomplete cost history is acceptable for existing users after upgrade.

Before merge

  • Resolve merge risk (P1) - Existing users with local token-cost history enabled can upgrade from full but slow accounting to silently incomplete accounting whenever a newly created rollout exceeds 256 MiB; completed JSONL files generally will not shrink and therefore may never be scanned.
  • Resolve merge risk (P1) - The PR’s strong runtime evidence proves bounded CPU work, but it does not prove that users can discover or recover omitted local cost history in the product.
  • Complete next step (P2) - A maintainer must choose the intended completeness contract for oversized completed rollouts before a repair path can be safely selected.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope 352 added, 7 removed across 4 files The PR changes scanner admission behavior, parser-hash provenance, performance coverage, and release notes together.
Live corpus proof 276 GiB, 1,322 rollout files, ~16 s cold refresh This is meaningful evidence that the proposed bounds address the reported availability failure on a real large corpus.

Merge-risk options

Maintainer options:

  1. Make oversized scans resumable (recommended)
    Keep the current per-refresh work budget but process oversized JSONL files incrementally with durable progress so their costs are eventually represented.
  2. Accept the hard cap with product disclosure
    Merge the hard skip only if maintainers explicitly accept incomplete local cost history and require an in-product incomplete-data signal plus a recovery path.
  3. Hold for contract decision
    Pause this PR if neither eventual accounting nor a clearly supported partial-history experience is ready to own.

Technical review

Best possible solution:

Preserve bounded background work while guaranteeing eventual accounting for oversized rollouts through resumable/chunked parsing with persisted progress, or explicitly adopt permanent omission with a visible incomplete-history state and documented recovery path.

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

No independent live reproduction was run in this read-only environment, but the source path and the contributor’s redacted current-head large-corpus run provide a high-confidence source-reproducible path: enable local token-cost history and scan a corpus containing multi-hundred-MiB rollout JSONL files.

Is this the best way to solve the issue?

Unclear. Per-refresh budgeting and newest-first ordering are a good solution for the CPU problem, but permanently skipping completed files above 256 MiB is not the best default unless maintainers explicitly accept incomplete local cost history and make that state discoverable.

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P1: The reported local scan can keep a CPU core busy for hours and materially degrade normal menu-bar app availability on affected machines.
  • merge-risk: 🚨 availability: The new admission and budgeting rules directly control whether local refreshes can avoid prolonged CPU-bound work.
  • merge-risk: 🚨 compatibility: The new 256 MiB default can silently change existing local cost-history completeness after upgrade by permanently excluding completed oversized rollouts.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The contributor provided redacted after-fix live output on the actual 276 GiB local corpus and a public-API oversized-file integration run; it directly demonstrates bounded scanner work and improved completion time.
  • proof: sufficient: Contributor real behavior proof is sufficient. The contributor provided redacted after-fix live output on the actual 276 GiB local corpus and a public-API oversized-file integration run; it directly demonstrates bounded scanner work and improved completion time.

Evidence

What I checked:

  • Scanner defaults create a permanent omission path: The proposed Options defaults cap a Codex session file at 256 MiB and describe oversized files as skipped; a completed rollout does not normally shrink, so a newly created file above that threshold can remain absent from local cost history indefinitely rather than merely being deferred. (Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift:37, 49d096683836)
  • Focused tests cover the bounded-work behavior: The PR adds performance gates for oversized-file skipping, per-refresh deferral, forced-rescan work sizing, and an oversized fork parent, which supports the availability objective but does not establish eventual accounting for a skipped large rollout. (Tests/CodexBarTests/CostUsagePerformanceGateTests.swift:288, 49d096683836)
  • Prior review identified the same unresolved compatibility choice: The preceding completed review on the same head explicitly noted that the 256 MiB default can omit a newly created large rollout indefinitely and changes the completeness received after upgrade; the follow-up added proof but did not change that behavior. (Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift:37, 49d096683836)
  • Real after-fix behavior proof is strong: The PR body reports a redacted live run on a 276 GiB, 1,322-rollout corpus: a cold refresh completed in about 16 seconds while reporting 424 oversized skips and 866 budget deferrals, plus a synthetic oversized-sibling integration result. (49d096683836)
  • Repository policy supports focused coverage and careful provider-data behavior: The repository guidance calls for focused XCTest coverage for new logic, parser-first validation where possible, and maintaining provider data boundaries; the PR’s test seam and separation from rate-limit polling align with that guidance. (AGENTS.md:1)

Likely related people:

  • steipete: The repository owner is the best available routing candidate for the user-visible completeness-versus-availability policy decision; local git-history inspection was unavailable in this read-only environment, so this is not asserted as line ownership. (role: likely product and adjacent code owner; confidence: low; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift, Tests/CodexBarTests/CostUsagePerformanceGateTests.swift)

Rank-up moves

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

  • Confirm the intended user contract for completed rollouts above 256 MiB.
  • If permanent omission is accepted, add a visible incomplete-history signal and recovery path; otherwise implement bounded resumable parsing.

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 (2 earlier review cycles)
  • reviewed 2026-07-25T16:35:46.158Z sha 49d0966 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-26T16:17:02.074Z sha 49d0966 :: needs maintainer review before merge. :: none

@D4ilyHub

Copy link
Copy Markdown
Author

Real behavior proof added (ClawSweeper request)

Updated the PR body with redacted after-fix live runtime evidence on head 49d096683836.

What was run

Public CostUsageFetcher against the actual large local ~/.codex session corpus (not a toy fixture), plus the synthetic 300 MiB oversized-sibling integration.

Corpus (aggregate / redacted)

  • 276.0 GiB sessions tree
  • 1322 rollout-*.jsonl files
  • 417 files ≥256 MiB (3 ≥1 GiB)
  • Largest sizes (MiB only): 1335, 1308, 1294, 722, 715, …

After-fix cold catch-up (forceRefresh, historyDays=30, empty temp cache)

elapsed_s=16.073
process_cpu_s=5.955
bounded=yes

CodexBarCore work-limit log (path-free):

skippedOversized=424
deferredByBudget=866
bytesConsumed=536854072   # ~512 MiB refresh budget
maxFileBytes=268435456
maxBytesPerRefresh=536870912

Second refresh (same cache)

elapsed_s=6.538
still_bounded=yes
total_tokens increased (progressive catch-up under budget)

Synthetic oversized sibling

300 MiB giant skipped; small session totalTokens=110; elapsed=0.021s

Intentional tradeoff (explicit for merge review)

Local token-cost history can lag for deferred/oversized multi-hundred-MB and multi-GB rollouts. That is the availability tradeoff. Account/rate-limit remaining + reset remain on a separate path and are unaffected by these scan budgets.

Not runnable on author host

Full CostUsagePerformanceGateTests still needs Xcode/Swift Testing (CLT-only here). Gates are in-tree for CI.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 26, 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 proof: sufficient Contributor real behavior proof is sufficient. 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. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 26, 2026
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. P1 Urgent regression or broken agent/channel workflow affecting real users now. proof: sufficient Contributor real behavior proof is sufficient. 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.

2 participants