Skip to content

codex/opencode: keep looking for the conversation id, not just for 45s - #18

Open
lvwerra wants to merge 1 commit into
mainfrom
codex/pin-recheck
Open

codex/opencode: keep looking for the conversation id, not just for 45s#18
lvwerra wants to merge 1 commit into
mainfrom
codex/pin-recheck

Conversation

@lvwerra

@lvwerra lvwerra commented Jul 31, 2026

Copy link
Copy Markdown
Member

A codex session that came back from a Space restart with its history gone (agent-manager-2 on the live Space) had no codexSessionId pin at all, so it launched codex resume --last and got a blank conversation.

The pin was missing because capture gave up too early. Codex writes NOTHING identifying to disk until the first message is submitted: measured on 0.146, an idle TUI produced no rollout file for 60s+, and one appeared within 3s of pressing enter. Capture polled at +5s/+15s/+45s and then stopped forever, so it only ever pinned sessions whose first message arrived inside that window. The Space's own history shows the split cleanly — every codex session whose rollout appeared within 11s of creation is pinned; every one that took 16s or longer (agent-manager-2 at 81s, my-assistant at 107s) is not.

Once unpinned, nothing retried, and the next launch fell through to codex resume --last. That resolves through codex's own thread index — state_5.sqlite under $CODEX_HOME, which lives on local disk and is wiped by every restart, then rebuilt from the rollouts at boot. This boot it rebuilt 17 of 18, missing exactly the agent-manager conversation, with its backfill cursor stranded on the previous file. No index row for that cwd means resume --last starts a FRESH thread and exits 0, so || exec codex can't even notice: the pane returns looking new. (A pin, by contrast, works with no index at all — codex resume <id> restored the full conversation from a CODEX_HOME holding only that rollout file.)

So keep looking for as long as the pane lives: the same opening ladder, then a steady 60s beat, ending when the pin lands or the session is gone. opencode gets the same treatment through a shared pollForPin — its ses_ row also only appears once the conversation has content, which its old 90s ceiling had the same problem with. Claude is untouched: it gets an id up front via --session-id, so its capture is only verifying a pin we already asked for.

Exercised against a live pane (isolated DATA_DIR + CODEX_HOME): a session left idle 75s before its first message — dead ground under the old ladder — got its rollout at t≈80s and was pinned on the following beat, and relaunching it brought the conversation back. An unpinned session abandoned at 20s stayed unpinned across two beats after a fresh matching rollout appeared in its folder, so an outlived loop can't hijack a later conversation.

A codex session that came back from a Space restart with its history gone
(agent-manager-2 on the live Space) had no `codexSessionId` pin at all, so it
launched `codex resume --last` and got a blank conversation.

The pin was missing because capture gave up too early. Codex writes NOTHING
identifying to disk until the first message is submitted: measured on 0.146, an
idle TUI produced no rollout file for 60s+, and one appeared within 3s of
pressing enter. Capture polled at +5s/+15s/+45s and then stopped forever, so it
only ever pinned sessions whose first message arrived inside that window. The
Space's own history shows the split cleanly — every codex session whose rollout
appeared within 11s of creation is pinned; every one that took 16s or longer
(agent-manager-2 at 81s, my-assistant at 107s) is not.

Once unpinned, nothing retried, and the next launch fell through to `codex
resume --last`. That resolves through codex's own thread index — state_5.sqlite
under $CODEX_HOME, which lives on local disk and is wiped by every restart, then
rebuilt from the rollouts at boot. This boot it rebuilt 17 of 18, missing
exactly the agent-manager conversation, with its backfill cursor stranded on the
previous file. No index row for that cwd means `resume --last` starts a FRESH
thread and exits 0, so `|| exec codex` can't even notice: the pane returns
looking new. (A pin, by contrast, works with no index at all — `codex resume
<id>` restored the full conversation from a CODEX_HOME holding only that rollout
file.)

So keep looking for as long as the pane lives: the same opening ladder, then a
steady 60s beat, ending when the pin lands or the session is gone. opencode gets
the same treatment through a shared pollForPin — its ses_ row also only appears
once the conversation has content, which its old 90s ceiling had the same
problem with. Claude is untouched: it gets an id up front via --session-id, so
its capture is only verifying a pin we already asked for.

Exercised against a live pane (isolated DATA_DIR + CODEX_HOME): a session left
idle 75s before its first message — dead ground under the old ladder — got its
rollout at t≈80s and was pinned on the following beat, and relaunching it
brought the conversation back. An unpinned session abandoned at 20s stayed
unpinned across two beats after a fresh matching rollout appeared in its folder,
so an outlived loop can't hijack a later conversation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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