Verification contracts: teaching your repo how to prove itself
A repository carries its code, and if you're lucky its tests. What it almost never carries is a durable answer to a plainer question: how do we prove this behavior actually works, and what does a red check imply? An agent finishes a feature, figures out the run-and-verify steps in its head — the migrations, the seed fixtures, the sample request, the status code it expects — and then the session ends and every one of those steps evaporates. The next agent rediscovers them from scratch. We think that operational knowledge deserves the same treatment Metatron already gives architectural knowledge: a reviewed, versioned artifact. That is the Repository Verification Layer, shipped in Metatron 0.13.0, and its unit is a verification contract.
The gap: proof that never gets written down
Metatron's job so far has been to capture how an agent should think about a repository — the intent, the invariants, the conventions — as curated markdown it consults before writing code. It says nothing about how to prove a change works when you run it. And that's a real gap, because the run-and-verify knowledge is exactly the kind that lives nowhere durable.
Watch what happens today. An agent lands a change, writes a unit test or two, and then — when a human or the next agent asks "how do I actually run this?" — reconstructs the operational steps inside its prompt window: bring the services up, apply the migrations, seed the fixtures, fire a request, check the status code and the response shape. None of that is committed. When the session closes it's gone, and the next agent rediscovers it from first principles. It's the same rediscovery problem Metatron already solves for architecture, only pointed at verification. Repositories have no durable, machine-readable, human-reviewed artifact that answers "how do we prove this behavior, and what does a failure imply?"
What a verification contract is
A verification contract is a git-tracked OKF
markdown file that lives right beside your decisions, under
context/verification/. It reuses the machinery decisions already
run on: the same frontmatter and scope: model that binds a contract
to a subsystem, the same reserved-filename discipline, the same mirror
import/export path. A contract has a handful of explicit sections the parser
keys off — the body stays human-readable and diffs cleanly:
- Assumptions — the pre-existing state to verify before anything runs (a database reachable, an env var set).
- Setup — the commands that stage the world: migrations, seed fixtures.
- Checks — each an action plus its expected assertions
(a status code, a JSONPath value, a substring), tagged so you can select a
slice like
smokeorcritical-path. - Failure Means — the part that doesn't exist anywhere else.
- Teardown — put the world back, whether the checks passed or not.
Because a contract is scoped to one subsystem and indexed like a decision, an
agent working on auth pulls the auth contract and nothing else. That's a
deliberate echo of what our context
inheritance study found about delivery: selection beats volume. A single
monolithic testing.md read into a context window crowds out the
task the same way a decision monolith did — it landed below the
no-context baseline while costing the most tokens. Scoped, served on demand,
never concatenated. That selective serving is the whole reason to build this
inside Metatron rather than leave it a loose docs/testing.md
convention.
The differentiator: "Failure Means"
Every test runner tells you a check went red. None of them tells you what red implies. That's the section we care about most. Failure Means is a curated mapping from a specific red check to the subsystem that is probably at fault — so a failure routes to the right fix instead of sending someone off to guess.
Concretely, for an auth contract it reads like this: a 401 on the happy path
points at a seed hash mismatch or a missing user, or a JWT_SECRET
that isn't set; a 500 on the wrong-password path means the auth middleware is
leaking an unhandled exception; a connection refused means the gateway is down
and setup never completed. No existing tool — not pytest, not Postman, not
Playwright, not Bruno — encodes what a failure implies about which subsystem.
It is a curated decision about failure modes, the same kind of distilled
operational judgment Metatron already stores for architecture, and it's what
lets a reading agent turn a red result into a directed fix.
Who authors it: the agent that just built the feature
Here's where the design leans directly on something we published. In the context inheritance study, the single variable that decided whether repository context helped was the capability of whoever wrote it relative to the agent that reads it. Context is worth most when it's authored by whoever holds the most capability and the most context. For a verification contract, that author has an obvious identity: the agent that just finished building the feature, at the exact moment it holds the most context it will ever have about how the thing works.
So metatron verification setup wires a one-time instruction into
AGENTS.md: after finishing a testable feature, draft a
verification contract describing how to prove it works and what a failure
implies. The just-built agent is its strongest possible author. But — and this
is the invariant we hold everywhere — a draft is never self-canonical. It lands
through the same review gate as decisions: either straight onto a working branch
where the reviewed pull request that merges it is the curation act, or staged as
a candidate a human promotes with a reviewed git mv. A human placing
or approving the file into verification/ is the curation act.
Nothing crosses that boundary on its own.
Running it: executable-first, and selective
The contract is inert markdown until someone runs it. That's
metatron verification run — a plain developer-and-CI command. The
first milestone is deliberately boring in the best way:
executable-first. It evaluates the declared assertions
deterministically — status and exit codes, substrings, JSONPath, regex, with a
shell-assertion escape hatch — with no model in the loop. It's cheap, offline,
and it exits non-zero on failure, so it drops into CI and pre-commit unchanged.
It's selective by design, the same lesson as serving, one level
down. With no scope it runs every canonical contract; narrow it with
--scope or --tags and CI can run just the
smoke and critical-path checks on every pull request
while a nightly job runs the full set. Run beats a monolith. And when a check
goes red, the report prints that check's Failure Means line
right next to it — the differentiator carried all the way through to the output,
so the person (or the agent reading the report) routes the failure instead of
guessing.
There's a later, opt-in --judge mode on the roadmap for invariants
no assertion can express — "the error copy stays user-neutral," "the migration
is reversible" — where a model judges a check against the contract's intent.
It's explicitly opt-in, clearly labeled non-deterministic, and never the default
or a merge gate on its own. Phase one ships without it.
The honest fence: Metatron serves, the operator runs
Now the part we want to be exact about, because it's easy to get wrong. Metatron runs against private codebases with an on-prem, offline posture — your source never leaves the machine. Given that, execution has to sit on the right side of a trust boundary, and we draw it hard.
Metatron's serving path never executes a contract. There is no
run_verification MCP tool, no runner behind the request path. On a
private on-prem deployment, a primitive that let the serving layer pipe
markdown-defined shell commands into a runner would turn any writable
context/ file — or a prompt-injected candidate — into an
arbitrary-code-execution vector reachable over the wire by any agent. So the
serving surfaces stay strictly read-only: an agent can fetch a contract to read,
never to run.
run is a different trust boundary entirely. It's a command a
developer (or a CI job they configured) invokes in their own shell, foreground,
with their own privileges — identical in trust to running the commands or
pytest by hand, which they could always do. And it's readable before
it's run: --dry-run resolves and prints the ordered plan and the
resolved assertions without executing anything, so you can see exactly
what a contract would do before you let it. Two rules keep the fence honest:
nothing an agent reaches over MCP ever runs, and only a human or a CI job they
set up ever triggers execution. An agent-authored or injected contract is inert
until a person chooses to run it — the same human gate that guards
canonicalization guards execution.
Where this is headed
Phase one is live in Metatron 0.13.0 — the metatron verification
commands and the read-only MCP tools — with the --judge mode still
ahead. The shape is consistent with everything Metatron already is. A repository
should carry not just how to think about itself, but how to prove itself: a
curated artifact, authored by whoever holds the most context at the moment of
most context, served selectively to whatever agent shows up next, and executed
only by a human or CI on their own trusted side of the wire. The durable value
stays where Metatron always puts it — in the reviewed artifact and, above all,
in the curated reading of what a failure means.