Skip to content

fix(codex): a Codex session's hooks reach it even with Codex's shared daemon - #131

Merged
sean-brydon merged 1 commit into
cosscom:mainfrom
Stener1:codex-no-daemon
Oct 16, 2026
Merged

sean-brydon merged 1 commit into
cosscom:mainfrom
Stener1:codex-no-daemon

Conversation

@Stener1

@Stener1 Stener1 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Refs #8: its shared-daemon part. (#71 fixed the notify part.)

Reproduced on Codex 0.163.0

Four Codex sessions through Shipyard, in one scratch repo on a Linux box:

Session Started with Where its hook events landed
cx8-a daemon allowed (first) started the shared daemon, which got BERTH_SESSION=cx8-a
cx8-b daemon allowed on cx8-a: SessionStart, prompt, tool, Stop and notify. cx8-a was even renamed after cx8-b's prompt, and turn check judged cx8-b's turn on cx8-a
cx8-c daemon_auto_start = false on cx8-a too: it joined the daemon that was already running
cx8-d codex --no-daemon on cx8-d, correct, with the daemon still running

cx8-b and cx8-c never got a hook event of their own: they were read off their screens only, and their finished-turn reports had no reply or transcript, while cx8-d's did. The daemon is Codex's own managed copy (~/.codex/packages/app-server-daemon/…), started by the first session with that session's environment.

Change

  • --no-daemon for an interactive Codex (codexdaemon.go). AgentCommandWith (new sessions) and handoff's codex resume add it when the installed Codex lists it in its --help. That's read once per binary (path and mtime), so a Codex without the flag still starts. Claude and the other agents are untouched, and so are the structured driver and headless runs, which don't use the TUI.
  • The ledger doesn't take a Codex hook's session name on trust (Turns.claimed, used by resolve and SessionOf). An event about a conversation (agent_session_id) another live session holds goes to that session. One from a folder other than the named session's goes by its folder, as an unnamed event does. This covers a Codex under a daemon anyway (a repo's own command, an older Codex). Two sessions in one folder still can't be told apart until one has held its conversation. Other agents are taken by name as before.

Tests

  • TestACodexDaemonsHooksReachTheirOwnSession replays the repro's pattern. It fails with the guard turned off.
  • TestAgentCommandsPassAModelAndAnEffort covers the flag, with and without support, and not adding it twice.
  • go vet ./..., go test -race ./internal/box/ ./internal/integrations/... pass. Checked against this box's real Codex 0.163.0, the preset's command is codex --no-daemon 'hi'.

🤖 Generated with Claude Code

https://claude.ai/code/session_01V7UV6sY16AabsdHtcyxyjL

… daemon

Codex can run every session from one shared app-server daemon, and the
daemon runs hooks with the environment of the session that started it. So
with two Codex sessions on a box, every hook (prompt, tools, Stop, notify)
reported the first session's BERTH_SESSION: the second session's work
showed on the first, which was even renamed after its prompt, and the
second was only ever read off its screen. A session started with
daemon_auto_start = false still joins a daemon something else started.

berthd now starts an interactive Codex (a new session, or a handoff that
resumes one) with --no-daemon when the installed Codex lists it in its
--help, read once per binary. --no-daemon keeps it off a daemon even one
that is already running.

For a Codex that runs under a daemon anyway (a repo's own command, an
older Codex), the ledger no longer takes a Codex hook's session name on
trust: an event about a conversation another live session holds is that
session's, and one from a folder other than the named session's goes by
its folder. Two sessions in one folder still can't be told apart that way
until one has held its conversation.

Refs cosscom#8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V7UV6sY16AabsdHtcyxyjL
@vercel

vercel Bot commented Oct 16, 2026

Copy link
Copy Markdown

@Stener1 is attempting to deploy a commit to the seanbrydonio's projects Team on Vercel.

A member of the Team first needs to authorize it.

@sean-brydon
sean-brydon merged commit 244719c into cosscom:main Oct 16, 2026
0 of 2 checks passed
@Stener1
Stener1 deleted the codex-no-daemon branch October 16, 2026 15:31
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.

2 participants