Remote phone session appends to same thread while open CLI/TUI does not ingest remote events
What version of Codex CLI is running?
0.130.0
What subscription do you have?
Max (200)
Which model were you using?
gpt-5.5 (high reasoning)
What platform is your computer?
Darwin 25.2.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
cmux 0.64.6 (86) [2f96c15c2]
Codex doctor report
not available
What issue are you seeing?
I had a Codex CLI/TUI session open on my machine. I opened the same session
from my phone. The phone session appended user messages and agent work to the
same thread. The CLI/TUI remained open the whole time, but did not receive or
integrate those remote events into its live context. When I continued typing
in the CLI/TUI, it appended a second continuation from stale in-memory context
to the same JSONL transcript.
What steps can reproduce the bug?
Uploaded thread: 019e199a-3d58-7863-b06e-c84a99bd9a87
What is the expected behavior?
Expected:
If a remote client attaches to an existing live CLI/TUI session, remote events
should either:
- stream back into the CLI/TUI and update its live context, or
- be rejected/locked/forked explicitly so two clients cannot append divergent
continuations to one linear transcript.
Actual:
Both paths were appended to the same transcript file linearly, but the CLI-
side model context did not include the phone-side segment.
Additional information
_No response_
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
This is a useful failure mode to call out. The dangerous part is not just that the phone can append to the same transcript; it is that the live CLI/TUI process still has stale in-memory context, so the thread looks linear on disk while the active controller is effectively forked.
For a remote attach design, I would expect one of two explicit contracts: either the local live process remains the authority and ingests every remote event before continuing, or the remote client gets a hard fork/lock indication so two controllers cannot write divergent continuations.
I built Faryo as a narrow open-source experiment around the other model: keep Codex CLI running inside tmux as the single live process, and let phone/browser act as a thin control surface for compact output, short input, approvals/interrupts, and handoff. It is not a fix for Codex mobile, but it may be a useful comparison point for the "same live session, no second transcript writer" case: https://github.com/Snailflyer/faryo
A code-path trace seems to line up with this failure mode.
The exit/resume behavior follows from the current TUI path:
thread/resumereturns reconstructedthread.turns, and the TUI replays those turns into the chat widget. A still-running CLI/TUI session does not appear to tail or reload the thread store.turn/startresolves the already-loadedCodexThreadand submitsOp::UserInputagainst that in-memory session state; it does not refresh persisted history first.That makes the problematic sequence:
Perhaps the primary fix could be a live-session ownership invariant: while a thread is loaded, mobile/remote turns for that thread route through the same loaded app-server
CodexThreadand stream events to all subscribed clients.If that cannot be guaranteed for every path, a defensive guard could be added before accepting
turn/start: compare the loaded thread's expected store revision/watermark against the current persisted thread revision, and reject with a refresh-required conflict when the thread changed externally. That would prevent appending from stale in-memory context.updated_atalone may not be a strong enough correctness boundary because it is metadata/timestamp based and can be coalesced. A real opaque thread revision/watermark would be safer; for the local rollout store, an append-only file watermark such as byte length plus mtime/hash could be a practical starting point.