Skip to content

Fix Codex fork parent cache invalidation#2118

Merged
steipete merged 1 commit into
steipete:mainfrom
xx205:agent/fix-codex-fork-cache-baselines
Jul 16, 2026
Merged

Fix Codex fork parent cache invalidation#2118
steipete merged 1 commit into
steipete:mainfrom
xx205:agent/fix-codex-fork-cache-baselines

Conversation

@xx205

@xx205 xx205 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • persist the parent-session file dependency used by each cached Codex fork
  • rebuild a cached child when its parent appears, changes, or resolves to another file
  • bind the stored dependency key to the exact stable parent snapshot used during parsing
  • add regression coverage for warm-cache invalidation and concurrent parent/child growth

Why

Fork accounting depends on the parent totals at the fork timestamp, but cache freshness previously tracked only the child file. A child cached while its parent was missing—or before the parent changed—could keep stale inherited totals indefinitely.

Current main already contains the leaf-session identity correction from overlapping work. This branch is intentionally narrowed to the remaining parent-cache dependency bug.

Safety

The cache field is optional. Existing Codex caches rotate through the generated parser producer key; the on-disk schema and artifact layout remain compatible. Parent snapshots are fingerprinted before and after parsing. If the parent changes during both read attempts, the unresolved result is deliberately not reusable on the next refresh.

Testing

  • swift test --filter 'CostUsageScannerBreakdownTests|CostUsageCacheTests' — 98 tests passed
  • make check — passed
  • make test — 651 selections in 55 groups passed; zero retries or failures
  • pre-commit and exact-commit autoreview — no actionable findings
  • source-blind synthetic CLI validation was inconclusive because the debug CLI stayed alive before emitting JSON; child fixture checksum remained unchanged and no live credentials or account data were used

Co-authored-by: Xu Xiang xx205@outlook.com

@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. P2 Normal priority bug or improvement with limited blast radius. labels Jul 13, 2026
@clawsweeper

clawsweeper Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed July 13, 2026, 5:49 AM ET / 09:49 UTC.

Summary
Prefers Codex fork leaf IDs, records parent-file fingerprints as cache dependencies, invalidates stale warm fork entries, rotates the parser hash, and adds cold/warm regression coverage.

Reproducibility: yes. at source level: current main selects a parent-oriented session alias before the child leaf ID, and the supplied frozen-corpus A/B run shows the resulting current-main overcount and stable after-fix cold/warm totals.

Review metrics: 3 noteworthy metrics.

  • Patch Scope: 5 files; 211 added, 11 removed. The implementation remains concentrated in the Codex scanner/cache path and one focused regression-test file.
  • Regression Coverage: 164 lines added in 1 test file. Most added code is dedicated to identity and cold/warm parent-dependency scenarios rather than unrelated production churn.
  • Runtime Corpus: 578 files; 1 cold and 2 warm branch scans. Repeated scans over identical frozen input demonstrate that the corrected aggregate remains stable after cache reuse.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] Merging either this PR or Fix Codex fork identity and cache dependencies #2120 without first comparing their current heads could discard a newer optimization, duplicate tests, or create two competing sources for the same fix.
  • [P1] The implementation overlaps the parent-resolution behavior in Partially fix inherited token accounting across Codex session forks #2113; landing order should preserve any complementary ancestry handling rather than resolving conflicts by dropping it.
  • [P1] The large real-corpus accounting reduction is convincing evidence of the bug, but it also makes representative leaf-ID and legacy-metadata regression coverage important before release.

Maintainer options:

  1. Reconcile And Land This Branch (recommended)
    Diff this head against both overlapping PRs, retain complementary ancestry behavior and tests, then land one canonical implementation.
  2. Select The Alternate Candidate
    Use Fix Codex fork identity and cache dependencies #2120 only after confirming that its current head fully subsumes this branch without losing attribution or optimizations.
  3. Pause Duplicate Landing Work
    Hold both branches until maintainers define one consolidated scanner/cache patch if the ancestry interactions cannot be safely reconciled during review.

Next step before merge

  • [P2] A maintainer should compare the active overlapping branches and choose one landing path; no narrow automated code repair is currently needed.

Maintainer decision needed

  • Question: Should maintainers land this actively maintained original branch, prefer the overlapping Fix Codex fork identity and cache dependencies #2120, or consolidate both with compatible ancestry work from Partially fix inherited token accounting across Codex session forks #2113?
  • Rationale: Two proof-positive branches carry substantially the same central fix, their contributors disagree about supersession, and an adjacent ancestry PR modifies the same accounting path; automation cannot safely choose ownership or integration order.
  • Likely owner: steipete — Repository ownership makes this person the best available owner for choosing between disputed overlapping landing branches.
  • Options:
    • Land This Original Branch (recommended): Compare the three current heads, add any uniquely useful ancestry coverage, and land this active original implementation while preserving its existing attribution.
    • Prefer The Cherry-Picked Branch: Land Fix Codex fork identity and cache dependencies #2120 only if maintainers confirm it contains every current optimization and test from this PR and provides the preferred review history.
    • Create A Consolidated Landing Branch: Pause both duplicate candidates and combine the accepted identity, cache-dependency, and ancestry changes into one maintainer-owned integration branch.

