Skip to content

feat(desktop): codex attach-rung resolver (L4a) - #567

Closed
physercoe wants to merge 1 commit into
feat-vision-f4-user-mcp-reseedfrom
feat-vision-l4a-codex-attach
Closed

feat(desktop): codex attach-rung resolver (L4a)#567
physercoe wants to merge 1 commit into
feat-vision-f4-user-mcp-reseedfrom
feat-vision-l4a-codex-attach

Conversation

@physercoe

Copy link
Copy Markdown
Owner

Stacked on #566 (F4) — base is that branch, so this diff is the single L4a commit. Its plan edit builds on the status line F4 adds. Merge #566 first; I'll rebase this onto main after.

L4's plan line specified a WebSocket attach to a codex app-server daemon, authenticated with a bearer scheme, with stdio spawn-per-session as "the fallback rung only".

Measured against the installed codex-cli 0.147.0, all three parts are wrong. This lands the corrected decision as a pure, tested resolver before any driver is written against it — building the WebSocket client the plan describes would have been a dead end.

What codex actually ships

  1. The shared-daemon transport is a Unix domain socket, not a WebSocket, and there is no bearer scheme. codex app-server daemon start brings the daemon up; codex app-server proxy --sock <path> pipes stdio to its control socket at <CODEX_HOME>/app-server-control/app-server-control.sock. The --code-mode-host <WS_URL> flag that exists is a different feature (where code mode runs), not the session transport. So the attach rung needs no WebSocket client and no token — it's the same JSON-RPC-over-stdio we already speak, pointed at another process.

  2. "Spawn it detached if absent" isn't available. daemon start refuses unless codex was installed by the official installer script, wanting the managed binary at <CODEX_HOME>/packages/standalone/current/codex:

    managed standalone Codex install not found … This command requires the standalone install managed by the Codex installer, because the daemon starts and updates app-server from that fixed path.

    An npm / homebrew / distro codex — including this machine's /usr/lib/node_modules/@openai/codex — has no daemon rung at all.

  3. The rung order inverts. Per-session stdio isn't a fallback; for the common install it's the only rung. The daemon is an opportunistic upgrade when the managed install is present.

Also measured: the control socket is subject to the platform SUN_LEN cap (~104–108 bytes). A deeply relocated CODEX_HOME fails at connect time with path must be shorter than SUN_LEN — a message nobody would attribute to path length — so the resolver disqualifies the daemon rung up front and returns a reason saying why. CODEX_HOME relocation is honoured for both the socket and the managed-binary probe, the same way #566 honours CLAUDE_CONFIG_DIR.

(Incidentally: the CLI here is 0.147.0, not the 0.133.0 E3 was written against — it moved under us.)

Scope

The install probe is an input, so the whole decision table is unit-testable with no codex on the box. Every rung returns a reason sentence: a user whose session isn't shared with their TUI should be able to find out why without reading code.

7 tests, 5 mutations checked, all killed. Electron suite 634 pass / 0 fail, tsc clean, doc lints green.

L4b is still to do — the app-server JSON-RPC driver over whichever argv this returns, delta throttling, R1 approval cards, turn/interrupt, config seeding.

L4's plan line specified a WebSocket attach to a `codex app-server`
daemon, authenticated with a bearer scheme, with stdio spawn-per-session
as "the fallback rung only". Measured against the installed codex-cli
0.147.0, all three parts are wrong, so this lands the corrected decision
as a pure, tested resolver before any driver is written against it.

  - The shared-daemon transport is a UNIX DOMAIN SOCKET, not a
    WebSocket, and there is no bearer scheme: `codex app-server daemon
    start` brings the daemon up, `codex app-server proxy --sock <path>`
    pipes stdio to its control socket at
    <CODEX_HOME>/app-server-control/app-server-control.sock. The
    `--code-mode-host <WS_URL>` flag is a different feature (where code
    mode runs), not the session transport. The attach rung therefore
    needs no WebSocket client and no token — it is the same
    JSON-RPC-over-stdio we already speak, pointed at another process.

  - "Spawn it detached if absent" is not available. `daemon start`
    refuses unless codex was installed by the official installer script,
    wanting the managed binary at
    <CODEX_HOME>/packages/standalone/current/codex. An npm / homebrew /
    distro codex — including this machine's — has no daemon rung at all.

  - So the rung order inverts: per-session stdio is not a fallback, it
    is the only rung for the common install, and the daemon is an
    opportunistic upgrade.

Also measured: the control socket is subject to the platform SUN_LEN cap
(~104-108 bytes). A deeply relocated CODEX_HOME fails at connect time
with "path must be shorter than SUN_LEN", which nobody would attribute
to path length — so the resolver disqualifies the daemon rung up front
and returns a reason saying so. CODEX_HOME relocation is honoured for
both the socket and the managed-binary probe, the same way F4 honours
CLAUDE_CONFIG_DIR.

The probe (does the managed binary exist?) is an input, so the whole
decision table is unit-testable with no codex on the box. 7 tests, 5
mutations checked, all killed. Electron suite 634 pass / 0 fail, tsc and
doc lints green.

L4b — the app-server JSON-RPC driver over whichever argv this returns,
delta throttling, R1 approval cards, turn/interrupt, config seeding —
is still to do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@physercoe

Copy link
Copy Markdown
Owner Author

Superseded: a PR based on a feature branch gets ZERO CI in this repo (pull_request: branches: [main]), so stacking is strictly worse than a doc conflict here. Reopened against main — and both #565 and #566 have since landed, so the plan status line merges cleanly.

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