Kairokuplaybook
Orchestration

Conventions and patterns

What a run reads about your repository before its first write, and who is allowed to change it.

An agent that has never seen your repository writes code that compiles and looks nothing like the rest of the tree. The fix is not a longer prompt. It is two files in the repository, read by every role before its first write, and changed the same way every other file in the repository changes — through a pull request a person merges.

FileWhat it holdsWho reads it
AGENTS.md / CLAUDE.md at the rootThe repository's conventions and its non-negotiablesEvery role a run launches; Codex reads AGENTS.md, Claude reads CLAUDE.md
.kairoku/patterns.mdExemplar snippets, each with a one-line whyEvery role a run launches
.kairoku/rules/*.ymlThe shapes the repository refuses, machine-checkedThe daemon — see the repo's own rules

The three are a ladder, not alternatives. Conventions are prose a model interprets. Patterns are the shape you actually want, shown rather than described. A rule is the one a machine enforces, and you write one only when a defect proved the prose was not enough.

Codex reads AGENTS.md and Claude reads CLAUDE.md, which is why the Kairoku repository mirrors its invariants verbatim in both files rather than having one import the other. A test diffs them.

patterns.md is exemplars, not rules

Each entry is a snippet the repository is proud of and one line saying what it buys — the shape it actually wants, as opposed to the shape that merely compiles. Keep it short: it is read before the first write of every run, and a hundred-line file is a file nobody finishes.

Add an entry when a reviewer praised something, or when a defect proved its absence, and cite which. Here is the app's own first file, in outline — six patterns, each a snippet and a why:

## Capture the real export by value before you mock it

const nextCache = await import("next/cache");
const realUnstableCache = nextCache.unstable_cache; // BY VALUE, before the mock
mock.module("next/cache", () => ({ ...nextCache, unstable_cache: identityCache }));

Why: `mock.module` mutates the namespace object in place, so a fall-through that reads the
export back off it calls the stub and wedges the run with no output and no counts
(KAIR-188, 11 files). Machine-checked by `.kairoku/rules/no-self-delegating-mock.yml`.

Note the last line. A pattern and a rule can name the same thing from two directions: the pattern says what to write, the rule catches what you wrote instead. The others in that file are the same shape — fake the edge, keep the real builder; red first, and quote the failure; assert the render, never the source; name the ceiling you accepted; pin a repo invariant with a scan, not a list — each with the pull request or the defect that earned it.

The file opens by saying what it is, so a run that reads only the top still knows the contract:

Exemplars, not rules. The rules are the seven invariants in CLAUDE.md / AGENTS.md and the machine-checked shapes in .kairoku/rules/. Read this before your first write in this repo.

One writer per resource

A run may change .kairoku/patterns.md only when the item it was given is what changes it. Any other change to that file is a defect — the reviewer reports it as one, naming the lines added.

That constraint is what keeps the file worth reading. Without it, every run that learned something would append to it, and a file appended to by fifty agents is a changelog nobody reads rather than a set of exemplars anybody follows.

So a pattern an implementer thinks ought to be recorded, but which is outside its item's scope, goes in its report, not in the file. Somebody reads the report and decides.

There is no cross-run scribe, and no injection machinery: the roles are simply told to read the files, the way they are told to read anything else in the checkout.

Changes ride a run's pull request

A change to patterns.md or to AGENTS.md is part of the run's diff, on the run's branch, in the run's pull request — and it reaches the next run only after a person merges it. That is the same gate the rules sit behind, and for the same reason: what a repository says about itself is not something an agent gets to change on its own recognisance mid-run.

The practical shape of it:

A run reads AGENTS.md/CLAUDE.md and .kairoku/patterns.md before its first write, and matches them.

If the item it was given is what changes a pattern, it edits the file in its own diff. Otherwise it writes the observation into its report.

The reviewer checks the diff against those same files — code that ignores the patterns is a finding — and treats an out-of-scope edit to patterns.md as a defect.

You merge, or you do not. The next run reads what you merged.

Starting a file

You do not need a blank page. A repository that has been reviewed for a while already has the material:

  • the worked examples in your own CLAUDE.md / AGENTS.md;
  • whatever a code-search assistant already keeps as project conventions;
  • the last dozen merge bodies — what reviewers praised, and what they kept catching.

Sixty lines is plenty for a first version. Then let it earn its entries one defect at a time.

On this page