Skip to content

Commit 88488f2

Browse files
committed
feat: add the Codex CLI companion course reusing the flagship code core
C2 'Hands-on with OpenAI Codex CLI' ships EN+ZH lessons, the same three scenario skins and the same verified starter/solution/tests contract as C1 per the 0.0.3 plan reuse rule; REVIEW.md records the mechanical verification with the live Codex run-through logged as pending launch evidence.
1 parent 0ade773 commit 88488f2

30 files changed

Lines changed: 1172 additions & 6 deletions

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ This file records notable catalog-contract and maintenance changes.
1010
contracts, bilingual lesson pairs, scenario skins, task contracts, runnable
1111
starter/solution pairs, and objective `verify.py` completion evidence.
1212
- First flagship course "Hands-on Python with Claude Code" (EN+ZH, five
13-
lessons, three scenario skins, REVIEW.md run-through record).
13+
lessons, three scenario skins, REVIEW.md run-through record), plus the
14+
companion "Hands-on with OpenAI Codex CLI" course reusing the same verified
15+
code core and skins.
1416
- `tools/verify_courses.py` enforcing the course folder contract, wired into
1517
the Makefile and the validation workflow.
1618
- Project Radar per-project YAML records (`catalog/projects/*.yml`) with

content-manifest.json

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,144 @@
185185
}
186186
]
187187
},
188+
{
189+
"id": "course-codex-cli",
190+
"type": "course",
191+
"content_version": 1,
192+
"status": "reviewed",
193+
"reviewed_on": "2026-09-12",
194+
"locales": [
195+
{
196+
"lang": "en-US",
197+
"path": "courses/hands-on-with-openai-codex-cli/COURSE.md",
198+
"title": "Hands-on with OpenAI Codex CLI",
199+
"summary": "The same verified Python workflow as the Claude Code course — task contract, bounded change, objective verify.py evidence — taught hands-on with the OpenAI Codex CLI instead.",
200+
"sha256": "aa223ff4356ab25c32f55344362a5133fcba0f25851e05c6bd3c6bde9189a8aa"
201+
},
202+
{
203+
"lang": "zh-CN",
204+
"path": "courses/hands-on-with-openai-codex-cli/COURSE_cn.md",
205+
"title": "OpenAI Codex CLI 实战",
206+
"summary": "与 Claude Code 课程相同的已验证 Python 工作流——任务契约、最小变更、客观 verify.py 证据——改用 OpenAI Codex CLI 完成实战。",
207+
"sha256": "4a31ae97c205ee1e28008f1149aadf1488d4d305176678da1c475475174944d5"
208+
}
209+
]
210+
},
211+
{
212+
"id": "course-codex-cli-l01",
213+
"type": "course",
214+
"content_version": 1,
215+
"status": "reviewed",
216+
"reviewed_on": "2026-09-12",
217+
"locales": [
218+
{
219+
"lang": "en-US",
220+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L01.md",
221+
"title": "Lesson 1: Reproduce the failure with Codex in the loop",
222+
"summary": "Run the verifier both ways, map each failing test to a real-world failure class, and learn how to hand the folder to Codex.",
223+
"sha256": "794fc25625913718bdca8bf4ad71d5528d8a05b818e677002988b155087a9332"
224+
},
225+
{
226+
"lang": "zh-CN",
227+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L01_cn.md",
228+
"title": "第 1 课:让 Codex 进环,先复现故障",
229+
"summary": "双向运行验证器,把每个失败测试对应到真实故障,并学会如何把文件夹交给 Codex。",
230+
"sha256": "03b91470fcf864bbf80dc4846f7b8cb1673a47623158af776698df1cf980e76f"
231+
}
232+
]
233+
},
234+
{
235+
"id": "course-codex-cli-l02",
236+
"type": "course",
237+
"content_version": 1,
238+
"status": "reviewed",
239+
"reviewed_on": "2026-09-12",
240+
"locales": [
241+
{
242+
"lang": "en-US",
243+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L02.md",
244+
"title": "Lesson 2: Write the task contract before the change",
245+
"summary": "Turn \"make it better\" into bounded, testable statements — the single highest-leverage skill for driving Codex.",
246+
"sha256": "61411a5da9baa192923d38c2db052380663179b0c2246196ae2d0cea0a70e10f"
247+
},
248+
{
249+
"lang": "zh-CN",
250+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L02_cn.md",
251+
"title": "第 2 课:动手之前先写任务契约",
252+
"summary": "把“优化一下”变成有边界、可测试的陈述——驱动 Codex 杠杆最大的一项技能。",
253+
"sha256": "92f68d255ed3a6f68a1c3357772467e1e26dfbc75664eb88b35d7d8ca13752a6"
254+
}
255+
]
256+
},
257+
{
258+
"id": "course-codex-cli-l03",
259+
"type": "course",
260+
"content_version": 1,
261+
"status": "reviewed",
262+
"reviewed_on": "2026-09-12",
263+
"locales": [
264+
{
265+
"lang": "en-US",
266+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L03.md",
267+
"title": "Lesson 3: Drive a bounded change, test by test",
268+
"summary": "Supervise Codex through seven small diffs — smallest change, no new dependencies, one failing test group at a time.",
269+
"sha256": "50bf8c5bab11827612da38a6ff2aa56011a6db119504d8a1fe2a1ee5fc2e82b1"
270+
},
271+
{
272+
"lang": "zh-CN",
273+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L03_cn.md",
274+
"title": "第 3 课:按测试驱动一次有边界的变更",
275+
"summary": "监督 Codex 完成七个小 diff——最小变更、不新增依赖、一次一组失败测试。",
276+
"sha256": "e71a0c9f87a5f8e7f04afcbeddc89fb135f4bfb3887dcd3eb0fb1f5d4132c831"
277+
}
278+
]
279+
},
280+
{
281+
"id": "course-codex-cli-l04",
282+
"type": "course",
283+
"content_version": 1,
284+
"status": "reviewed",
285+
"reviewed_on": "2026-09-12",
286+
"locales": [
287+
{
288+
"lang": "en-US",
289+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L04.md",
290+
"title": "Lesson 4: Verify like an engineer, review like a skeptic",
291+
"summary": "Complete the evidence loop — both verification directions, all three skins, a scope-creep diff review, and a written record of what is not proven.",
292+
"sha256": "a300024f50ac832903ea4336268f53973cfec1b3192f5739e9d140f68a8bbd51"
293+
},
294+
{
295+
"lang": "zh-CN",
296+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L04_cn.md",
297+
"title": "第 4 课:像工程师一样验证,像怀疑者一样审查",
298+
"summary": "完成证据闭环——双向验证、三个皮肤、范围蔓延 diff 审查,以及一份写明未证明内容的记录。",
299+
"sha256": "43aef97d44143ac7f95ecaa63c7027fd1b63096c6def6d19bc62f59a6642d223"
300+
}
301+
]
302+
},
303+
{
304+
"id": "course-codex-cli-l05",
305+
"type": "course",
306+
"content_version": 1,
307+
"status": "reviewed",
308+
"reviewed_on": "2026-09-12",
309+
"locales": [
310+
{
311+
"lang": "en-US",
312+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L05.md",
313+
"title": "Lesson 5: Apply this to your own project",
314+
"summary": "Port the workflow — not the code — to one script you own, with tests, a verify command, and honest limits.",
315+
"sha256": "f70eae4fb1e1c367fe95001a89d77aa32e2c58470c26c2571777773e3189611e"
316+
},
317+
{
318+
"lang": "zh-CN",
319+
"path": "courses/hands-on-with-openai-codex-cli/lessons/L05_cn.md",
320+
"title": "第 5 课:把这套方法带回你自己的项目",
321+
"summary": "迁移工作流——而不是代码——到你拥有的一个脚本上,附测试、验证命令与诚实的局限说明。",
322+
"sha256": "2357b697ae279590bfb4ab268fb241918ce2075ffe7c704bcf6975a39b6b9725"
323+
}
324+
]
325+
},
188326
{
189327
"id": "example-async-fetcher",
190328
"type": "example",
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
id: course-codex-cli
3+
type: course
4+
title: Hands-on with OpenAI Codex CLI
5+
summary: The same verified Python workflow as the Claude Code course — task contract, bounded change, objective verify.py evidence — taught hands-on with the OpenAI Codex CLI instead.
6+
lang: en-US
7+
content_version: 1
8+
status: reviewed
9+
reviewed_on: 2026-09-12
10+
---
11+
12+
# Hands-on with OpenAI Codex CLI
13+
14+
> TL;DR: download this folder, open it where you run `codex`, and say **"start
15+
> lesson 1"**. You finish with a working report tool, a reproducible
16+
> pass/fail command, and a workflow that transfers to any capable coding
17+
> agent. This course reuses the scenario skins and code core of the Claude
18+
> Code course — only the tool you drive changes.
19+
20+
## What you build
21+
22+
The same scenario report tool as the flagship course: messy CSV/JSON input,
23+
invalid rows isolated instead of crashing, rounded aggregates, atomic report
24+
writes. Three scenario skins ship with the folder — pick the domain you know:
25+
26+
| Skin | You are… | Data |
27+
| --- | --- | --- |
28+
| `scenario/excel-report/` | turning a weekly orders export into a region summary | `orders.csv` |
29+
| `scenario/data-monitor/` | checking service latency numbers from your servers | `metrics.csv` |
30+
| `scenario/api-tool/` | summarizing ticket data pulled from an internal API | `tickets.json` |
31+
32+
Same code, same nine tests, different agent at the wheel.
33+
34+
## Teaching contract (read this first, agent)
35+
36+
- **Audience:** a project owner who has working-with-AI experience and is
37+
stuck on reliability — not a Python beginner tutorial, not prompt tricks.
38+
- **Prerequisites:** Python 3.11+ on PATH, the OpenAI Codex CLI installed
39+
and signed in, and the ability to run shell commands. Standard library
40+
only — nothing to install.
41+
- **Tool:** taught and reviewed against Codex CLI 0.x (reviewed 2026-09-12);
42+
a Codex CLI major release triggers a course re-review.
43+
- **Lesson order:** L01 → L05, one per session; never skip the checkpoint.
44+
- **Teaching style:** work from the files in this folder. Quote the contract
45+
line you are satisfying. Smallest change per failing test group. No new
46+
dependencies, never edit `solution/`, ask before touching files the
47+
current lesson does not name. Respect the repository's AGENTS.md rules —
48+
they apply to you.
49+
- **When to stop:** a lesson is done when its checkpoint command runs and
50+
the learner can explain what failed and why.
51+
- **`verify.py`:** `python verify.py starter --expect-failure` must reproduce
52+
the listed failures; `python verify.py solution` must pass.
53+
- **Honesty rules:** say what you did not verify; no production-ready
54+
claims; no promised outcomes.
55+
56+
## What this course does NOT cover
57+
58+
Installing Codex CLI, model selection, prompt engineering, multi-file
59+
architecture, real `.xlsx` files, or deployment. The companion repository's
60+
guides and playbooks cover those — link, don't improvise.
61+
62+
## Folder map
63+
64+
Same layout as the Claude Code course: `COURSE.md`/`COURSE_cn.md`, bilingual
65+
`lessons/`, `scenario/` skins, `TASK.md`/`TASK_cn.md`, `starter/`,
66+
`solution/`, `tests/`, `verify.py`, and `REVIEW.md`. The code contract is
67+
identical — see `TASK.md`.
68+
69+
## Evidence and licensing
70+
71+
`REVIEW.md` records the run-through state with dates and tool versions.
72+
Code is MIT-licensed; lesson prose is CC BY 4.0 (see repository `LICENSE`).
73+
Teaching drift goes to the `course-feedback` issue form.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
id: course-codex-cli
3+
type: course
4+
title: OpenAI Codex CLI 实战
5+
summary: 与 Claude Code 课程相同的已验证 Python 工作流——任务契约、最小变更、客观 verify.py 证据——改用 OpenAI Codex CLI 完成实战。
6+
lang: zh-CN
7+
content_version: 1
8+
status: reviewed
9+
reviewed_on: 2026-09-12
10+
---
11+
12+
# OpenAI Codex CLI 实战
13+
14+
> 摘要:下载本文件夹,在你运行 `codex` 的地方打开,说一句 **“开始第 1 课”**
15+
> 课程结束时你会得到一个可运行的报表工具、一条可复现的通过/失败命令,
16+
> 以及可迁移到任何编码 Agent 的工作流。本课程复用 Claude Code 课程的场景
17+
> 皮肤与代码核心——变的只是你驱动的工具。
18+
19+
## 你将做出什么
20+
21+
与旗舰课程相同的场景报表工具:混乱的 CSV/JSON 输入、无效行隔离而非
22+
崩溃、聚合舍入、原子写报告。文件夹附带三个场景皮肤——选你熟悉的领域:
23+
24+
| 皮肤 | 你的角色 | 数据 |
25+
| --- | --- | --- |
26+
| `scenario/excel-report/` | 把每周订单导出变成区域销售摘要 | `orders.csv` |
27+
| `scenario/data-monitor/` | 检查来自服务器的服务延迟数据 | `metrics.csv` |
28+
| `scenario/api-tool/` | 汇总从内部 API 拉取的工单数据 | `tickets.json` |
29+
30+
同一份代码、同一套九个测试,换一个 Agent 掌舵。
31+
32+
## 教学契约(Agent 请先阅读本节)
33+
34+
- **受众:** 有 AI 协作经验、卡在可靠性上的项目所有者——不是 Python
35+
入门教程,也不是提示词工程课。
36+
- **前置条件:** PATH 中有 Python 3.11+,已安装并登录 OpenAI Codex CLI,
37+
能运行 shell 命令。只用标准库——无需安装任何包。
38+
- **工具:** 以 Codex CLI 0.x 完成教学与审核(审核日期 2026-09-12);
39+
Codex CLI 主版本更新会触发课程复审。
40+
- **课程顺序:** L01 → L05,每次一课;绝不跳过检查点。
41+
- **教学风格:** 从本文件夹的文件出发。引用你正在满足的契约原文。每个
42+
失败测试组做最小变更。不新增依赖,不修改 `solution/`,改动当前课程
43+
未授权的文件前先询问。遵守仓库 AGENTS.md 的规则——它同样约束你。
44+
- **何时停止:** 检查点命令运行通过、且学习者能说清什么失败了、为什么。
45+
- **`verify.py`** `python verify.py starter --expect-failure` 必须复现
46+
列出的失败;`python verify.py solution` 必须通过。
47+
- **诚实规则:** 说明哪些没验证过;不宣称生产可用;不承诺结果。
48+
49+
## 本课程不涉及的内容
50+
51+
Codex CLI 安装、模型选择、提示工程、多文件架构、真正的 `.xlsx` 文件、
52+
部署。这些在配套仓库的指南与手册里——链接过去,不要现场发挥。
53+
54+
## 文件夹结构
55+
56+
与 Claude Code 课程相同的布局:`COURSE.md`/`COURSE_cn.md`、双语
57+
`lessons/``scenario/` 皮肤、`TASK.md`/`TASK_cn.md``starter/`
58+
`solution/``tests/``verify.py``REVIEW.md`。代码契约完全一致——
59+
`TASK.md`
60+
61+
## 证据与许可
62+
63+
`REVIEW.md` 记录带日期与工具版本的试跑状态。代码采用 MIT 许可;课程
64+
文字采用 CC BY 4.0(见仓库 `LICENSE`)。教学偏差请走 `course-feedback`
65+
issue 表单。
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Maintainer run-through record
2+
3+
## 2026-09-12 — contract verification (mechanical)
4+
5+
- Environment: macOS (arm64), Python 3.13; repository clean checkout on
6+
branch `feat/0.0.3-courses-and-radar`.
7+
- The code core is the reviewed Claude Code course core reused per the 0.0.3
8+
plan §2.2 ("reuse C1 skins"): same starter/solution/tests contract.
9+
- Commands and results:
10+
- `python verify.py starter --expect-failure` — exit 0; all seven expected
11+
failure names reproduced.
12+
- `python verify.py solution` — exit 0; 9/9 tests pass.
13+
- All three skins exercised end to end by the shared suite.
14+
- Not verified in this pass: teaching quality with a live Codex CLI session.
15+
16+
## Pending before the public course drop
17+
18+
- One full agent-taught run-through with Codex CLI 0.x ("start lesson 1"
19+
through the Lesson 5 checkpoint), recording observed deviations from
20+
COURSE.md here; the recording doubles as demo-video source material.
21+
22+
## Deviation log
23+
24+
(none recorded yet — first agent-taught run-through pending)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Task contract: scenario report tool (hands-on course core)
2+
3+
Change only `starter/report_tool.py`. Standard library only; no new
4+
dependencies.
5+
6+
- `load_records(path) -> list[dict]`:
7+
- `.csv` files load through `csv.DictReader`.
8+
- `.json` files load as a list of objects; a non-list or non-object payload
9+
raises `ValueError`.
10+
- Any other suffix raises `ValueError` naming the unsupported file.
11+
- `build_report(records, *, required_fields, numeric_field, group_field) -> dict`:
12+
- Returns `{"total", "valid", "invalid", "groups", "errors"}`.
13+
- Invalid rows never abort the run: each is collected in `errors` as
14+
`{"index": <row position>, "reason": <short string>}`. Invalid means:
15+
not a dict, missing or blank required field, or a non-numeric
16+
`numeric_field` value (booleans do not count as numbers).
17+
- Valid rows aggregate into `groups[group_value] = {"count": int,
18+
"total": float}`; each group total is rounded to two decimals.
19+
- `total = valid + invalid` must hold for every input.
20+
- `write_report(report, destination)`:
21+
- Writes JSON (UTF-8, indent 2, trailing newline) atomically: write a
22+
sibling temp file, then `os.replace`.
23+
- Creates missing parent directories.
24+
- Never leaves a `.tmp` file behind on success.
25+
- `run_scenario(scenario_dir) -> dict`:
26+
- Reads `scenario.json` (`data_file`, `required_fields`, `numeric_field`,
27+
`group_field`, `report_file`), processes the data file, writes the
28+
report inside the scenario directory, and returns the report.
29+
- `main(argv=None) -> int`:
30+
- Exactly one argument (the scenario directory). Otherwise print usage to
31+
stderr and return 2.
32+
- On success print `total=... valid=... invalid=...` to stdout and return 0.
33+
- On input failure print `error: ...` to stderr and return 1.
34+
35+
Done means `python verify.py starter` exits 0 with all nine tests passing,
36+
and `python verify.py starter --expect-failure` exits nonzero because the
37+
starter no longer reproduces the unfinished state.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# 任务契约:场景报表工具(实战课程核心)
2+
3+
只修改 `starter/report_tool.py`。仅用标准库;不新增依赖。
4+
5+
- `load_records(path) -> list[dict]`
6+
- `.csv` 文件经 `csv.DictReader` 加载。
7+
- `.json` 文件按对象列表加载;不是列表或元素不是对象时抛出
8+
`ValueError`
9+
- 其他后缀抛出 `ValueError`,并指明不支持的文件名。
10+
- `build_report(records, *, required_fields, numeric_field, group_field) -> dict`
11+
- 返回 `{"total", "valid", "invalid", "groups", "errors"}`
12+
- 无效行绝不中止运行:每行以 `{"index": <行位置>, "reason": <简短
13+
说明>}` 收集进 `errors`。无效指:不是字典、必填字段缺失或为空、
14+
`numeric_field` 不是数字(布尔值不算数字)。
15+
- 有效行聚合为 `groups[分组值] = {"count": int, "total": float}`;每个
16+
分组总计保留两位小数。
17+
- 任何输入下都必须满足 `total = valid + invalid`
18+
- `write_report(report, destination)`
19+
- 原子地写入 JSON(UTF-8、缩进 2、末尾换行):先写同名临时文件,再
20+
`os.replace`
21+
- 自动创建缺失的父目录。
22+
- 成功后不留任何 `.tmp` 文件。
23+
- `run_scenario(scenario_dir) -> dict`
24+
- 读取 `scenario.json``data_file``required_fields`
25+
`numeric_field``group_field``report_file`),处理数据文件,把
26+
报告写进场景目录,并返回报告。
27+
- `main(argv=None) -> int`
28+
- 恰好一个参数(场景目录)。否则向 stderr 打印用法并返回 2。
29+
- 成功时向 stdout 打印 `total=... valid=... invalid=...` 并返回 0。
30+
- 输入失败时向 stderr 打印 `error: ...` 并返回 1。
31+
32+
完成的标准是 `python verify.py starter` 以 0 退出且九个测试全部通过,
33+
同时 `python verify.py starter --expect-failure` 非零退出——因为
34+
starter 已不再复现未完成状态。

0 commit comments

Comments
 (0)