How I configured Codex with specialized subagents and safer defaults

I use Codex across several projects, and I wanted its behavior to be consistent from one task to the next. I had a few specific goals:

  • Plan work before editing, then delegate independent parts to the right subagent.

  • Stop destructive commands before a bad path or broad cleanup request turns into data loss.

Codex already supports the pieces needed for this. Global instructions live in ~/.codex/AGENTS.md, custom agents live under ~/.codex/agents/, and executable command policies can live under ~/.codex/rules/.

This article describes my current setup on Codex CLI 0.144.x. These features can change, especially command rules, which are still documented as experimental. Check the current Codex subagent documentation and rules documentation before copying the configuration unchanged.

The planning, delegation, and destructive-operation configuration is available in the digitalknk/codex-global-agent-setup repository.

The directory layout

My global Codex configuration now includes these files:

~/.codex/
├── AGENTS.md
├── agents/
│   ├── luna-xhigh.toml
│   └── terra-high.toml
└── rules/
    ├── default.rules
    └── safety.rules

The files have different jobs:

  • AGENTS.md tells the main agent how to plan, delegate work, and handle destructive operations.

  • Each file under agents/ defines a custom agent, including its model, reasoning effort, description, and instructions.

  • Files under rules/ evaluate command prefixes and return allow, prompt, or forbidden.

That distinction matters. An instruction is guidance for the model. A command rule is an executable policy check. The sandbox is the actual filesystem and network boundary. I use all of them instead of expecting one file to handle everything.

Why I created two worker agents

The main model is responsible for planning and coordination. I wanted it to choose between two workers based on the work in the plan.

My Luna worker handles bounded work such as a targeted search, a mechanical change, or a clearly specified test. I run it with xhigh reasoning:

name = "luna_worker"
description = """
Fast implementation worker for bounded, low-risk tasks, mechanical changes,
targeted exploration, straightforward tests, and clearly specified fixes.
Choose this when speed and efficiency matter more than deeper reasoning.
"""
model = "gpt-5.6-luna"
model_reasoning_effort = "xhigh"

developer_instructions = """
Complete the assigned scope independently.
Stay within the files and responsibilities assigned by the parent.
Run relevant verification and return a concise result with changed files,
tests run, and any remaining risks.
"""

My Terra worker handles debugging, cross-file changes, architecture-sensitive work, and integration. It runs with high reasoning:

name = "terra_worker"
description = """
Balanced implementation worker for ambiguous changes, debugging, integration
work, cross-file reasoning, architecture-sensitive changes, and tasks requiring
stronger judgment. Choose this when correctness and follow-through outweigh speed.
"""
model = "gpt-5.6-terra"
model_reasoning_effort = "high"

developer_instructions = """
Complete the assigned scope independently.
Inspect the real execution path before editing, preserve existing conventions,
run relevant verification, and return changed files, tests run, and remaining risks.
"""

The model IDs available to you may be different. Use /model in the app or inspect the model catalog in your Codex client before pinning a model name. The important part is the division of responsibility. Give each agent a narrow description that helps the planner make a useful choice.

Making /plan produce a delegation map

Defining custom workers does not guarantee that every plan will use them. I added a planning section to my global AGENTS.md so the coordinator knows when delegation is expected.

## Planning and delegated execution

When Plan mode is active:

- Build an implementation-ready plan grounded in the actual workspace.
- Use subagents for independent read-only investigation when parallel research
  would materially improve the plan.
- Do not begin implementation while still in Plan mode.
- Include a delegation map identifying which plan steps can run independently
  and whether `luna_worker` or `terra_worker` is the better fit for each step.

After the user approves the plan, starts a goal, or otherwise authorizes execution:

- Treat that authorization as an explicit request to use subagents for independent
  implementation, investigation, and verification work whenever the task can be
  safely decomposed.
- Choose only `luna_worker` or `terra_worker` for delegated work.
- Choose `luna_worker` for bounded, straightforward, low-risk, mechanical, or
  speed-sensitive work.
- Choose `terra_worker` for ambiguous, cross-cutting, debugging-heavy,
  architecture-sensitive, or integration-sensitive work.
- Run independent agents concurrently when their scopes do not overlap.
- Give every agent a specific scope, expected output, and verification requirement.
- Wait for all required agents, integrate their results, resolve conflicts, and
  perform final end-to-end verification in the main task.
- Keep tightly coupled work in the main task.

Plan mode still remains Plan mode. The agent can investigate and prepare the work, but it should not begin implementation until I approve the plan or otherwise authorize execution. Once approved, the coordinator can start independent workers concurrently and collect their results.

Codex can delegate when the user asks directly or when an applicable AGENTS.md or skill requests it. Each subagent consumes its own model and tool usage, so delegation has a cost. I reserve it for work that can actually run independently.

Why I added destructive-operation rules

An agent that can edit files and run shell commands needs clearer boundaries than "be careful." The failure mode I cared about most was a recursive deletion pointed at the wrong directory.

My behavioral policy says that Codex must never recursively delete the filesystem root, my home directory, the active workspace root, or a repository root. Recursive deletion elsewhere requires an explicit request naming the exact target, path resolution, inspection, and fresh confirmation.

The policy also covers other operations that can discard work or destroy external state:

  • git reset --hard, git clean, destructive restore operations, history rewriting, and force pushes

  • Recursive permission or ownership changes

  • Disk formatting and raw-device writes

  • Database drops, infrastructure destruction, namespace deletion, and bulk cloud-resource deletion

