Lesson 2: Write the task contract, let AGENTS.md carry the rules
Objective
You can read TASK.md as a set of testable statements, trace each statement
to a test in tests/test_report_tool.py, and write durable rules a Codex
thread will pick up automatically.
Why this lesson exists
Vague requests produce vague code. “Handle bad rows better” gives an agent
permission to guess; “invalid rows are collected in errors with index and
reason, valid rows still produce a report” gives it a target and gives you a
way to check. In the Codex app there is a second failure mode: a rule you
typed into one thread does not exist in the next. The contract fixes the task;
AGENTS.md fixes the working rules.
The lesson
Open TASK.md. Notice what every line has in common: it names an observable
behavior, not an implementation. Four statements from the contract, and the
tests that pin them:
| Contract line | Test |
|---|
| “a JSON file loads into the same record list as CSV” | test_load_json_records_returns_list_of_dicts |
“invalid rows land in errors with index and reason; valid rows still aggregate” | test_invalid_records_are_isolated_with_reasons |
| “group totals are rounded to two decimals” | test_group_totals_are_rounded_to_two_decimals |
| “the report write is atomic and creates missing parents” | test_write_report_creates_missing_parent_directories |
Now the durable half. Codex reads AGENTS.md files before doing any work —
a global file in ~/.codex, then project files from the repo root down to
your directory; closer files win. This course’s working rules are exactly the
kind of thing that belongs there. Open a scratch file and draft three rules
for this project, for example:
- Change only starter/report_tool.py. tests/, solution/, scenario/ are read-only.
- One failing test group per turn; run `python verify.py starter` after each.
- Standard library only — no new dependencies.
Tell the thread: “Here are the rules I want for this project — write them
to AGENTS.md at the folder root so every future thread starts with them.”
Then start a new thread and ask it to summarize its working rules. If it
quotes your three lines back, the instruction chain is working; if not, check
where the file landed.
Exercise
Write one contract line for a script you actually own, using the same shape:
inputs, outputs, error cases, and “done means <command> exits 0”. Then write
the two rules you would put in that project’s AGENTS.md.
Checkpoint
Run python verify.py — this checkpoint’s claim code prints when
you can answer:
- Which
TASK.md line does test_invalid_records_are_isolated_with_reasons
pin, in your own words?
- Which file carries rules across threads — the prompt, or AGENTS.md?
- Where does a global
~/.codex/AGENTS.md sit in precedence versus the
project file?
Expected evidence
Your drafted contract line, your two rules, and the thread’s summary of its
own working rules from the new thread.