fix(codex): the RC pane drives sign-in and pairing itself - #180
Merged
Conversation
A codex Remote Control session printed two commands and told the user to
open a second (shell) session to paste them. That second session is the
onboarding problem, not the fix for it: the pane is the only thing a new
box hands you, and it was a read-only status view.
The supervisor wrapper now runs the flow in the pane it already owns:
`codex login --device-auth` when the box is logged out (URL + one-time
code print right there), then `codex remote-control pair` once it isn't.
Enter re-runs whichever step is outstanding — normally minting a fresh
pairing code, since codes expire quickly.
Details worth knowing:
- `codex login --device-auth` REMOVES ~/.codex/auth.json as it starts and
does not restore it if the flow is abandoned, so it runs only behind a
`login status` guard. Verified on a live box: an aborted run leaves it
logged out.
- Typing `login` is the escape hatch Enter can't be: with a stale token
`login status` still succeeds while pairing keeps failing, so it drops
the credentials first and re-authenticates.
- The first pairing call after a cold daemon start races enrollment
("timed out waiting for remoteControl/pairing/start response", or
"pairing is unavailable until enrollment completes"); it is retried
twice, re-enabling Remote Control before the last try, instead of
surfacing a transient error.
- The 5s daemon health probe is now a `read` timeout, so the pane takes
keys without dropping supervision. Reading is skipped where there is no
terminal, and abandoned on EOF (Ctrl-D) — either would spin the loop.
Refs #159 (items 1 and 5 for codex); the RC-singleton guard and the
initialPrompt caveat there are still open.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN
This was referenced Aug 4, 2026
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.
Motivation
A codex session with
remoteControl = trueprinted the two onboarding commands and told the user to run them from "any other shell on the box — open another terminal tab, oragent-box-session add sh --agent shell". Needing a second session to get the first one working is the onboarding problem; the pane is the only thing a fresh box hands you. Follow-on to #159 (items 1 and 5), which #161 only partly addressed by making the pane report state.What changed
codexRemoteControlnow drives the flow in the pane it already owns:codex login --device-authin the pane. The verification URL and one-time code print there; the command blocks polling until the browser side finishes, which is exactly the foreground behaviour the pane wants.logindrops the stored credentials and re-authenticates. This is the one state Enter cannot fix: with a stale token or the wrong account,codex login statusstill succeeds while pairing keeps failing, and the device-auth guard (correctly) declines to run.Supporting fixes in the same wrapper:
readtimeout, so the pane accepts keys without dropping supervision. It exits 0 when the daemon dies exactly as before, so the reconcile loop still respawns it.timed out waiting for remoteControl/pairing/start response, orpairing is unavailable until enrollment completes.Security / safety effects
codex login --device-authremoves~/.codex/auth.jsonas it starts and does not put it back if the flow is abandoned — verified on a live box, which is how the deployed box briefly lost its login during this work (restored from a backup). So it is called only behind alogin statusguard, never on a box that is already signed in, and the destructive re-auth path sits behind a typed word rather than the Enter that mints pairing codes. Pairing codes are short-lived and only ever printed to a pane that already requires the box's web password.No new privileges, no new sudo rules, no network surface, no AWS/IAM/cost impact.
Checks run
Native
aarch64-linux(this box), all passing:nix run .#assemble(regenerated module committed)nix build -L .#checks.aarch64-linux.{module-generated-up-to-date,module-single-file,multi-user,download-route,webhook-route}cfn-lint aws/template.yaml(clean)Behaviour was exercised end to end by extracting the generated wrapper and running it in a real tmux pane:
CODEX_HOME, real codex → pane printed the device-auth URL + code itselfpairwas retried transparentlylogindropped them, re-ran device auth, then pairedThe
sessionsVM test gained a regression assertion (pane drives sign-in; no copy-paste command list, no "open a shell session" advice). It isx86_64-linux-only, so CI runs it, not this box — a NixOS test needs a same-arch KVM guest.Still open from #159
The RC-codex singleton guard (item 4) and the
initialPrompt-is-discarded caveat (item 6) are untouched.🤖 Generated with Claude Code
https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN