Codex (limited)
Codex is OpenAI's coding CLI. It is supported, not the main harness: Claude Code is the harness the rest of this handbook assumes, and this section holds only what differs when you run Codex instead. Read Start here first; its Step 2 has a Codex variant, shown below this chapter.
What a Codex seat is
A Codex seat is the native codex binary running in a herdr pane. It carries the UCC skills through one symlink and reaches the daemon through Codex's own hooks, so after its first turn it has a card and a live row in the fleet like any other seat. What it does not have is the Meridian MCP server: no put, no sql, no board or memo writes, no fleet verbs. Its record access is mrd read, its output is a report file, and its human contact is a Codex tool, not the fleet's Telegram path.
flowchart LR you[You] -->|herdr agent start --kind codex| seat[Codex seat] seat -->|hooks.json| daemon[ccc-statusd] daemon --> card[Card + fleet row] seat -->|mrd read root:path| root[(Sessions root)] seat -->|curl, with network_access| pages[page.sui.pics records] seat --> report[Report file] seat --x|no put, no sql, no ccc-agent| root
Two directions share the name, so keep them apart:
| You run | What it is | Where it belongs |
|---|---|---|
codex inside herdr |
the native Codex CLI — this section | short, read-only work: records read, a report file written |
ucc-codex and your codex-gpt* profiles |
Claude Code on a GPT model through a local proxy (ucc-cli codex ensure starts it; no /login) |
the Start here chapter — a normal Claude Code seat with the full MCP |
The recommended way to take part in the fleet is the second row: a UCC gateway profile is a Claude Code seat on your ChatGPT-backed model and gets every Meridian tool. Native Codex is for when you want Codex itself.
What is installed for Codex
| Piece | Where it comes from | Shows it |
|---|---|---|
| Codex CLI binary | OpenAI's install | codex --version |
~/.codex/skills/ucc → $UCC_HOME/shared/skills |
the ucc installer, refreshed by every ucc-cli update |
readlink ~/.codex/skills/ucc |
[features] hooks = true in ~/.codex/config.toml |
you, once, or herdr integration install codex writes it; without it the installer prints one WARN and writes nothing |
grep -n 'hooks = true' ~/.codex/config.toml |
the three _ccc entries in ~/.codex/hooks.json |
the ucc installer, at the end of SessionStart, UserPromptSubmit, Stop |
grep -c '"_ccc"' ~/.codex/hooks.json → 3 |
| herdr integration | herdr integration install codex, once per account and again after a herdr update |
herdr integration status → codex: current (v<n>) |
The skills link goes into ~/.codex/skills, never over it: ~/.codex/skills is a real directory holding Codex's own skills. Codex reads skills at session start, so a skill added to the tree is visible to the next codex, not the running one. Instructions come from AGENTS.md, never CLAUDE.md, found by walking up from the pane's working directory — start the pane in the tree you are working on, not in a wiki or sessions directory.
hooks.json accepts only description and hooks at the top level. One foreign top-level key makes Codex refuse the whole file with a single startup line, and then no hook runs at all — no card, no fleet row, no dialog.
The network setting
Codex runs commands in a sandbox. Under sandbox_mode = "workspace-write" the sandbox has no network: a prompt that names a URL fails with curl: (6) Could not resolve host. The key that opens the network and nothing else is:
[sandbox_workspace_write]
network_access = true
in ~/.codex/config.toml (the same key per invocation: codex -c sandbox_workspace_write.network_access=true). Every handbook prompt ends with the web address it lives at, which the seat re-reads, so set it before your first session. sandbox_mode = "danger-full-access" also passes but grants far more than a fetch needs. Codex's own web tool is not the path that carries these fetches; curl in the sandboxed shell is, and that is exactly what this key governs.
Starting a seat
A native seat starts inside herdr, never through ccc-agent spawn (it appends --session-id, which Codex refuses) and never through a ucc-codex* wrapper (that is Claude Code on a proxy). The pane sequence, run from any herdr pane:
herdr pane split --current --direction right --cwd <tree under work> --no-focus \
--env HERDR_AGENT= --env UCC_PROFILE= --env CLAUDE_CONFIG_DIR= --env CCC_ROLE= --env CCC_CARD_SEED=
herdr agent start <name> --kind codex --pane <pane id>
herdr agent read <name> --source visible # a dialog may be up
herdr agent prompt <name> "<one sentence>" --wait --timeout 180000
herdr agent get <name> # .result.agent.agent_session.value = the Codex session id
herdr pane close <pane id>
The name matches [a-z][a-z0-9_-]{0,31}. Clearing the five environment variables matters: empty reads as absent, so the card is born role: worker with no leaked seed.
Two dialogs can sit on the screen while herdr agent start already reports interactive_ready: true, so read the pane after every start:
- Hooks need review — N hooks are new or changed, once per host and again whenever a hook entry's bytes change. Answer option 2, Trust all and continue:
herdr agent send-keys <name> down enter. Option 3 persists nothing and asks again next time. - Do you trust the contents of this directory?, once per directory Codex has not seen. Answer option 1, Yes, continue:
herdr agent send-keys <name> enter.
Codex signs in with your ChatGPT account through its own sign-in, not through /login.
Identity
SessionStart fires at the first prompt, not at process start. Until the seat's first turn there is no card, no id in herdr agent get and no row in ccc-agent list --table. After it, the seat is a daemon/live/worker row.
Codex session ids are UUIDv7. The short id is the last 8 hex characters, not the first 8: the first 8 are a timestamp every seat born in the same minute shares.
What the seat can and cannot do
Can:
- Read any record —
mrd read 'sessions:<path>'(the root-qualified form works from any working directory),--section <n>for one section. The transcript in the Codex variant of Step 2 below shows it. - Fetch a handbook record by URL with
curl, once the network key is set. - Be a fleet seat — card, daemon row, the developer-message context the daemon injects each turn.
- Ask its own user and run its own sub-agents through Codex-native tools (
request_user_input; thecollaboration.*family). These reach Codex only: they are not fleet verbs and do not reach the fleet's Telegram relay. - Write a report file in its working directory. That file is the proof of its work.
Cannot:
- Write any record. There is no Meridian
puttool in the seat — no memos, cards, rosters, board moves. ThemrdCLI's write doors refuse or need a workspace the pane does not sit in; an able model driving it landed nothing in four attempts. - Use any
ccc-agentverb (spawn,send,screen,transcript,wait,get,list,kill) or any lifecycle verb (session killme,restart,forkme,schedule). Its exit is the spawner'sherdr pane close. - Reach the fleet's AskUserQuestion-to-Telegram path or receive hook sensors (
tokens>,idle>,auq>). A question for a human that its own tool cannot settle becomes an open item in the report. - Be prompted from outside except by
herdr agent prompt. Accc-statusd session sendfrom its shell arrives asfrom="cli", so the reply line must carry the agent name and the report path.
skill: ccc-native — the seat's own contract: its verbs, its must-not list, the reply protocol, and references/codex.md for every setup detail above.