fix: resolve imported transfer threads when the ledger record diverges (#417)#469
Open
ayobamiseun wants to merge 1 commit into
Open
fix: resolve imported transfer threads when the ledger record diverges (#417)#469ayobamiseun wants to merge 1 commit into
ayobamiseun wants to merge 1 commit into
Conversation
openai#417) After a Claude session import completes, the companion looks up the imported thread in Codex's external_agent_session_imports.json by strict equality on source_path (Node realpathSync output) plus a content sha256 computed at lookup time. That match misses successful imports in two known ways: - Codex canonicalizes the recorded source path itself; on Windows Rust's canonicalization yields verbatim paths (\\?\C:\...) that never compare equal to realpathSync output. - A live Claude transcript keeps growing while the transfer runs, so the hash computed at lookup time trails the content Codex actually imported. Both cause /codex:transfer to fail with "did not record an imported thread" even though the import succeeded, identically for auto-detected and explicit --source paths. Snapshot the ledger before the import and fall back to records Codex appended during it: prefer an appended record whose source path matches after normalization (strip the verbatim prefix, unify separators, case-fold on Windows), else accept a single appended record. The strict match stays first so Codex-side dedup of unchanged sessions still resolves. The failure error now names the ledger path it searched. Fixes openai#417
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #417
Problem
/codex:transferconsistently fails withCodex reported that the Claude import completed, but did not record an imported thread— identically for auto-detected and explicit--sourcepaths — even though the import actually succeeds on the Codex side.After the
externalAgentConfig/importnotification fires,importedThreadIdForSourcelooks up the imported thread in$CODEX_HOME/external_agent_session_imports.jsonby strict equality onsource_path(NoderealpathSyncoutput) and a content sha256 computed at lookup time. That match misses real imports two ways:source_pathitself; Rust'sfs::canonicalizeyields verbatim paths (\\?\C:\Users\...) that never compare equal to Node'srealpathSyncoutput (C:\Users\...). The strict path match can never succeed — matching the reporter's Git Bash / Windows 11 environment where both invocations fail byte-for-byte identically..jsonlkeeps growing (the transfer invocation itself gets logged) between Codex hashing it at import time and the companion hashing it at lookup time — socontent_sha256diverges and the record is rejected.Either way the command exits 1 with an opaque error while a perfectly good imported thread sits in the ledger.
Fix
importExternalAgentSessionsnapshots the ledger before the import; when the strict match misses, the lookup falls back to records Codex appended during this import:\\?\verbatim prefix, unify\//separators, case-fold on win32),The strict path+hash match stays first so Codex-side dedup of an unchanged, already-imported session still resolves without any appended record. The failure error now also names the ledger path it searched instead of only pointing at app-server logs.
Tests
New fake-codex behavior
external-import-divergent-ledgersimulates real Codex: the ledger record gets a verbatim-prefixed, backslash-separatedsource_pathand a hash of content that differs from what the companion reads back (both #417 divergences at once). The new regression test:main:transferexits 1 withdid not record an imported threadthr_1and prints the resume commandAll 5 transfer tests pass; full suite 91/92 — the one failure (
resolveStateDir uses a temp-backed per-workspace directory) fails identically onmainwhen run inside a live Claude Code session (pre-existing #455, unrelated).Note: the
[DEP0190]deprecation warning mentioned in the issue is a separate stderr-noise concern (#452 territory) and is not addressed here.