fix(codex): guide the RC session and give it a usable machine name - #161
Open
defangdevs wants to merge 1 commit into
Open
fix(codex): guide the RC session and give it a usable machine name#161defangdevs wants to merge 1 commit into
defangdevs wants to merge 1 commit into
Conversation
A codex session with remoteControl = true showed one line of daemon-start JSON and then nothing, forever. It is not a TUI, so typing did nothing, and nothing said that Remote Control cannot enroll until someone signs in — while README told the quickstart user to complete sign-in in that very tab. Pairing then failed with "remote control pairing is unavailable until enrollment completes", which never mentions login, and the flow that actually works headless (`codex login --device-auth`) appeared nowhere in this repo. Replace the blank pane with a status screen: what the pane is, the machine name, and whichever of sign-in / pairing is outstanding, with the exact commands. Sign-in happens in another tab, so the health loop polls for the transition and confirms when it lands. Daemon-start JSON goes to the log instead of being the first impression, and both failure paths now say what failed and point at app-server.stderr.log rather than dumping into an unexplained post-mortem shell. Also fix the name the Codex apps show. It came from gethostname(2) — the internal cloud fqdn — and codex offers no override: HOSTNAME does not occur in the binary, every candidate -c key is rejected by --strict-config, and disassembly shows the gethostname crate result fed straight to the serverName notification. networking.hostName cannot hold a dotted public name either (NixOS types it strMatching without dots). So the wrapper re-execs in a private UTS namespace whose hostname is hostLabel — the same public address claude sessions already use. The user namespace is unprivileged (--keep-caps grants CAP_SYS_ADMIN inside the namespace only, uid unchanged), and unshare execs in place, so the wrapper keeps its pid and its trap-based daemon teardown. Verified on an aarch64 box: serverName goes from ip-10-42-1-247.eu-central-1.compute.internal to 3.79.168.78.sslip.io, read back via `codex app-server` on stdio with a throwaway CODEX_HOME. Refs #159. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN
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 the first three items of #159.
Before
A codex session with
remoteControl = true(the default) showed this, then nothing, forever:Not a TUI, so typing does nothing. No indication that Remote Control cannot enroll until someone signs in — while
README.md:43told the quickstart user to complete sign-in in that exact tab. Pairing failed withremote control pairing is unavailable until enrollment completes, which never mentions login, andcodex login --device-auth— the only flow that works on a headless box — appeared nowhere in this repo.After
The pane is a status screen: what it is, the machine name, and whichever step is outstanding with the exact command to run. Sign-in happens in another tab, so the existing health loop polls for the transition and confirms when it lands. Daemon-start JSON goes to the log rather than being the pane's first impression, and both failure paths now name what failed and point at
app-server.stderr.loginstead of dumping into a silent post-mortem shell.The machine name
Codex takes it from
gethostname(2), so the apps showed the internal cloud fqdn. There is no override —HOSTNAMEdoes not occur in the binary, every candidate-ckey is rejected by--strict-config, and disassembly shows thegethostnamecrate result fed straight to theserverNamenotification.networking.hostNamecannot hold a dotted public name either (nixos/modules/tasks/network-interfaces.nix:564types itstrMatchingwith no dots).So the wrapper re-execs inside a private UTS namespace whose hostname is
hostLabel— the same public address Claude sessions already use. The user namespace is unprivileged:--keep-capsgrantsCAP_SYS_ADMINinside the new namespace only, uid unchanged, conferring nothing outside.unshareexecs in place, so the wrapper keeps its pid and its trap-based daemon teardown, and the daemon inherits the namespace after detaching.Verification
All on this aarch64 box:
nix-instantiate --parseon both.nixand.nix.in;assemble-module.py --checkconfirms the generated file is in sync.Generated wrapper extracted and
bash -nclean.UTS re-exec in the exact committed form:
uname -nis the public name inside, unchanged outside.End to end —
serverNameread back viacodex app-serveron stdio with a throwawayCODEX_HOME:serverNameip-10-42-1-247.eu-central-1.compute.internal3.79.168.78.sslip.ioNot verified: the VM tests, which are
x86_64-linux-only and need KVM — CI has to cover those. A codex session withoutskipPermissions(codex landlock/seccomp under a nested user namespace) is also untested.Note
Changing the reported name mints a new
server_idand replaces theremote_control_enrollmentsrow, so an already-paired box needs re-pairing once. Taken as acceptable pre-1.0 rather than designed around.Not in this PR (still open on #159)
initialPromptsilently discarded on RC codex sessions.aws/lightsail-template.yaml:552's stale "Codex has no Remote Control channel" — left alone to avoid conflicting with fix(lightsail): derive Remote Control name from the public host #156, which is already editing that block.🤖 Generated with Claude Code
https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN