Dayward AI
Week 1 · D1About 4 hours

Getting Started With the Codex CLI: Install, AGENTS.md, Approval Modes and the Sandbox, Common Commands

Install the Codex CLI, understand what it reads to make sense of your project, what stops it from touching files it shouldn't, and finish your first real task with it.

Today's goals 0/3

Sign in to tick these off and save your progress.

Today's Goals

  1. Install the Codex CLI, sign in with a ChatGPT account or an API key, and complete a first task
  2. Explain AGENTS.md's lookup order, merging rules, and size cap, and write one for your own project
  3. Explain what the approval_policy and sandbox_mode switches each control, and pick a combination to match task risk

This course does not re-teach how to talk to a model — the four parts of a prompt, few-shot examples, chain of thought, and the rest are covered thoroughly in D1 of the prompt engineering course, and here we assume you can write a clear request. Today solves a different problem: once the model is no longer merely answering but genuinely editing files and running commands in your repository, how do you brief it on the project, and how do you keep it inside the lines? Once you have read this and finished the work, scroll back to the top and tick off the three goals.

Plain-Language Walkthrough

What Codex is: a programming partner running in your terminal

Start with a scenario. You have a small project, and a new partner arrives — a contractor sent over from another firm: perfectly capable, but knowing nothing about your project and nothing about how your team does things. How would you bring them up to speed? Roughly in three steps. First, hand them an onboarding handbook covering how the project installs, how it is tested, and what must not be touched. Second, for the first few days have them check with you before they change anything. Third, give them a machine with only the tools the job needs, rather than the production database password on day one. That is this course's analogy — the same job, given to two contractors from different firms: this course covers the one OpenAI sent (Codex), the companion course on using Claude effectively covers the one Anthropic sent (Claude Code), and on the last day we put both on the same task and measure. What we compare is ways of working, not which one is smarter.

Codex is the collective name for OpenAI's coding agent product line, and it has several entry points: the Codex CLI in your terminal, the IDE extension in your editor, the Codex desktop app, cloud tasks running on OpenAI's servers, and code review hooked into GitHub. Today is about the CLI only, because it is the most transparent — every file it reads and every command it runs is printed in front of you, which makes it the best place to build intuition; the other entry points are tomorrow's subject. The CLI itself is open source, in the openai/codex repository, written in Rust, which means it starts fast and can implement a genuine system-level sandbox on your machine (more on that below).

What separates it from discussing code with ChatGPT in a browser? One sentence: it has hands. A model in the browser can only give you a block of code, and the copy-paste, run-tests, read-errors, fix-again loop is turned by you; Codex moves that loop inside itself — reading your files, editing, running tests, reading errors, editing again, until the tests pass or it gets stuck and asks you. This is exactly what the formula from D1 of the 30-day course — "agent = model + loop + tools + memory" — looks like in a coding setting: the tools are file access and a shell, and the memory is the current session plus whatever project notes you wrote. Once that lands, every later question of the form "why is it asking me this" or "why can it not read that directory" has an answer: because it is a program executing actions on your machine, not a window that only talks.

Install and sign-in: five minutes to install, two identities

Installing is one command, via npm or Homebrew:

BashBash
npm install -g @openai/codex
# or
brew install --cask codex

Once installed, type codex in any project directory and the first run asks you to sign in. Two identities are available: a ChatGPT account (OAuth, drawing on your ChatGPT subscription allowance) or an API key (billed to your OpenAI platform account). For an individual learner, the ChatGPT account is the least trouble; for a team or a CI setting, an API key is more controllable, because it can be issued and revoked per project. The codex login subcommand re-authenticates or switches identity on its own.

After signing in you get a full-screen terminal interface with an input box at the bottom. Do not rush to state a requirement — type / and look at the slash commands it lists: /permissions (change approvals and the sandbox), /review (review code), /clear (start a new session), /rename (name a session). Those commands are one of today's leads; for now just note that they exist.

AGENTS.md: Codex's onboarding handbook

Back to the new contractor. On their first day, the thing they most need is not a task but a handbook: how the project installs, how tests run, roughly what the directory layout is, which parts are legacy and off-limits, what format commit messages take. Without that handbook they re-derive everything every time, and will most likely fall back on how their previous firm did things. Codex's handbook is AGENTS.md — an ordinary Markdown file in the repository that Codex reads into context at the start of every session and treats as established fact about the project.

Its lookup rules are worth getting exactly right, because they determine where a rule has to live to take effect:

  1. The global layer: first ~/.codex/AGENTS.override.md, and failing that ~/.codex/AGENTS.md. This holds your personal cross-project habits, such as "always run lint before committing."
  2. The project layer: walking from the project root down to whichever subdirectory you are in, each level is checked for AGENTS.override.md and, failing that, AGENTS.md. The files found are concatenated in order from the root down to the current directory, joined by blank lines.

The merge order has one direct consequence: a file nearer the current directory appears later in the merged prompt and therefore overrides earlier rules. That is why you can write "tests use vitest" at the root and then, in a legacy/ subdirectory, write "this directory uses mocha, do not convert it to vitest" — while working under legacy/, the latter wins.

There is also a cap: the total merged content defaults to 32 KiB, beyond which nothing more is added. The setting is called project_doc_max_bytes and you can tune it in ~/.codex/config.toml. That cap is not an obstacle but a reminder — an onboarding handbook is not an encyclopedia. It forces you to write only what Codex cannot discover on its own and yet must know. A good AGENTS.md looks like this:

mdmd
# Project: TODO API
 
## How to run
- pnpm install && pnpm dev (port 3181)
- Tests: pnpm test (vitest; mandatory after any code change)
 
## Rules
- Input validation goes through zod; do not hand-roll if checks
- Do not edit anything under src/legacy/
- Commit messages follow Conventional Commits
 
## Known pitfalls
- Start the postgres service in docker compose before running pnpm test

Notice that it does not say "this is a TODO application written with Express and it has three routes" — Codex works that out for itself by opening package.json and src/, and writing it only wastes that 32 KiB. What it does contain is all conventions (zod rather than if checks), forbidden zones (legacy is off-limits), and environment facts it cannot guess (start the database before the tests). The thinking is identical to Claude Code's CLAUDE.md, with only the file name and lookup rules differing — D5 puts the two handbooks side by side.

Approval modes and the sandbox: two independent sets of switches

The new contractor is about to change something. You have two independent questions to answer: should they check with you before acting? and what can their machine actually reach? The first is a process question, the second a permission question. Many people fuse them into a single "security level," when in fact Codex splits them into two separate configurations — and understanding that resolves most of the confusion about "why is it asking me again."

Set one: approval_policy, controlling when it asks you. Four values:

ValueMeaning
untrustedOnly clearly safe read-only operations go through automatically; every other command asks before running
on-requestThe default. Operations inside the sandbox do not ask; it asks only when it needs to leave the sandbox (going online, writing outside the workspace)
on-failureRuns in the sandbox first, and asks whether to lift the restriction and retry only after a failure
neverNever asks; anything that cannot be done inside the sandbox simply fails

Set two: sandbox_mode, controlling what it can reach. Three values:

ValueMeaning
read-onlyCan read files only; editing files and running commands that write to disk require approval
workspace-writeThe default. Can read, can edit files inside the current workspace, can run ordinary local commands; outside the workspace and the network are closed by default
danger-full-accessNo sandbox at all, and the danger in the name is meant literally

The two sets combine freely, specified on the command line with -a (--ask-for-approval) and -s (--sandbox) respectively, and changed mid-session with /permissions. The documentation names three common combinations: Auto (workspace-write plus on-request, which is the default in a git directory), Read-only (read-only plus on-request, letting it look and explain, which suits getting oriented in an unfamiliar repository), and Full access (--dangerously-bypass-approvals-and-sandbox, aliased --yolo, which belongs only in a throwaway container). You may have seen the --full-auto flag before; it is deprecated and equivalent to --sandbox workspace-write.

How does the sandbox make something impossible? Not through the prompt but through the operating system: Seatbelt on macOS, bubblewrap user-namespace isolation on Linux, the native sandbox on Windows, and the Linux mechanism under WSL2. So when it tries to write to ~/.ssh under workspace-write, what fails is not "the model decided not to" but the kernel refusing the write. The network is closed by default, and when something needs it — npm install, say — you either turn on network_access = true in the [sandbox_workspace_write] section of config.toml or approve it when it asks.

Common commands: interactive, unattended, resumed

The Codex CLI has few commands, and the ones below are enough, grouped by whether you are sitting there.

You are there, interactive: type codex for the full-screen interface, or codex "replace the input validation in src/todo.ts with zod" to enter with your first request already stated. Inside a session, /permissions changes permissions, /review has it review the current changes (detailed tomorrow), /clear starts a new session, and /rename names this session so you can find it again later.

You are not there, unattended: codex exec "…" (aliased codex e) skips the interface, takes the request directly, and streams the result to standard output; it can also emit JSONL for a script to parse. That is the entry point for wiring Codex into CI or a batch script — running "add a test skeleton to every module that has no tests" overnight, for instance. Note that unattended means nobody is nodding, so it usually pairs with a stricter sandbox and a branch you can afford to break.

Come back and continue: codex resume picks up the most recent session, or a specific one by id; codex fork branches a new session off an old one while keeping the original record — which suits trying two approaches from the same starting point.

One small trick: codex exec with -s read-only makes an excellent code explainer. Taking over someone else's repository, run codex exec -s read-only "explain this project's directory structure and startup flow" and half a minute later you have a guided tour that changed no files at all.

Your first real task: adding input validation to the TODO API

Now string today's material together on the example task that runs through all five days: add input validation and matching unit tests to a TODO API written with Express or FastAPI. Today covers the first half — the validation; the tests go to a cloud task on D2, and D5 pits the whole thing against Claude Code.

Start from a minimal baseline. Below is a create endpoint with no validation whatsoever, and both versions teach the same thing:

src/todo.ts
import express from 'express'
 
const app = express()
app.use(express.json())
 
const todos: Array<{ id: number; title: string; done: boolean }> = []
 
// The problem: title can be an empty string or not a string at all, and done can be anything
app.post('/todos', (req, res) => {
  const { title, done } = req.body
  const todo = { id: todos.length + 1, title, done: Boolean(done) }
  todos.push(todo)
  res.status(201).json(todo)
})
 
app.listen(3181)

Then write an AGENTS.md for the project following the sample above, stating at minimum that validation goes through zod (or pydantic) and how tests are run. Now start codex in the project root, keep the default Auto permissions, and brief it clearly:

TextText
Add input validation to POST /todos: title must be a non-empty string of 1 to 200
characters, and done is optional and must be a boolean. On a validation failure return
400 with JSON shaped like { error: string }. Use the library specified in AGENTS.md.
Run the tests once after your change to confirm nothing existing broke, and finish by
telling me in one sentence which files you edited.

Once it starts, do not stare only at the final result — watch its process. Which files did it read first (it should open AGENTS.md and package.json before anything else)? Did it validate with the library you specified (that is the evidence AGENTS.md took effect)? Did an approval pop up when it ran pnpm test (under the default Auto, a local test command is inside the sandbox, so it should not)? If it wants to npm install zod, that step does raise an approval, because it needs the network — which is the closed-by-default network at work. When it finishes, look at the changes with git diff and you will find it behaved much like a new colleague who actually read the handbook: it edited the files it should, left the directories it should not alone, and told you what it changed.

The most valuable thing in this task is not those few lines of validation code but seeing all three mechanisms do their jobs in front of you: AGENTS.md decides by what rules it works, the sandbox decides what it cannot do, and approvals decide what has to pass through you. The combination of those three is the whole secret of a coding agent turning from a chat window that writes code into a partner you can safely hand work to.

Source Reading

Hands-On Lab

🧪 D1 lab: write an AGENTS.md for your own project

Code location: labs/codex-mastery/day-01-agents-md

Acceptance criteria:

  1. The project root holds an AGENTS.md, and Codex read it at the start of the session (its changes match the library you specified).
  2. Some subdirectory carries a rule that contradicts the root, and while working in that subdirectory Codex follows the subdirectory's version.
  3. You have run the same task under both read-only and workspace-write, and can say at which step each of them raised an approval.
  4. AGENTS.md contains nothing Codex could discover by opening a file itself, and its total length fits on one screen.

Today is a documentation-style lab: no code to pnpm install, and the deliverable is that AGENTS.md. starter/ holds a template with blanks and solution/ a finished one for this course's TODO API; follow its structure for your own project.

  1. Run codex once in your own project root with no AGENTS.md in place and ask it to explain how the project starts and how it is tested. Note everything it guessed wrong or could not find — that is exactly what the handbook should contain.
  2. Fill in the blanks in starter/AGENTS.md: how to install, how to test, which directories are off-limits, the commit message format — every line being something it failed to guess in the previous step.
  3. Move one rule into a subdirectory's AGENTS.md with the opposite content, cd into it, run the same task again, and confirm it follows the subdirectory's version.
  4. Run the add-validation task once with codex -s read-only and once with the default permissions, recording at which step each approval appeared and what you approved.
  5. Go back and delete: anything it could have seen for itself by opening package.json or src/ comes out of AGENTS.md, until only conventions, forbidden zones, and environment facts remain.

Interview Questions

Today's 3 questions are in the question bank below, weighted toward how a coding agent gets project context injected, the boundary between approvals and the sandbox, and how to explain the risk controls to a team. Expand each one and read the analysis before the key points — practicing the derivation beats memorizing bullets.

Checklist and Tomorrow

  • Install the Codex CLI, sign in with a ChatGPT account or an API key, and complete a first task
  • Explain AGENTS.md's lookup order, merging rules, and size cap, and write one for your own project
  • Explain what the approval_policy and sandbox_mode switches each control, and pick a combination to match task risk
  • Say what "written rules govern what should happen, runtime limits govern what cannot" corresponds to in Codex specifically
  • All 4 acceptance criteria of the lab pass
  • Answer at least 2 of the 3 interview questions without looking at the key points

Tomorrow (D2) we expand Codex from one session in a terminal into a whole way of working: sending tasks to run in parallel in cloud containers, having it review PRs on GitHub, wiring in external tools with MCP, and handing selected code to it from inside the IDE. Learning the local CLI before the cloud is deliberate: the approval boundaries and environment configuration of a cloud task are these same two switch sets and the same AGENTS.md transplanted to another machine — once it makes sense locally, the cloud is only a change of venue.

Interview questions

  • What belongs in a project instruction file for a coding agent (such as Codex's AGENTS.md), what does not, and why is there a size limit?给 coding agent 写的项目说明文件(比如 Codex 的 AGENTS.md)应该写什么、不该写什么?为什么它要有大小上限?
    Common in ChinaCommon overseasBasic#coding-agent#context#agents-md

    How to reason about it · think before answering

    1. This probes whether you treat context as a scarce resource, not whether you know the file format; answering with a project overview signals inexperience.
    2. Use one test: can the agent discover this by opening files? If yes, leave it out (directory layout, framework); if no, write it down (conventions, no-go areas, environment facts, test commands).
    3. Add the lookup rules: a global file in the home directory, then project files concatenated from the repo root down to the current directory, so closer files override earlier ones.
    4. The size cap (32 KiB by default in Codex) forces prioritization: a long manual crowds out the task and dilutes adherence to every rule.
    5. Expect the follow-up: will the model always obey the file? No, it is prompt text and fades over long sessions; hard limits belong to the sandbox and approvals.

    分析过程 · 先想清楚再作答

    1. 这题考的不是文件格式,而是你对「上下文是有限资源」有没有工程直觉。把它答成「写项目介绍」会被判为没真用过。
    2. 拆法是一个判断句:这条信息 agent 打开文件自己能不能发现?能发现的不写(目录结构、用了什么框架),发现不了的才写(约定、禁区、环境事实、测试命令)。
    3. 再补一层查找规则:全局层在用户目录,项目层从根目录到当前目录依次拼接,越靠近当前目录越靠后、越优先,所以子目录可以覆盖根规则。
    4. 大小上限(Codex 默认 32 KiB)的意义是逼你做取舍:手册太长会挤占任务本身的上下文,还会让模型对每一条规则的遵守度下降。
    5. 可预期的追问:写在说明文件里的规则模型一定会遵守吗?不一定,它是提示词的一部分,会被长对话稀释;硬约束要靠沙箱与审批,不是靠文字。

    Key points

    • Write conventions, no-go areas, environment facts and verification commands; skip anything discoverable from the files
    • Lookup goes global first, then project files concatenated root-down, with closer files taking precedence
    • The size cap forces you to keep only high-value guidance so the task itself keeps its context budget
    • Instruction files are advisory; hard limits come from the sandbox and approval policy

    答题要点

    • 写约定、禁区、环境事实和验证命令;不写 agent 自己打开文件就能发现的内容
    • 查找顺序是全局文件在前、项目文件从根到当前目录拼接,越靠近当前目录越优先
    • 大小上限逼你只保留高价值信息,避免挤占任务上下文、降低规则遵守度
    • 文字规则是建议性的,真正不能越的线交给沙箱与审批
  • Codex splits 'when to ask the user' and 'what can be touched' into two independent settings, approval_policy and sandbox_mode. Why separate them, and what does each solve?Codex 把「什么时候问用户」和「能碰到什么」拆成 approval_policy 和 sandbox_mode 两组独立开关。为什么要拆?各自解决什么问题?
    Common in ChinaCommon overseasIntermediate#coding-agent#security#sandbox

    How to reason about it · think before answering

    1. The discriminating part is 'why separate'; reciting the values without explaining orthogonality earns little.
    2. Define both: approval policy is process control, whether a human must nod before an action; sandbox is permission control, whether the OS allows the action at all.
    3. Then justify orthogonality with combinations a single slider cannot express: 'do not interrupt me but never leave the workspace' versus 'ask every time but read-only'.
    4. Ground it in implementation: the sandbox uses OS mechanisms (Seatbelt on macOS, bubblewrap on Linux) rather than model goodwill, so it is a hard limit, while approval is the one human checkpoint.
    5. Expect the follow-up: why is network off by default? Because network is the channel for code leaving or entering the machine, a different risk class from local edits.

    分析过程 · 先想清楚再作答

    1. 题眼是「为什么拆」。只背出每组的取值等于没答,面试官要听的是两者正交带来的好处。
    2. 先给定义:审批策略是流程控制,决定动作执行前要不要人点头;沙箱是权限控制,决定即使模型想做、操作系统允不允许。
    3. 再说为什么正交:你可能想要「不打扰我,但绝不许出工作区」(on-request 加 workspace-write),也可能想要「每步都问,但只让它读」(untrusted 加 read-only);合成一个滑杆就表达不了这两种组合。
    4. 落到实现:沙箱靠操作系统机制(macOS Seatbelt、Linux bubblewrap),不是靠模型自觉,所以它是硬约束;审批则是唯一由人把关的环节。
    5. 可预期的追问:为什么网络默认关?因为联网是把内部代码送出去或把外部代码拉进来的通道,风险等级和改本地文件不同,需要单独授权。

    Key points

    • approval_policy governs process: untrusted / on-request / on-failure / never decide whether a human confirms first
    • sandbox_mode governs permission: read-only / workspace-write / danger-full-access decide what the OS allows
    • Orthogonality lets you express 'no interruptions but stay in the workspace' and 'ask each step but read-only'
    • The sandbox is an OS-level hard limit, approval is the human checkpoint, and network is off by default

    答题要点

    • approval_policy 管流程:untrusted / on-request / on-failure / never 决定动作前是否要人确认
    • sandbox_mode 管权限:read-only / workspace-write / danger-full-access 决定操作系统放行什么
    • 两者正交才能表达「不打扰但不越界」和「步步问但只读」这类组合
    • 沙箱是操作系统级硬约束,审批是唯一的人工把关点;网络默认关闭需单独放开
  • You want to introduce a coding agent that runs commands locally. How do you explain its risk boundary to skeptical teammates?你要在团队里引入一个能在本地执行命令的 coding agent,怎么向不放心的同事解释它的风险边界?
    Common in ChinaCommon overseasIntermediate#coding-agent#security#communication

    How to reason about it · think before answering

    1. This tests communication as much as engineering: state the technical boundary in terms the listener can verify, not just 'it is safe'.
    2. Present three layers of defense: written rules (AGENTS.md) shape habits; the sandbox limits capability to read-only or workspace-only writes with network off; approvals gate every exception.
    3. Offer verifiable guarantees: every change lands in the git working tree, visible via diff and revertable via checkout; unattended runs stay on throwaway branches or containers.
    4. Name the residual risk yourself: the model can misread a requirement and produce wrong but passing code, so review and tests remain mandatory, and secrets stay out of readable files.
    5. Expect the follow-up: can network be fully blocked? Yes, the sandbox is offline by default; approve installs case by case or configure an allow-list of domains.

    分析过程 · 先想清楚再作答

    1. 这题考的是沟通加工程两层:既要说清技术上的边界,又要用对方能验证的方式说,不能只说「它很安全」。
    2. 拆成三层防线来讲:第一层文字规则(AGENTS.md)管习惯;第二层沙箱管能力,只读或只能写工作区、网络默认关;第三层审批管例外,越界的每一步都要人批。
    3. 给出可验证的承诺:所有改动都在 git 工作区里,`git diff` 能看、`git checkout` 能撤;脱手运行只跑在一次性分支或容器里。
    4. 主动说出剩余风险:模型可能误读需求写出错误但能通过的代码,所以审查和测试不能省;密钥不要放在它能读到的文件里。
    5. 可预期的追问:能不能完全禁止它联网?可以,沙箱默认就不通网,需要装依赖时逐次批准,或在配置里给一个允许的域名清单。

    Key points

    • Three layers: written rules for habits, the sandbox for capability, approvals for exceptions
    • All edits live in the git working tree and are diffable and revertable; unattended runs use throwaway branches or containers
    • State residual risks yourself: wrong-but-passing code and secret exposure, hence mandatory review and tests
    • Network is off by default; approve per request or configure an allow-list

    答题要点

    • 三层防线:文字规则管习惯、沙箱管能力、审批管例外
    • 改动全在 git 工作区,可 diff 可撤销;脱手运行只在一次性分支或容器
    • 主动说明剩余风险:错误但能通过的代码、密钥暴露,所以审查与测试不能省
    • 网络默认关闭,联网按次批准或配置允许域名清单

Comments