Fix Codex fork identity and cache dependencies - #2120
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes Codex fork session identity selection and makes warm-cache correctness depend on the parent baseline file used for inherited fork totals, preventing forked child sessions from being aliased to their parent and avoiding stale fork accounting when the parent file changes.
Changes:
- Prefer
payload.idoverpayload.session_idwhen parsing Codex session identifiers (leaf identity wins). - Persist and validate a fork parent “baseline dependency key” so cached fork results invalidate when the parent file appears/changes.
- Add focused scanner tests covering both leaf-identity selection and warm-cache parent dependency invalidation; regenerate
CodexParserHash.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Tests/CodexBarTests/CostUsageScannerBreakdownTests.swift | Adds regression coverage for fork leaf-ID preference and parent-baseline cache invalidation. |
| Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner+CacheHelpers.swift | Stores a parent baseline dependency key in cache entries and uses it to decide cached-fork freshness. |
| Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift | Updates fast/slow session-id parsing order to prefer leaf id; adds a dependency-key helper for parent baseline tracking. |
| Sources/CodexBarCore/Vendored/CostUsage/CostUsageCache.swift | Documents Codex cache artifact versioning invariants and adds a new optional cached field for fork dependency tracking. |
| Sources/CodexBarCore/Generated/CodexParserHash.generated.swift | Updates the tracked parser hash to reflect scanner/parser source changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if let parentSessionId = cached.forkedFromId { | ||
| guard let cachedDependencyKey = cached.forkBaselineDependencyKey, | ||
| try cachedDependencyKey == (context.resources.inheritedResolver.dependencyKey(for: parentSessionId)) | ||
| else { return false } | ||
| } | ||
|
|
||
| guard !Self.cachedCodexFileNeedsPriorityRescan(cached, context: context) else { return false } |
There was a problem hiding this comment.
Fixed in 0571f21. The priority-rescan, identity-rescan, and empty-row checks now run before the parent dependency lookup. The throwing lookup is also assigned to currentDependencyKey before comparison. Validation: 89 focused scanner/cache tests passed, and make check passed.
|
Codex review: needs maintainer review before merge. Reviewed July 13, 2026, 5:41 AM ET / 09:41 UTC. Summary Reproducibility: yes. The PR supplies a controlled current-main versus branch scan over the same frozen 1,692-file Codex corpus, reproducing Unknown-model attribution and fork overcount before the fix and eliminating them afterward. Review metrics: 3 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land one canonical leaf-identity and parent-cache-dependency implementation with preserved authorship and both proof records, then separately evaluate the non-overlapping parent-resolution behavior from #2113 against the remaining overcount corpus. Do we have a high-confidence way to reproduce the issue? Yes. The PR supplies a controlled current-main versus branch scan over the same frozen 1,692-file Codex corpus, reproducing Unknown-model attribution and fork overcount before the fix and eliminating them afterward. Is this the best way to solve the issue? Yes for the demonstrated identity and warm-cache dependency bug: preferring the leaf ID and tracking the parent-file fingerprint is narrow and regression-tested. The unresolved question is which duplicate branch should land, not whether this implementation approach is appropriate. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c852c135e10c. Label changesLabel changes:
Label justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
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
Review history (1 earlier review cycle)
|
|
@clawsweeper re-review Addressed the cache fast-path ordering finding in 0571f21. Parent indexing now runs only after the cheap priority, identity, and empty-row rejection gates. Validation:
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Provenance clarification: the substantive fork identity and cache invalidation implementation here is a cherry-pick of the original implementation in #2118. #2118 remains active, now includes the cache-gate ordering optimization and its own controlled local proof, and has not been abandoned or agreed to be superseded. The runtime evidence in #2120 is independent and should remain separately attributed. Please leave any close or supersede decision to maintainers. |
|
The previous claim that #2120 superseded #2118 was incorrect. #2118 was not abandoned or agreed to be superseded, and @xx205 has kept the original implementation active. I compared the latest trees after #2118 added its cache-gate optimization. There is no remaining behavioral reason to keep two landing candidates. I am closing #2120 as a duplicate, while retaining the branch and its independent 1,692-file proof as an audit trail. The technical conclusions do not change: leaf-ID precedence and parent-dependent cache invalidation fix the reproduced issue, parser changes should use @clawsweeper cluster #2120 as duplicate/independent validation under canonical candidate #2118. Keep implementation attribution and the two independent proof corpora separate. |
Status
Closed as a duplicate landing candidate after #2118 remained active and incorporated the same cache-gate ordering repair. #2118 is the original implementation by @xx205. This branch remains available as an audit trail for the independent runtime validation and review work below.
What this PR established
payload.idover parent-orientedsession_idaliases and invalidates a cached fork when its parent baseline file changes. The substantive implementation came from Fix Codex fork parent cache invalidation #2118, with its Git authorship preserved.Unknown modelsymptom, then verified the fix on the same immutable input.CodexParserHash;codex-vNchanges only for an incompatible on-disk schema or cache layout.Problem
A fork rollout can contain both:
payload.id: the child/leaf session identitypayload.session_id: the parent-oriented session identityChoosing
session_idfirst aliases the child to its parent. That breaks parent lookup and can keep a child cache entry fresh after its inherited parent baseline has changed. In the UI, the same identity error can surface as fork usage attributed toUnknown model:Independent frozen-data proof
I cloned my local Codex session tree into an isolated frozen corpus of 1,692 JSONL files and scanned it with isolated home and cache directories. This evidence is independent of the 578-file proof supplied by @xx205 on #2118.
main@c852c135A separate model-inheritance experiment produced no further change once leaf identity and parent dependency invalidation were correct, so that patch was excluded.
Validation
swift test --filter 'CostUsageCacheTests|CostUsageScannerBreakdownTests': 89 tests passedmake check: passed; SwiftFormat clean and SwiftLint reported 0 violationsCanonical routing
Implementation credit and runtime-evidence credit are separate: the core code belongs to #2118/@xx205, while each contributor's frozen-corpus results retain their own provenance.