Security
Cleared: The scanner, optional cache metadata, generated parser hash, and regression-test changes introduce no concrete security or supply-chain concern.

Review details

Best possible solution:

Land one canonical patch that preserves leaf-ID precedence, parent-fingerprint cache invalidation, parser-hash rotation, and all compatible ancestry improvements, with focused synthetic tests plus stable cold/warm frozen-corpus output.

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

Yes at source level: current main selects a parent-oriented session alias before the child leaf ID, and the supplied frozen-corpus A/B run shows the resulting current-main overcount and stable after-fix cold/warm totals.

Is this the best way to solve the issue?

Yes for the code direction: leaf identity plus explicit parent-cache dependency tracking is narrower and safer than global fork suppression. The unresolved question is which overlapping branch should become the canonical landing vehicle.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: Incorrect fork accounting can substantially distort Codex usage and cost reporting, but the impact is bounded to affected forked-session logs.
  • merge-risk: 🚨 other: Three concurrent scanner/accounting branches overlap, so an unreconciled landing could omit complementary behavior or create competing implementations.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body contains redacted after-fix output from identical frozen input showing a corrected cold result and two exactly stable warm-cache results; the aggregate proof directly exercises the changed scanner/cache behavior.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body contains redacted after-fix output from identical frozen input showing a corrected cold result and two exactly stable warm-cache results; the aggregate proof directly exercises the changed scanner/cache behavior.
Evidence reviewed

What I checked:

