August 15, 2026 · How-to · Harness Engineering · Coding Agents · EN

How to Set Up a Four-Role Codex Room

Install an isolated Supervisor, Lead, Peer, and Review Codex room through Paseo: share one operator login, keep four runtimes apart, and leave ~/.codex under the operator's control.

How to Set Up a Four-Role Codex Room

How to Set Up a Four-Role Codex Room

Bản tiếng Việt

A Codex room is a four-role working environment — Supervisor, Lead, Peer, and Review — launched through Paseo. It is not a better prompt. It is a process harness around Codex: one operator login, four isolated runtimes, and a single coordinator that decides who is in the room.

This is the install guide. It also explains the three ownership rules that keep the room from eating the operator’s Codex home, mixing sessions, or growing a second unofficial coordinator inside each role.

The room complements a repository harness. The repository still needs routing, bounded tasks, and validation. The room decides which Codex process is allowed to do which kind of work.

What you are installing

Four roles share identity and durable tools. They do not share mutable state.

RoleJobDefault modelPaseo MCP
SupervisorWatch topology, relay the project owner’s intent, flag process problemsgpt-5.6-sol / mediumYes
LeadOwn technical outcome, split work, integrate, verify, decidegpt-5.6-sol / mediumYes
PeerExecute or investigate one Lead-assigned scopegpt-5.6-sol / mediumNo
ReviewRead a stable candidate and argue against it; never edit product codegpt-5.6-luna / maxNo

Paseo is the picker. Codex is the worker.

You choose a provider in Paseo
        |
        v
Paseo runs: codex-room <role>
        |
        v
codex-room-sync merges ~/.codex + the role overlay
        |
        v
~/.codex-runtime/<role>/config.toml
        |
        v
Codex starts with that role's CODEX_HOME

Current overlays request danger-full-access and approval_policy = "never". Treat that as a trusted-operator default, not a public-machine default.

Three rules that make the install safe

1. ~/.codex stays with the operator

The setup reads ~/.codex/config.toml and symlinks auth, skills, plugins, hooks, and the global AGENTS.md. It never installs files into ~/.codex.

That split is the whole point of a shareable room:

Do not package auth with shared config
  -> each operator logs into Codex on their own machine
  -> the setup repo can be copied without copying tokens
  -> a password change or skill update in ~/.codex takes effect through the symlink

If ~/.codex is missing or incomplete, stop. The installer will not invent an auth file for you.

2. Each role gets its own CODEX_HOME

The four expected runtimes are:

~/.codex-runtime/supervisor
~/.codex-runtime/lead
~/.codex-runtime/peer
~/.codex-runtime/review
Shared by symlinkIsolated per role
auth.jsonconfig.toml
AGENTS.mdsessions/
hooks.jsonlogs, memory, queue
skills/SQLite and other runtime state
plugins/processed model catalog

A Review session does not land in Lead history. Both still use the same Codex account.

3. Paseo owns topology; native Codex agents stay off

The generated runtime turns native agents off:

  • [agents].enabled = false
  • multi_agent = false and multi_agent_v2 = false
  • multi_agent_version stripped from the generated model catalog

If those flags stay on, Paseo coordinates four roles while Codex quietly creates more agents inside a role. Ownership and handoff become un-auditable. That is a coordination failure, not a model failure.

Know the four file kinds before you edit anything

KindExampleEdit it?
Source templatehome/.config/codex-room/overlays/lead.config.tomlYes — this is the lasting change
Installed HOME copy~/.config/codex-room/overlays/lead.config.tomlOnly as a temporary patch; copy the change back to source
Generated runtime~/.codex-runtime/lead/config.tomlNo
Private stateauth, sessions, logs, databases, keypairsNever package or share
Want a lasting change
  -> edit the template in the setup repo
  -> install it into HOME
  -> regenerate that role's runtime

Editing ~/.codex-runtime/lead/config.toml by hand is the most common setup mistake. The next sync regenerates the file.

Prerequisites

You need a Unix-like machine (macOS is the tested path) with:

  • Bash, Python 3, Git, Node, npm, and jq
  • Codex installed and authenticated
  • ~/.local/bin on PATH
  • a ~/.codex tree that already has config.toml and auth.json

Optional but required for the Desktop picker: access to the Paseo fork remote. The installer does not create SSH keys or GitHub credentials.

Confirm the machine before touching HOME:

git clone <codex-room-setup-url> codex-room-setup
cd codex-room-setup
./scripts/doctor

doctor fails closed if Codex, Python, Git, jq, Node, npm, or ~/.codex is missing. It warns, and does not fail, when ~/.local/bin is off PATH or the Paseo checkout is not there yet.

Install sequence

Dry-run is the default. The installer never writes to ~/.codex or ~/.codex-runtime.

./scripts/install                 # dry-run: list CREATE / REPLACE
./scripts/install --apply         # backup, then write HOME copies
./scripts/install-paseo-fork      # clone or verify ~/projects/supervisors/paseo
./scripts/sync-all                # materialize four CODEX_HOME directories
./scripts/verify                  # check installed files and runtimes

Replaced files land under:

~/.codex-room-backups/install-<UTC timestamp>/

install-paseo-fork clones or verifies remotes. It does not pull or build an existing checkout. After the fork exists at ~/projects/supervisors/paseo:

paseo-local-update

That command updates the checkout, installs dependencies, builds and signs the local Desktop app, backs up the previous /Applications/Paseo.app, restarts the daemon, and opens Paseo. Run it only when no important agent turn is in flight.

Then confirm the live picker:

./scripts/verify --live

--live asks the local daemon for its provider inventory and checks that codex-supervisor, codex-lead, codex-peer, and codex-review are all present.

What lands in HOME

The home/ tree is a miniature $HOME. Installation renders @@HOME@@ placeholders to the operator’s real home.

SourceDestination
home/.config/codex-room/~/.config/codex-room/
home/.local/bin/codex-room*~/.local/bin/
home/.paseo/config.json.template~/.paseo/config.json

The important pieces:

  • model-instructions.md — shared working style for every role
  • overlays/*.config.toml — per-role model, sandbox, approval, and developer_instructions
  • workflow/ — room constitution, anti-patterns, Supervisor notebook template
  • codex-room — thin launcher: sync, then exec Codex
  • codex-room-sync — the runtime generator
  • Paseo provider catalog — four custom providers and the MCP injection boundary

MCP injection is limited to Supervisor and Lead:

["codex-supervisor", "codex-lead"]

Peer only needs the assigned scope. Review needs a small, independent tool surface. Review also has inherited mcp_servers tables stripped from the generated config. That is a second fence, not a substitute for the Paseo allowlist.

How one launch actually works

Choosing Codex Peer in Paseo is not “start Codex with a different system prompt.” It is a six-step pipeline.

  1. Paseo reads the rendered command, for example ~/.local/bin/codex-room peer.
  2. The launcher calls codex-room-sync peer.
  3. Sync merges the operator base, the Peer overlay, a live model catalog from codex debug models, and the native-agent kill switches.
  4. Sync links shared auth, skills, plugins, and workflow files into ~/.codex-runtime/peer.
  5. The launcher sets CODEX_HOME=~/.codex-runtime/peer and replaces itself with Codex.
  6. Codex writes the new session under the Peer runtime. Lead and Review do not see that session as their own.

Sync runs immediately before every launch so an overlay edit that has already been installed is visible on the next start.

codex-room-sync writes configs atomically (temp file, then replace) and refuses to clobber a real file that should have been a symlink. If a runtime path is a regular file instead of a link, the script stops.

First useful session

The room is installed when all of these are true:

  • Paseo shows four custom Codex providers
  • ~/.codex-runtime/{supervisor,lead,peer,review}/config.toml exist
  • Review has no inherited [mcp_servers.*] tables
  • each runtime config contains multi_agent = false

Do not start by asking four roles to build a feature in parallel. Start with one bounded outcome:

  1. Lead names the outcome, the write scope, and the proof command.
  2. One Peer owns that write scope. No second Peer writes the same files.
  3. Review reads a stable commit or snapshot and returns findings as evidence → consequence → how to refute → smallest fix.
  4. Lead accepts or revises. Review does not issue ACCEPT or REVISE.

That sequence is the room constitution in one pass. It matches the evidence-handoff pattern: the writer proves the change, an independent reader tries to refute a frozen candidate, and the Lead decides from artifacts rather than from role seniority.

A Peer may return three signals instead of more code:

  • REOPEN_REQUEST — the technical premise is wrong
  • DEPENDENCY_REQUEST — a prerequisite has no owner
  • BLOCKED — no safe next step remains in the current scope

Those signals are cheaper than a cache added to hide a split source of truth.

The repository still has to be readable. If the project has no AGENTS.md, validation matrix, or “do not touch” list, prepare that first with How to Prepare Your Repository for Codex. A well-isolated room on an illegible repo still guesses.

Customize after the first successful launch

Change source, then install, then sync. make test covers the Python suite and a syntax check of the shell scripts.

Change a role’s default model

Two surfaces must stay in sync:

  1. home/.config/codex-room/overlays/<role>.config.toml — Codex process default
  2. home/.paseo/config.json.template — Paseo picker default

Then:

make test
./scripts/install --apply
./scripts/sync-all <role>
# restart Paseo only when no agent is running
./scripts/verify --live

If you change only the overlay, the runtime moves and the picker lies. If you change only Paseo, the UI moves and the process keeps the old default.

Change how Lead splits work

Edit developer_instructions in the Lead overlay. That field is already on the overlay allowlist, so codex-room-sync does not need a code change. A running Lead session keeps old context until you start a new process against the regenerated runtime.

Lower danger-full-access

Every overlay and every Paseo provider param currently asks for full access with approval_policy = "never". To reduce that, inspect all four surfaces together: the overlay, the Paseo params, the tools the role actually needs, and the security invariants already encoded in tests.

A read-only Review sandbox sounds correct until OCR preview needs to write local session metadata. Check the real write path first. Review can fail while still being “behaviorally read-only.”

Do not add a fifth role unless the job is permanent

A new role is not “another TOML file.” At minimum you must update ROLE_FILES in codex-room-sync, the overlay, the Paseo provider, role-validation rules, MCP and tool boundaries, the shipped file list, model/runtime invariants, and the ownership docs. If the work is a temporary Peer hat — implementer, scout, reviewer — keep it as a Peer task.

Lab or throwaway tests

codex-room-sync honors isolation variables such as CODEX_ROOM_LAB_ROOT, CODEX_ROOM_RUNTIME_ROOT, CODEX_ROOM_CANONICAL_HOME, CODEX_ROOM_CONFIG_HOME, CODEX_ROOM_MODEL_CATALOG, and CODEX_BIN. Use them to generate a runtime somewhere other than the real HOME.

Common setup failures

“I edited the runtime config and the change vanished”

The runtime is generated output. Edit ~/.codex/config.toml for a change that should apply to every role. Edit the role overlay for a change that should apply to one role. Then install and sync.

“Paseo does not show the four providers”

Check in this order:

  1. jq . ~/.paseo/config.json is valid JSON
  2. each command points at ~/.local/bin/codex-room
  3. ~/.local/bin is on the daemon’s PATH, not only the interactive shell
  4. Paseo was restarted after the config change
  5. ./scripts/verify --live sees the four providers

If the PID file and the process listening on 127.0.0.1:6767 disagree, diagnose before deleting state:

cat "$HOME/.paseo/paseo.pid"
lsof -nP -iTCP:6767 -sTCP:LISTEN

A wrapper PID and a child Node PID can differ.

“Review is called read-only but the config is full access”

Read-only is a contract in developer_instructions. Sandbox enforcement and instruction enforcement are different layers. Do not treat the current Review profile as a hard sandbox on an untrusted machine.

“Should I share a runtime snapshot or a session?”

A reviewed summary can go into a shared workspace on purpose. A raw session should not. Sessions can contain prompts, tool output, local paths, and secrets.

codex-room-sync cannot find a shared resource”

The operator ~/.codex tree is incomplete. The setup will not create the missing file. Restore it from the operator’s own Codex install.

Setup checklist

  • Codex is installed and ~/.codex/auth.json exists
  • ~/.local/bin is on PATH
  • ./scripts/doctor reports DOCTOR_OK
  • ./scripts/install dry-run looks right
  • ./scripts/install --apply wrote HOME copies and a backup
  • Paseo fork exists at ~/projects/supervisors/paseo
  • ./scripts/sync-all created four runtimes
  • ./scripts/verify passes
  • paseo-local-update built Desktop after the fork existed
  • ./scripts/verify --live sees all four providers
  • first session uses one Lead, one Peer write scope, and Review on a frozen candidate

Keep six facts after the checklist:

  1. Paseo chooses the role; Codex executes inside it.
  2. codex-room-sync is the center: base + overlay → runtime.
  3. ~/.codex belongs to the operator.
  4. Four roles share stable resources and split config, sessions, and state.
  5. Templates are the source of lasting change; runtimes are generated.
  6. Model, permissions, and MCP each have more than one config surface. Change them together.

The room is the process harness. The repository still needs the agent-ready layer — AGENTS.md, validation commands, and evidence handoffs. Use repository-harness for that layer, then let the room decide which Codex role is allowed to touch it.


FAQ

What is a Codex room?

A Codex room is a four-role working environment — Supervisor, Lead, Peer, and Review — launched through Paseo. Paseo owns topology. Each role runs Codex with its own CODEX_HOME so sessions and generated config stay isolated while auth, skills, and plugins stay shared.

Does Codex room setup overwrite ~/.codex?

No. The installer never writes to ~/.codex. It reads the operator’s existing config as a base and creates per-role runtimes under ~/.codex-runtime. Auth, skills, plugins, hooks, and the global AGENTS.md are shared by symlink.

Why does each Codex role need its own CODEX_HOME?

A shared Codex home would mix sessions, logs, memory, and generated config across roles. Isolated runtimes keep Review history out of Lead, let each role carry different model and instruction defaults, and still reuse one operator login.

Why turn off native Codex multi-agent features in a Codex room?

Paseo already decides who is Supervisor, Lead, Peer, and Review. If Codex also spawns native agents inside a role, two coordinators run in parallel and ownership becomes hard to audit. The sync step disables native agents and multi-agent flags in every generated runtime.

Where should I edit if I want a lasting Codex room change?

Edit the source templates in the setup repository, install them into HOME, then regenerate the role runtime. Do not edit ~/.codex-runtime/<role>/config.toml directly. The next sync will overwrite it.

Why does Review have full filesystem access if it is read-only?

Read-only is a behavioral contract in the Review instructions: Review must not edit product code or issue ACCEPT or REVISE. The sandbox stays at danger-full-access because session metadata writes, including OCR preview, still need a local write path.

How do I change a Codex role’s default model?

Update both surfaces at once: the role overlay that sets the Codex process default, and the Paseo provider catalog that controls the picker. Then install, sync that role, and restart Paseo before expecting the UI and the runtime to agree.