Start headless
Codex automation: pick the surface, then prove the result
Codex automation means running Codex with nobody at the prompt: codex exec in scripts and CI, scheduled automations in the Codex desktop app, Codex cloud tasks, parallel worktrees, the Codex SDK, and delegation from Slack or Linear. A run is only as trustworthy as the machine check that decides whether its output merges.
You already use Codex interactively and have chores it could do alone: the nightly flaky-test sweep, dependency bumps, triage of failed CI runs. This hub is for developers and tech leads deciding which surface runs each one, and how to know the result is right without reading every diff. It was checked against Codex CLI 0.157.1.
Which Codex surface should run your job?
Section titled “Which Codex surface should run your job?”Choose by trigger and by what the run must reach. A job that needs your local services belongs on your machine. A job that must run while your laptop sleeps belongs in CI or on Codex cloud.
| Your job | Surface | Trigger | Read |
|---|---|---|---|
| Scripted or CI step with a machine-readable result | codex exec (--json, --output-schema, -o) | Your script or pipeline | Headless Codex with codex exec |
| Recurring check or report | Desktop app automations (macOS and Windows; runs only while that machine is awake), or a CI schedule | Clock | Scheduled Codex automations |
| Long or remote task, several attempts | Codex cloud (codex cloud exec --env ENV_ID --attempts 3; experimental in CLI 0.157.1; codex cloud lists environment IDs, --attempts is best-of-N) | CLI, web or integration | Codex cloud environments |
| Several local tasks at once | Managed worktrees (--worktree, /worktree) | You | Codex worktrees and multi-agent workflows |
| Your own tool or dashboard drives Codex | @openai/codex-sdk (TypeScript) or openai-codex (Python) | Your code | Codex SDK |
| A request starts in chat or a ticket | Slack and Linear integrations | A mention or assignment | Slack and Linear |
| Pull request review and fixes in GitHub | openai/codex-action@v1 | Workflow event | Codex in CI/CD |
| Gateways, sandbox tests, audit trails | Config and telemetry | Setup | Advanced Codex setups |
The same jobs in Claude Code and Cursor live in the Claude Code automation hub and the Cursor automation hub. To choose between vendors’ SDKs, read driving agents from code.
In what order should you automate Codex?
Section titled “In what order should you automate Codex?”Each step reuses what the previous one proved. Skipping ahead means debugging the prompt, the sandbox and the schedule at the same time.
-
Run the task interactively until it succeeds twice and write down the command that proves it, such as
pnpm testorpnpm lint. That command becomes the run’s gate. -
Run it headless with the narrowest permissions and a fixed output shape. In a terminal:
Terminal window gh run view "$RUN_ID" --log-failed | codex exec -c default_permissions=":workspace" \--output-schema triage.schema.json -o triage.json \"Triage the failing tests in the CI log on stdin. Do not edit test files."RUN_IDis the ID of the failed GitHub Actions run (gh run list --status failureprints it). When a prompt argument is given,codex execappends piped stdin to it as a<stdin>block.triage.schema.jsonfixes the shape of the final message:{"type": "object","additionalProperties": false,"required": ["failing_tests", "suspected_cause", "flaky", "confidence"],"properties": {"failing_tests": { "type": "array", "items": { "type": "string" } },"suspected_cause": { "type": "string" },"flaky": { "type": "boolean" },"confidence": { "type": "string", "enum": ["low", "medium", "high"] }}}Permission profiles are beta (CLI 0.138.0 and later) and do not compose with the legacy
--sandboxflag: in 0.157.1, passing both starts without an error and--sandboxsilently replaces the profile. Pass one or the other, and check thesandbox:line in the run header.--approve-for-meruns on the legacy workspace-write sandbox, so it does not compose with a profile either. Pick one control.--full-autono longer exists (removed in 0.147.0). The permissions and sandboxing guide sets the posture per run type. -
Parallelise once one run is reliable: one worktree per task.
-
Schedule it or move it to the cloud.
-
Wire it into CI so the pipeline, not the agent’s own report, decides the result.
-
Reach for the SDK last, when a script around
codex execcan no longer express the flow.
How do you verify unattended Codex output without reading every line?
Section titled “How do you verify unattended Codex output without reading every line?”Trust the gates, not the agent’s summary. A working setup has four layers:
- A fixed output shape.
--output-schemadescribes the final message; your script still checks that the field is present and the model is not unsure (jq -e 'has("failing_tests") and .confidence != "low"' triage.json) before acting on it. - Independent checks. CI reruns the tests, type check and lint on the branch Codex pushed. The agent cannot mark its own work green.
- A second reviewer.
codex exec review --base mainor@codex reviewon the pull request looks for bugs the tests miss. See Codex code review. - An audit trail.
--jsonwrites every event as JSONL; archive it with the run so you can answer “what did it do?” later.
A human still signs off at the merge, on the evidence: green gates, the review findings and the contract’s report. The evidence bundle page defines what that package contains.
What breaks when Codex runs unattended?
Section titled “What breaks when Codex runs unattended?”| Symptom | Cause | Recovery |
|---|---|---|
unexpected argument '-a' | codex exec has no -a in 0.157.1, and does not need one: without --approve-for-me it runs with approval never, whatever approval_policy or a codex -a … exec prefix says. With --approve-for-me the header shows on-request and auto-review decides | Drop the flag and check the approval: line in the run header: never normally, on-request under --approve-for-me. Limit what the run can do with the sandbox or permission profile instead |
| The run has wider or narrower access than the profile | --sandbox passed alongside default_permissions; the flag silently wins in 0.157.1 | Drop one of them and confirm the sandbox: line in the run header |
Script fails on --full-auto | Flag removed in 0.147.0 | Use a permission profile, as in step 2 |
| The run ignores project rules | Untrusted projects do not supply AGENTS.md (since 0.150.0) | On the runner, add [projects."REPO_PATH"] with trust_level = "trusted" to $CODEX_HOME/config.toml (REPO_PATH is the absolute checkout path on the runner) (configuration). Trust only a checkout of your own default branch: a trusted contributor head supplies its own AGENTS.md, project config and hooks |
| Project hooks do not fire | Hooks need persisted trust | Approve them once with /hooks; avoid --dangerously-bypass-hook-trust |
| Parallel runs break each other | Shared ports, database or branch | One worktree and one port block per run |
| A secret leaks from a PR-triggered job | Untrusted code ran with secrets in the environment | Follow agent identity and secrets before enabling the trigger |
Never pass --dangerously-bypass-approvals-and-sandbox outside a disposable, network-restricted sandbox.
Where to go next with Codex automation
Section titled “Where to go next with Codex automation”Schedule it
Configure first
Control the cost
Govern it for a team
Compare background agents