I also tell the agent to prefer Trash or a quarantine directory when practical, run dry-run commands where available, and preserve files it does not recognize.

This belongs in AGENTS.md because no short list of command prefixes can describe every destructive equivalent. It is still only a behavioral layer, so I added executable rules as a second barrier.

Blocking root and home deletion

Codex rules use exact argument prefixes. This sample blocks common recursive forms targeting / or a configured home directory:

prefix_rule(
    pattern = [
        ["rm", "/bin/rm", "/usr/bin/rm"],
        ["-rf", "-fr", "-r", "-R", "--recursive"],
        ["/", "/Users/YOUR_USERNAME", "/Users/YOUR_USERNAME/"],
    ],
    decision = "forbidden",
    justification = "Never recursively delete the filesystem root or the user's home directory.",
    match = [
        "rm -rf /",
        "rm -fr /Users/YOUR_USERNAME",
        "/bin/rm -R /Users/YOUR_USERNAME",
    ],
    not_match = [
        "rm -rf /Users/YOUR_USERNAME/project/tmp",
        "rm file.txt",
    ],
)

Use the absolute home path. Do not assume ~ or $HOME will behave like a shell expansion inside an exact argument rule.

I use forbidden for the filesystem root and home directory. For recursive deletion elsewhere, I use prompt:

prefix_rule(
    pattern = [
        ["rm", "/bin/rm", "/usr/bin/rm"],
        ["-rf", "-fr", "-r", "-R", "--recursive"],
    ],
    decision = "prompt",
    justification = "Recursive deletion requires fresh approval and a verified absolute target.",
    match = [
        "rm -rf build",
        "rm -r /tmp/example",
        "/bin/rm --recursive generated",
    ],
    not_match = [
        "rm file.txt",
        "rmdir empty-directory",
    ],
)

My full rules file also handles separate -r -f arguments, sudo rm, destructive Git commands, recursive permission changes, disk tools, Docker prune, Terraform and OpenTofu destroy, Kubernetes namespace deletion, and database administration commands.

I keep a sanitized copy of the complete rules file separate so it can be reviewed and tested on its own. Replace /Users/YOUR_USERNAME with your absolute home path before installing it. Linux users will usually want /home/YOUR_USERNAME instead.

Rules are prefix-based, so they cannot prove that every destructive command is covered. Alternate programs, complex scripts, and remote APIs can have the same effect without sharing these prefixes. This is why I keep the behavioral policy and sandbox enabled as well.

Keeping the sandbox and approvals enabled

My normal configuration uses:

approval_policy = "on-request"
approvals_reviewer = "user"
sandbox_mode = "workspace-write"

The Codex sandbox documentation describes the sandbox and approvals as separate controls. The sandbox defines the technical boundary. The approval policy determines when Codex must stop and ask before crossing it.

I do not treat a command rule as permission to run Codex with unrestricted access. I keep the project boundary as the default and use Full Access only when a specific task requires it and I understand the added risk.

Testing the command rules

Codex includes execpolicy check for validating rule files without running the command. I used it for every rule before restarting Codex.

To test root deletion:

codex execpolicy check --pretty \
  --rules ~/.codex/rules/safety.rules \
  -- rm -rf /

The expected decision is:

{
  "decision": "forbidden"
}

Test the configured home path too:

codex execpolicy check --pretty \
  --rules ~/.codex/rules/safety.rules \
  -- rm -rf /Users/YOUR_USERNAME

Then confirm that an ordinary recursive project path prompts instead of being silently allowed:

codex execpolicy check --pretty \
  --rules ~/.codex/rules/safety.rules \
  -- rm -rf /some/project

Expected decision:

{
  "decision": "prompt"
}

I also test rules together with my existing defaults:

codex execpolicy check --pretty \
  --rules ~/.codex/rules/default.rules \
  --rules ~/.codex/rules/safety.rules \
  -- rm -rf src-tauri/icons/android src-tauri/icons/ios

When multiple rules match, Codex uses the most restrictive result. In my configuration, a previous narrow allow for that icon cleanup is overridden by the broader recursive-deletion prompt.

The match and not_match entries inside the rules file act as inline tests when Codex loads it. They are worth maintaining. A safety rule that does not match the command form you expect is false confidence.

Installing the setup

Create the directories:

mkdir -p ~/.codex/agents ~/.codex/rules

Then:

  1. Add each custom agent as a standalone TOML file under ~/.codex/agents/.

  2. Add the planning and destructive-operation instructions to ~/.codex/AGENTS.md.

  3. Add command rules under ~/.codex/rules/.

  4. Replace every example home path with the correct absolute path for your machine.

  5. Run codex execpolicy check against destructive and harmless examples.

  6. Restart Codex so it reloads the rule files.

  7. Start a new task so the global instructions and custom agents are loaded cleanly.

After restarting, I test the behavior with a disposable project. I ask for a plan that has two independent work items, inspect which custom worker the coordinator chooses, and confirm that a recursive removal request produces an approval prompt. I do not test destructive policies against directories containing real work.

What this setup does not guarantee

No prompt or prefix-rule file can eliminate every possible failure. Models can misunderstand instructions, command-line tools have aliases and wrappers, and destructive actions can happen through APIs that never invoke rm.

The setup improves my defaults in several practical ways. Plans state how work will be delegated. Worker selection is explicit. Dangerous commands meet a policy barrier before execution.

That is the standard I wanted: predictable coordination, clear approval points, and fewer surprises when Codex moves from answering questions to changing a real workspace.

Replies

No approved Webmentions yet.