Skip to content

fix(codex): import replacement rollouts and resolve parent history - #514

Open
GalaxyKW wants to merge 1 commit into
SaladDay:mainfrom
GalaxyKW:fix/codex-rollout-identity-and-parent-pages
Open

GalaxyKW wants to merge 1 commit into
SaladDay:mainfrom
GalaxyKW:fix/codex-rollout-identity-and-parent-pages

Conversation

@GalaxyKW

Copy link
Copy Markdown

After thread/revert, Codex can write replacement rollouts named rollout-...-<threadId>_<rolloutId>.jsonl while keeping <threadId> in session_meta.id. The CLI compares that ID only with the filename's trailing UUID, so it defers the entire replacement file. Child sessions can also remain deferred because the parent index finds only the original, older rollout.

Validate both UUIDs and require replacement metadata to match the logical thread ID, while retaining the physical rollout ID in request IDs so per-file event indexes do not collide. Resolve a parent's history across its rollout segments before applying the fork cutoff. For explicitly paginated replacements, select the segment active at the fork and follow physical history_base references, respecting their byte prefixes so discarded history is not treated as inherited replay. Creation ordering uses UTC metadata because filename timestamps are local wall time; event order within each file is preserved. Explicitly paginated replacement files retain ancestry metadata but reference their old history rather than copying its events, so their own live usage must not be filtered as parent replay.

Billable files with logical self-parent references or invalid replacement identities remain deferred without advancing the import cursor. Identical copies are not replayed twice; conflicting copies, missing timestamps, stale replicas, and ambiguous segment ordering retain conservative deferral. For replacement rollouts, parent snapshots validate their root identity from the same opened file used for the cache stamp. For paginated reconstruction, only the segment active at the fork can establish cutoff completeness. Invalid candidate identities, missing referenced segments, and incomplete referenced prefixes defer billable children without advancing their cursors.

Adapted from the merged desktop fixes farion1231/cc-switch#6905 and farion1231/cc-switch#8213, preserving the CLI's incremental import and parser/cache structure. Replacement ancestry follows Codex's replacement writer and its physical prefix reference semantics.

Validation (Rust 1.91.1, isolated HOME/config directories on Linux):

  • cargo fmt --check passes.
  • RUSTFLAGS="-D warnings" cargo check --lib --no-default-features and cargo test --lib --no-default-features --no-run pass, matching the Linux library-only CI build. cargo build --bin cc-switch and cargo test --doc also pass.
  • Library unit tests: 4,586 passed, 2 ignored. Binary unit tests: 10 passed.
  • All 41 integration targets: 544 passed, 13 failed. The same 13 failures reproduce on unchanged base 1b43ce6 in the same environment (running as root) across import_export_sync, prompt_commands, provider_commands, proxy_service, and workspace_commands; no new integration failures were introduced. The integration tests selected by Rust CI pass.
  • Plain cargo clippy fails on the existing clippy::reversed_empty_ranges error at src/cli/tui/ui/home_chart.rs:806, reproduced on unchanged base 1b43ce6. cargo clippy -- -A clippy::reversed_empty_ranges passes; the source is not changed to suppress it.
  • Twenty new regression tests cover replacement identity, request-ID separation, logical attribution, parent replay, UTC ordering, replicas, file replacement, reference-only fork/spawn replacements, physical history chains, discarded history, missing-parent recovery, repeated sync, and rebuilds.
  • 31 isolated CLI reproduction scenarios pass, including timezone changes, invalid identities, incremental append, parent-only recovery, reference-only fork/spawn replacements, discarded-history exclusion, historical fork selection, and repeated sync.
  • A sanitized local corpus no longer defers its eight affected rollouts: 5,206 requests for the sampled day versus 1 before the fix, with zero additional requests on repeat sync. Physical prefix offsets were remapped to preserve their boundaries after sanitization.

Scope: this keeps the existing token_count accounting model and replay path for parent families without replacement rollouts. Paginated parent reconstruction is limited to references within the same logical thread; cross-thread history projection remains conservatively deferred. Compaction responses whose cumulative token counters do not increase are still outside that model. The separate idle/completed-parent cutoff behavior discussed in #392 is also unchanged.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant