DEV Community

Cover image for 9 Codex Config Keys to Set Before Your Coding Agent's First Long Task
Gabriel Anhaia
Gabriel Anhaia

Posted on Edited on AI-assisted

9 Codex Config Keys to Set Before Your Coding Agent's First Long Task


You hand Codex a two-hour refactor and go to lunch. You come back to a terminal that has been sitting on an approval prompt since minute four, because the agent wanted to run npm install and the sandbox has no network.

Nothing broke. Codex did exactly what its defaults say. For a long unattended run, a few of those defaults work against you, and one of them hands the agent's shell more of your environment than you'd expect.

Here are nine settings for a long Codex run, eight of them keys in ~/.codex/config.toml and one a file next to it, each checked against OpenAI's config reference and advanced config guide as of November 4, 2026. For each one: what the default does to a long run, and a value to paste. One of them is a correction. If you copied a [profiles.*] table from an older blog post, it stopped working in Codex 0.134.0.

1. Pin the model and the effort

Keys: model, model_reasoning_effort

The reference lists effort values "such as low, medium, high, xhigh, max, or ultra", and says "available levels depend on the model and client." The docs list no default for either key. Leave them unset and the run gets whatever the client picks today.

model = "gpt-6.1-sol"
model_reasoning_effort = "high"
Enter fullscreen mode Exit fullscreen mode

The docs' own profile example uses gpt-6.1-sol and notes it needs access on your account or workspace. Use a model your account lists. Pick an effort that model offers. Save the top levels for the profile in item 6, so your quick questions don't pay for them.

2–5. The permission keys decide whether it stalls

Four keys control what the agent may do without you. On a long run, getting them wrong means it either waits for hours or has more reach than you meant to give it.

2. approval_policy. Values are on-request, never or a granular table. The reference says untrusted "is unsupported" and on-failure "is deprecated", so check any old config for them. Its advice: "use on-request for interactive runs or never for non-interactive runs." Under on-request, OpenAI's approvals page says Codex asks before it edits files outside the workspace or runs network-dependent commands. That is the lunch-break stall. With never there are no prompts, and the page notes "you still control Codex's level of autonomy" through the sandbox.

approval_policy = "on-request"   # day to day; item 6 flips it
Enter fullscreen mode Exit fullscreen mode

3. sandbox_mode. Values are read-only, workspace-write and danger-full-access. On launch Codex recommends Auto (workspace write plus on-request approvals) for version-controlled folders and read-only for everything else, per the approvals page. Take that recommendation in a folder without git and a long task can't write a single file. The same page labels the no-sandbox, no-approvals --yolo combination "not recommended". Don't use it on a run nobody watches.

sandbox_mode = "workspace-write"
Enter fullscreen mode Exit fullscreen mode

Editorial illustration of a terminal window standing inside a fenced yard, a closed gate with a small bell on it, and an unplugged network cable lying outside the fence
The sandbox is the fence, approvals are the gate, and the network cable starts unplugged.

4. network_access under [sandbox_workspace_write]. "By default, the agent runs with network access turned off," says the approvals page. It also warns that "prompt injection can cause the agent to fetch and follow untrusted instructions." My suggestion is to keep it off and install dependencies before you start. If the task needs the network, turn it on for that run only. The advanced guide shows the one-run form:

codex --config sandbox_workspace_write.network_access=true
Enter fullscreen mode Exit fullscreen mode

5. writable_roots. These are "additional writable roots when sandbox_mode = "workspace-write"." You need one when the task also edits a sibling repo, such as a shared types package. Use absolute paths. Inside every writable root, .git stays read-only, and so does .codex when it is a directory (approvals page).

[sandbox_workspace_write]
network_access = false
writable_roots = ["/path/to/shared-types"]
Enter fullscreen mode Exit fullscreen mode

6. Profiles are files now

Key: none. It's a file next to config.toml.

The advanced guide is blunt about it: in Codex 0.134.0 and later, --profile no longer reads [profiles.<name>] from config.toml, and the top-level profile = "<name>" selector is no longer supported. A profile is now its own file, ~/.codex/<name>.config.toml, with top-level keys. Names can use letters, numbers, hyphens and underscores.

That suits long runs. Keep your daily config cautious and put the unattended settings in a file of their own:

# ~/.codex/long-run.config.toml
model = "gpt-6.1-sol"
model_reasoning_effort = "xhigh"  # if your model lists it
approval_policy = "never"
sandbox_mode = "workspace-write"
Enter fullscreen mode Exit fullscreen mode
codex --profile long-run
codex exec --profile long-run "migrate the tests to vitest"
Enter fullscreen mode Exit fullscreen mode

Precedence matters. The config basics page puts CLI flags and --config overrides first, then project .codex/config.toml files (trusted projects only), then the profile, then ~/.codex/config.toml. A repo's own .codex/config.toml can override your profile.

7. notify: find out when a turn ends

Key: notify

Unset, nothing tells you when a turn finishes. You keep going back to the terminal to check. notify takes a command array. Codex runs it with one JSON argument when it emits a supported event, and "currently only agent-turn-complete" is supported (advanced guide). The payload fields are type, thread-id, turn-id, cwd, input-messages and last-assistant-message.

notify = ["python3", "/path/to/codex-turn-log.py"]
Enter fullscreen mode Exit fullscreen mode

A small script that appends one line per finished turn, so tail -f ~/.codex/turns.log shows a whole session:

#!/usr/bin/env python3
import json
import os
import sys
import time

event = json.loads(sys.argv[1])
if event.get("type") != "agent-turn-complete":
    sys.exit(0)

msg = event.get("last-assistant-message") or ""
line = "{} {} {}\n".format(
    time.strftime("%H:%M"),
    event.get("cwd", "?"),
    msg.replace("\n", " ")[:80],
)
path = os.path.expanduser("~/.codex/turns.log")
with open(path, "a") as f:
    f.write(line)
Enter fullscreen mode Exit fullscreen mode

If you forward these events to a webhook or a queue instead, use turn-id as the dedupe key so a retried delivery doesn't post twice. If all you want is a desktop alert, the guide points to the built-in tui.notifications setting as the alternative.

8–9. Context size and secrets

8. project_doc_max_bytes. The AGENTS.md page says Codex "stops adding files once the combined size reaches the limit defined by project_doc_max_bytes (32 KiB by default)." The limit is combined, not per file. The advanced guide describes it as per file, and an open docs issue from July 31, 2026 says the code treats it as one shared budget along the root-to-folder chain. A large root AGENTS.md can use it up and silently drop a nested one, and the nested one usually holds the rules for the folder the agent is working in.

List every AGENTS.md and its size. Only the files on the path from the repo root to the folder the agent works in count toward one run, so add up those:

find . -name AGENTS.md -not -path '*/node_modules/*' \
  -exec wc -c {} +
Enter fullscreen mode Exit fullscreen mode

If the total is close to 32,768, raise the limit. 65536 is the docs' own example:

project_doc_max_bytes = 65536
Enter fullscreen mode Exit fullscreen mode

9. shell_environment_policy. This is the one that exposes secrets. The reference says ignore_default_excludes defaults to true, which keeps variables whose names contain KEY, SECRET or TOKEN. Unless another filter removes them, the commands the agent runs during a two-hour task can see the credentials you exported this morning. Set it to false to apply the automatic exclusions, and use the newer filters table. The legacy exclude and include_only arrays can't be combined with filters in the same layer.

[shell_environment_policy]
inherit = "core"
ignore_default_excludes = false

[shell_environment_policy.filters]
"AWS_*" = "exclude"
"AZURE_*" = "exclude"
Enter fullscreen mode Exit fullscreen mode

inherit = "core" starts from what the docs call a trimmed set, and none starts from nothing. If your tests need a variable, give them a dummy value with set = { ... }. set runs after exclusions, so it can bring a name back. Don't write real secrets into config.toml. To check the result, ask the agent to run env | cut -d= -f1 | sort and read the names it prints.

Running the same config from Hermes IDE

I build Hermes IDE, so weigh this section with that in mind. Hermes runs Codex as a built-in agent, in a real terminal, with Codex's own interface, "exactly as it would anywhere else", in the README's words. You sign in to Codex with Codex's own login, and Hermes never asks for your tokens.

The Hermes New task sheet with its agent picker open: Claude Code selected, Codex installed at 0.145.0, and other supported agents marked Not installed, plus Custom agent
The ⌘N New task sheet's agent picker in Hermes 2.3.4, with Claude Code and Codex installed.

On top of that config, the ⌘N sheet (Ctrl+Shift+N on Windows and Linux) picks the agent, model, effort and account for each task, and you can save the combinations you use often as presets. Each task gets its own hermes/<task> branch and worktree, so workspace-write scopes Codex to that task's folder and not to your main checkout.

The Hermes New task sheet with a refund-endpoint task typed, chips for agent, project, a new hermes/ worktree, Accept edits, model and effort, and a preview of the command Hermes will run
The ⌘N New task sheet: agent, project, worktree, approval, model and effort chips, and the "Hermes will run" command preview.

notify still fires, because Codex fires it. Hermes adds its own layer: one status per session, a notification when an agent is blocked on you or done, and ⌘I to jump to the agent that has waited longest. It never answers a permission prompt for you.

Hermes is free, source-available under BSL 1.1, runs on macOS, Windows and Linux, and isn't affiliated with OpenAI, Anthropic, Nous Research or any other agent vendor. The current release is 2.3.4, published October 15, 2026, and you can download it here.


If this was useful

notify turns every finished Codex turn into an event that some other program consumes. Once you send those events through a webhook or a queue, you're dealing with retries, duplicate deliveries and ordering, and the Event-Driven Architecture Pocket Guide covers those traps in a short read. If you run Codex next to other agents, Hermes IDE keeps each one on its own branch with one inbox.

Event-Driven Architecture Pocket Guide: Saga, CQRS, Outbox, and the Traps Nobody Warns You About

Top comments (0)