Lesson 2: Write the task contract, plan it in the planning lane
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 use the planning
lane to decompose the contract before any file is touched.
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. Kimi Code’s built-in lanes make the discipline
literal: plan can think about the work but holds no write or shell
tools, so planning cannot accidentally become editing. And because
subagents cannot spawn subagents, the work never recurses out of sight.
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 let the planning lane do its job. Tell kimi:
“Use the plan subagent to turn TASK.md into an ordered implementation
plan for starter/report_tool.py: one step per failing test group, ending
each step with python verify.py starter. Do not edit anything yet.”
Read the plan it returns. It should name the same four behavior groups
you just traced to tests, in an order where each step is independently
verifiable. If a step is “improve error handling,” send it back — that is
not a contract line. A plan you can check against TASK.md line by line
is the deliverable of this lesson.
Also note what carries rules across sessions: if the repository root has
an AGENTS.md, Kimi Code reads it — durable working rules live in files,
not in a chat you will close.
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 sketch the two-step plan the plan lane should return for it.
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?
- Why does it matter that
plan has no write or shell tools?
- Why does “subagents cannot spawn subagents” make review easier?
Expected evidence
Your drafted contract line and the ordered plan you accepted (or the
version you sent back and why).