Edison SinaniAI implementation architectBook a call

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.

Contents

The playbook

  1. Overview

Before code

  1. 1Write the constitution first
  2. 2One instruction file, under 200 lines
  3. 3Prose is advice, hooks are enforcement
  4. 4Three gates before any code
  5. 5A walkable demo before any screen

Building

  1. 6One task, one worktree, one pull request
  2. 7Every contract has a file and two tests

Reviewing

  1. 8AI review first, and filtered
  2. 9Human review by risk tier
  3. 10Done means the evidence is in the pull request

Over time

  1. 11Measure five numbers from day one
  2. 12Protect the people who are still learning

Appendix

  1. AInstall checklist
  2. BOther tools, limits and sources
  3. CTightening the process
  4. DRun the agent with no entitlements

Get the kit

Who owns it
Whoever changes a contract changes both tests in the same pull request. The reviewer of record watches the system design's contract section.
In the kit
docs/contracts.mdcontracts/docs/design.md, section 4
Enforced by
The reviewer agent and the automated review both flag a contract change without both tests. A contract task is never marked parallel.

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.

  1. A file in the repository, under contracts/, that states the shape in a machine-readable form. Generated where possible, never edited by hand.
  2. 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.
  3. 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.