AI Team Playbook / Rule 7 of 12
Every contract has a file and two tests
Every place two components must agree on a shape has a file that states the shape, a test on the producing side, and a test on the consuming side.
September 16, 2026 · About 2 minutes
Why
Contracts are where parallel work breaks, and where agents fail silently. An agent working on one side of a boundary cannot see the other side. It renames a field, its own tests pass, and the consumer on the other side starts seeing an empty value and skipping it. Nobody notices for weeks.
The worked example in the kit is a Python extraction service that writes field names into a JSON document, and a .NET rules engine that reads them. Nothing connected the two. Each rule’s unit tests hand-wrote their own field names, so a rename on either side failed without a sound.
How
What counts as a contract. An API route and its payload. A queue message. A set of field names one service writes and another reads. A generated manifest. The test: if two of these are true, it is a contract. Two deployable units depend on it. Changing it needs a coordinated release. A mismatch fails silently rather than loudly.
Every contract gets three things.
- A file in the repository, under
contracts/, that states the shape in a machine-readable form. Generated where possible, never edited by hand. - A test on the producing side that fails when the file no longer matches what the code writes. This tells you the file is stale.
- A test on the consuming side that fails when the code reads something the file does not contain. This tells you a consumer is dead.
The pair is the point. One test alone leaves one direction of failure silent.
In the worked example, the fix was a generated manifest of every field name each document type produces, a test in the Python service that fails when the checked-in manifest is stale, and a test in the .NET project that fails when any rule reads a field no flattener produces, naming the rule and the document type. A README under contracts/ lists each file, the command that regenerates it, and its two tests. That README is the whole documentation of the boundary.
The rule for tasks. A task that changes a contract runs first, alone, and merges before any task that depends on it starts. The task template’s Contract: line makes this visible in the tracker. The instruction file tells the agent: before changing anything under contracts/ or any field another component reads, stop and say so.