Likely related people:

  • hhh2210: Authored the earlier parser-producer-key design in refactor: derive Codex cost cache producer key from parser source hash #1042 and the independently mergeable overlapping implementation in Fix Codex fork identity and cache dependencies #2120. (role: cache invalidation design contributor and overlapping candidate author; confidence: high; commits: e7dd706d5e72, 0571f21dc3d3; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageCache.swift, Sources/CodexBarCore/Generated/CodexParserHash.generated.swift, Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift)
  • iam-brain: Authored Partially fix inherited token accounting across Codex session forks #2113, which changes the same Codex parent-session resolution and inherited-token accounting area. (role: adjacent ancestry implementation author; confidence: high; commits: 845c8b61636c; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift, Tests/CodexBarTests/CostUsageScannerBreakdownTests.swift)
  • steipete: The overlapping active branches and disputed supersession require the repository owner or delegated reviewer to select the canonical landing path. (role: repository owner and likely landing decision owner; confidence: medium; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift, Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+CacheHelpers.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.
Review history (4 earlier review cycles)
  • reviewed 2026-07-13T08:55:07.411Z sha 7b80264 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-13T09:15:36.400Z sha 7b80264 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-13T09:29:52.145Z sha 7b80264 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-13T09:36:39.892Z sha 8152bca :: needs maintainer review before merge. :: none

@hhh2210

hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@clawsweeper re-review

I reproduced the current-release Unknown model symptom and reran the same frozen Codex log corpus against current main, this PR, and this PR plus a separate fork-model inheritance experiment.

Release screenshot:

CodexBar 0.42.1 showing Unknown model usage

The corpus contains 1,692 frozen JSONL files. Each run used a fresh isolated HOME and cost cache. The input files and CLI arguments were identical.

Variant Jul 13 total tokens Unknown model gpt-5.6-sol codex-auto-review
current main (c852c135) 705,781,187 27,654,293 663,872,726 14,254,168
this PR (7b802644) 394,500,055 0 380,245,887 14,254,168
this PR + fork-model inheritance experiment 394,500,055 0 380,245,887 14,254,168

This PR already fixes the observed Unknown model symptom. The separate model-inheritance patch made no difference once leaf identity and parent dependency invalidation were correct, so I am not opening that redundant PR.

The cache boundary should remain explicit: parser and attribution changes must regenerate CodexParserHash; they must not bump codex-v9. PR #1042 introduced the parser-content producer key specifically to avoid manual artifact-version churn. An artifact bump is only appropriate for an incompatible on-disk schema or file-layout change. The optional dependency field in this PR does not require one.

Please use this run as real-data proof for #2118. For clustering, #2118 is the complete candidate for the current-release fork identity/cache and Unknown model symptom; #2113 remains a narrower partial ancestry fix, and #2037 should stay open for the larger exact cross-file accounting problem.

@xx205

xx205 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 13, 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: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 13, 2026
@hhh2210

hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Superseded by ready PR #2120, which preserves @xx205 attribution, includes the same valid implementation, adds the #1042 cache-versioning invariant, and carries frozen-corpus proof for the Unknown-model symptom. @clawsweeper cluster #2118 under #2120 and close this draft; review #2120 as the independently mergeable candidate.

@clawsweeper clawsweeper Bot added 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: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 13, 2026
@xx205

xx205 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Provenance correction: the runtime evidence claimed by this PR is limited to the controlled local 578-file experiment now documented in the PR body. The same frozen input was scanned with current main and this PR using separate empty caches, followed by two warm-cache scans. Any third-party validation elsewhere in the discussion is independent and must not be attributed to the contributor-provided proof for this PR. Please evaluate the redacted local table in the PR body for the proof gate.

@xx205

xx205 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@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 Jul 13, 2026
@xx205
xx205 marked this pull request as ready for review July 13, 2026 09:33
@xx205

xx205 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Status and provenance clarification: #2118 is the original implementation PR and remains actively maintained. It now includes a controlled local A/B plus cold/warm proof, incorporates the cache-gate ordering optimization, and is ready for maintainer review. #2120 independently cherry-picks the substantive implementation and adds separate documentation and evidence; there has been no contributor agreement that it supersedes or closes #2118. Evidence from the two PRs should remain separately attributed. Please leave the landing decision to maintainers.

@xx205

xx205 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 13, 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: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@hhh2210

hhh2210 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@clawsweeper re-review

Routing correction: I closed #2120 as a duplicate landing candidate after comparing it with the latest #2118 tree. #2118 is the original, actively maintained implementation and should be treated as the canonical identity/cache candidate.

My 1,692-file frozen-corpus A/B remains independent supporting evidence for #2118; @xx205's 578-file cold/warm run remains the contributor proof for this PR. Please preserve that evidence provenance, keep #2113 classified as partial ancestry overlap, and leave #2037 open for the broader accounting problem.

@devYRPauli devYRPauli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Traced the root bug - it's real on main: the session_meta parse resolved identity as payload["session_id"] ?? payload["sessionId"] ?? payload["id"], so a forked child whose session_id alias carries the parent's id got filed under the parent's identity, corrupting the session->file index and row-dedup keys. Preferring the leaf id is right, and good that this updates all three parse sites (~1604/1742/2213), not just one. The 578-file before/after corpus (3.37B -> 522M tokens, stable across cold/warm rescans) is convincing.

One coordination note: this overlaps #2113 and #2121 - all three touch the identity / keepCachedCodexFileIfFresh path and will conflict. Since this one carries the real-corpus proof, landing it first and rebasing the other two on top would avoid the churn.

@iam-brain

iam-brain commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

I like this simple fix for the 5.6 multiagents v2 bloat. My successive PRs #2155 #2156 #2157 #2158 aim to tackle more of the larger problem and should be complementary your fix but with added performance, lineage tracking, and containment improvements to overall increase token accounting accuracy. So far, it's strongly backed by my comparisons between the reported OpenAI token usage on my codex account vs the results of the current "legacy" scanner without this specific fix.

#2118 falls short of #2158's overhaul and improvements (with many more changes, of course):

UTC day OpenAI official #2118 Difference #2158 rerun Difference
Jul 9 852,682,935 764,026,920 -10.40% 764,026,920 -10.40%
Jul 10 1,580,199,588 1,421,124,213 -10.07% 1,498,664,841 -5.16%
Jul 11 1,259,990,957 846,608,173 -32.81% 1,315,404,262 +4.40%
Aggregate 3,692,873,480 3,031,759,306 -17.90% 3,578,096,023 -3.11%

Co-authored-by: Xu Xiang <xx205@outlook.com>
@steipete
steipete force-pushed the agent/fix-codex-fork-cache-baselines branch from 8152bca to 45dfa3f Compare July 16, 2026 07:10
@steipete steipete changed the title Fix Codex fork identity and cache invalidation Fix Codex fork parent cache invalidation Jul 16, 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: 45dfa3f959

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

return false
}
if let parentSessionId = cached.forkedFromId {
guard let cachedDependencyKey = cached.forkBaselineDependencyKey else { return false }

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 warm-cache hits for subagent forks

When the cached file is a Codex subagent with forkedFromId, the parser intentionally treats the parent id as lineage rather than a baseline and never records a parent dependency key, so forkBaselineDependencyKey remains nil. This guard then rejects an otherwise fresh cache entry on every refresh, causing unchanged subagent logs to be fully reparsed repeatedly; in subagent-heavy histories this defeats the warm cache and makes refresh cost scale with old logs. Consider skipping this dependency check for independent/subagent forks or storing a non-parent sentinel.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Owner

Exact-head maintainer proof for 45dfa3f959bccea3845d7009a8c48f35d4e0df32:

  • Focused scanner/cache suite: 98 tests passed.
  • make check: passed with zero SwiftFormat and SwiftLint violations.
  • make test: 651 selections across 55 groups; zero failures, retries, or timeouts.
  • Pre-commit and exact-commit autoreview: no actionable findings.
  • Hosted CI: all eight checks green, including both macOS shards and both Linux architectures. ARM64 passed on attempt 3 after two external Ubuntu mirror timeouts before build.
  • No live account, browser, or Keychain probe. A source-blind synthetic CLI harness was inconclusive because the debug CLI did not exit; deterministic fixture regressions cover the repaired cache behavior.

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

Labels

merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants