Skip to content

Add pinned launchd supervisor for Codex Lab daemon #459

Description

@shiny-code-bot

Objective

Add a durable macOS launchd supervisor for the pinned Codex Lab app-server daemon without starting ChatGPT or enabling the upstream standalone updater.

Finish Line

Pinned Codex Lab daemon recovers after login, reboot, and crash without updater drift.

Current Status

  • PR Supervise the pinned websocket app-server with launchd #461 merged the versioned user LaunchAgent dev.everycode.codex-lab.app-server.v1. launchd directly owns the signed managed command ~/.codex-lab/packages/standalone/current/codex app-server --remote-control --listen ws://127.0.0.1:4766; no detached PID daemon or standalone updater participates.
  • PR Connect the desktop launcher to the supervised websocket engine #463 merged the packaged desktop gate. It validates the canonical runner, launchd state, exact executable and command, and listener ownership before launching the official app with CODEX_APP_SERVER_WS_URL=ws://127.0.0.1:4766/rpc and empty CLI/force/local-daemon overrides.
  • Crash canary: launchd replaced PID 27660 with PID 33872 in 15 seconds; the initialized desktop made websocket-only reconnect attempts and reinitialized without stdio_transport_spawned.
  • Login-equivalent canary: with ChatGPT stopped, explicit bootout/bootstrap replaced service PID 96852 with PID 12601 and restored the exact loopback listener.
  • Rollback/uninstall canary: uninstall produced installed=false, loaded=false, and listening=false with no runner or plist; reinstall validated signed engine SHA-256 67951ae1f698b68e7a3f359b771f05bf7c01b4c98ffbcc4a37686d20ff78525e and started healthy PID 18270.
  • Final merged-code desktop canary: ChatGPT PID 20662 initialized over websocket against service PID 18270 and source commit ee84ba5267e5a9e71c0e114def2c5b87f92f9fda through the five-second stability window.
  • The signed local-MVP supervisor finish line is complete. Automatic provisioning of a signed engine through the published release installer remains separate follow-up Provision signed engine and supervisor through installer #462.

Acceptance Criteria

  • A versioned user LaunchAgent starts the app-server at login without launching ChatGPT.
  • KeepAlive recovers an unexpected app-server crash without a restart loop on permanent configuration/provenance failure.
  • The supervisor directly invokes ~/.codex-lab/packages/standalone/current/codex app-server --remote-control --listen ws://127.0.0.1:4766 with both CODEX_HOME and CODEX_LAB_HOME pinned.
  • The supervisor does not bootstrap or start the standalone updater or detached PID daemon.
  • Status reports loaded/running state, exact executable and command, launchd PID, listener ownership, websocket URL, updater state, and actionable logs.
  • Install is idempotent and refuses a managed engine that is missing, unsigned, dirty, or not the expected candidate.
  • Uninstall stops/unloads only the Codex Lab LaunchAgent and leaves no stale plist, runner, PID-daemon, updater, or listener state.
  • Crash, login-equivalent bootout/bootstrap, and rollback/uninstall canaries pass on macOS with the final launcher.

Relationships

Validation

  1. Unit tests for plist generation, validation, idempotence, and rollback.
  2. Static plutil and launchctl bootstrap/print/bootout checks.
  3. Kill the managed app-server process and prove launchd recovery from the exact signed path.
  4. Bootout/bootstrap as a login-equivalent canary without launching ChatGPT.
  5. Uninstall and restore the previous engine with no stale launchd state.

Metadata

Metadata

Assignees

No one assigned

    Labels

    planDurable planning issueplan:donePlan completed or superseded

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions