Agent Contracts and Receipts: toward verifiable agentic software factories
From the aiDevCon NYC talk, November 2026: Version your factory, not just your code.
Download the slides (PDF) · Read format draft 0.1 on GitHub
Someone at a bank writes one sentence: hold outgoing wires of $10,000 or more to a new payee for a second approval. Minutes later, an agentic software factory has done the work, and a pull request is waiting against the bank’s core payments system. Three files: the wire logic, a new test module, the documentation. A hundred and seventy-five lines added, nine removed. One required check, and it is green.
The bank is fictional. The code, the CI and that pull request are real.
Would you merge it without reading it?
Today the honest answer is no. The code may look fine, but nothing about the pull request tells you how it was made: which factory produced it, whether that factory is the one you approved, which checks it was held to, and whether anyone tampered with any of it on the way. So you read it line by line, the way you would read a stranger’s code.
This essay is about what it would take to say yes: a system around the model that you can version, check and admit, the way we already admit software we did not write.
Generation scaled. Delivery didn’t.
Give a factory to every team in a company of ten thousand engineers. Generation scales immediately. Delivery does not. Every pull request now waits twice: once for CI to rerun everything, and once for a human to read it. There is still one of you.
A common answer today is a risk classifier: auto-merge the low-risk changes, route the rest to a human, let CI keep rerunning everything. I think that is necessary. It is not enough. A change to how wires are approved is never low-risk, so every change that matters still lands in the human queue. And a classifier judges the change, not how it was made. It can tell you the diff touches payments. It cannot tell you whether the factory that wrote it was the one you approved, held to the checks you approved.
When I talk to enterprises about this, the same four needs come up, each with an owner who will not sign off without an answer. Verification, for the product owner: does it do what we intended? Enforcement, for the platform team: did every agent work the approved way, with our mandated skills and dependencies, at every step, not just get caught at the end by CI while it loops again? Traceability, for audit: which factory built it, at which version? Security, for the CISO: was that factory, or anything it depends on, tampered with?
A reviewer can form an opinion about the first. The other three are questions about the producing system, and the diff does not contain it.
Trust has to come from the system
My thesis:
Trust in agent-built software can’t come from the model, or from reading its output. It has to come from the system that produces it — engineered and attested like any software supply chain, on open standards.
It builds on three ideas from The Agentic SDLC Handbook:
- A smarter model is not the answer. In the first chapter I wrote that the wall teams hit when they scale AI-assisted development “is not about intelligence. It’s about information.” What fixes it is engineering discipline around the model, not a better model or another tool.
- The model proposes; something deterministic decides. The Deterministic/Probabilistic Boundary splits every agentic system in two: a probabilistic part that proposes, and a deterministic part (tests, checks, policy) that decides what actually happens. Where you draw that line matters more than which model you pick.
- Agent primitives are packages. Primitives as Code treated skills and agent configuration as packages, with manifests, lockfiles and versions. It left one problem open: when your agents run on skills published by other teams or companies, how do you know what you’re running, and who vouches for it?
Agent Contracts take the next step: packages become modules of a program. A contract imports skills by name and the lockfile pins their versions, the way a linker binds libraries. Contracts connect through the files they need and produce, so the order is derived from the data, not scripted. Each contract states its preconditions and postconditions (its checks), in the sense of Design by Contract. So an agentic software factory is a program, and like any program built from other people’s packages, it has a supply chain: an agent supply chain. Intent, contracts, skills and a coding agent go in; code comes out.
Software supply chains already let us trust code nobody in the room wrote: we give what produced it an identity, record evidence of how it was built, and have a machine check that evidence against a policy before admitting it. Agent supply chains need the same, with two changes I will come to.
The handbook’s line between proposing and deciding then becomes three roles:
Generation proposes. Verification evaluates. Policy authorizes.
A passing test is not permission to merge. A merge is not permission to deploy. The agent only generates. Checks it cannot edit do the evaluating, and rules your security team owns decide what merges.

Figure 1. The whole system on one page: a versioned factory leaves a signed receipt, and one gate at merge reads it against rules your security team owns. The rest of this essay zooms into each part.
A factory is a program
You did not set out to build a factory. You explained a repository to an agent, then captured the method as a skill, packaged skills so other teams could reuse them, automated the loop of build, check and correct, and connected those loops across planning, implementation and review. Somewhere along the way you had built a producing system. That is an agentic software factory.
A factory is a program. And the first thing any program needs is a version, because identity is what everything else attaches to. You cannot pin, inventory, trace, sign or admit something that has no identity.
Today most factories cannot be versioned, for one of two reasons. Most are loose parts: agents wired by hand to skills, prompts, plugins, scripts and MCP servers. Every piece is yours, but there is no single thing to version or sign. The rest are locked in: the factory lives inside one vendor’s harness, so it is one thing, but it only runs there. What is missing is a portable unit of agent work: one file you can version, check and sign, and run on your choice of coding agent.
I call that unit an Agent Contract. It is written down the way you would write a job contract for a new hire:
- the assignment: your intent, the one part that changes every run;
- the role: how the work is done, the same every run;
- the dependencies: the skills and packages it may use, pinned;
- the budget: how many tries and how much time;
- the checks: how the work is judged, fixed before the run;
- the deliverables: what it hands back.
It is one file, reviewed and versioned like code: composable, portable across coding agents, and identifiable by its digest. Here is the front matter of the build contract in the factory that produced the bank’s pull request (danielmeppiel/apmx-demo-factory, tag v2.0.0), unedited:
---
needs:
- request.md
- specification.md
produces:
- changes.diff
- implementation.md
imports:
- python-testing-patterns
budget:
max_attempts: 3
max_seconds: 600
verify:
acceptance-scenarios: python3 -I -B checks/acceptance.py changes.diff
regression-suite: python3 -I -B checks/regression.py changes.diff
change-scope: python3 -I -B checks/scope.py changes.diff
money-in-cents: python3 -I -B checks/money.py changes.diff
implementation-report-format: python3 -I -B checks/documents.py implementation implementation.md
---The assignment arrives as request.md. The role is the Markdown body below this block. The dependency is one pinned skill. The budget is three attempts sharing ten minutes. The checks are five ordinary commands your platform team can read. The deliverables are a diff and a report. A security reviewer can read all of it without running anything.
The name has history. Design by Contract, Bertrand Meyer’s discipline from Eiffel, gave software preconditions and postconditions. The Contract Net Protocol (Reid Smith, 1980) used contracts to allocate tasks among agents. Ye and Tan’s Agent Contracts (2026) formalize resource budgets and success criteria for autonomous agents. What this proposal adds is the rest of the supply chain: contracts composed into a versioned factory, a receipt of standard evidence for every run, signed in CI rather than by the agent, and one gate at merge that reads it against your rules.
There are two layers of checks, the same split as a CI pipeline and the test cases in a repository. The contract holds the generic, reusable checks for this kind of work: the platform’s standards. The task-specific acceptance scenarios travel with the intent, in the repository, written before the run. Here, acceptance-scenarios runs the repository’s own acceptance/*.feature files, read from the original bytes, and a patch that touches acceptance/ is rejected before anything runs.
A factory is then a graph of contracts. Each contract’s checked output becomes the next one’s input: planning hands a plan to specification, specification hands a spec to build, and so on. The whole graph is one package with one version and one factory fingerprint: a definition digest that pins every contract, every check and every skill. The bank’s factory has five contracts and eleven checks, and its fingerprint begins sha256:f6c2d240.
The factory does not name a coding agent. A harness runs each contract, and the harness is your choice of coding agent; today that means GitHub Copilot CLI or OpenCode. The factory is the program. The harness is the machine it runs on.
The fabric of trust, rewoven for factories
Over roughly twenty years, software built what I call a fabric of trust out of open standards. It has six threads, and versioning is the first: identity is what every other thread attaches to. Then inventory, provenance, evidence, signature and admission, where a machine checks all of it before anything runs. Every thread has a direct counterpart for factories.

Figure 2. The same six threads, for factories. Two of them change: evidence is re-checked rather than rebuilt, and the signature comes from CI, not from the agent.
The six threads as a table
| Thread | For software | For agentic software factories |
|---|---|---|
| Identity | versions, commits, digests | factory version and fingerprint |
| Inventory | SBOM (CycloneDX) | ABOM: the skills and packages the agent was given, pinned (CycloneDX) |
| Provenance | SLSA provenance | which factory, contract steps, agent, model and base produced it |
| Evidence | test results (in-toto) | each contract check, rerun with no agent |
| Signature | Sigstore | signed in CI by a trusted signer the agent can’t reach |
| Admission | admission control | one gate at merge that reads the receipt against your rules |
The threads come together in one artifact, which I call the receipt. Every completed run leaves one. It is a single in-toto bundle, and every statement in it is about the exact files delivered:
- SLSA provenance: which factory and version, which contract steps, which agent and model, and which base commit it started from.
- in-toto test results: one statement per declared check, each recording that the check passed on these bytes.
- An ABOM, an agent bill of materials: an ordinary CycloneDX document listing the skills and packages the factory was given, each pinned by content hash. This is the enforcement evidence: the mandated way of working was supplied. Whether it was followed is the checks’ job.
In CI, a trusted signer the agent cannot reach verifies the receipt and signs it with Sigstore, storing the attestations under each delivered file’s digest. Receipts produced on a laptop are unsigned; they bind content, not identity.
Each part is an existing open standard your supply-chain tooling already knows. What is new is the profile: how a factory’s build is described, and what an agent bill of materials should contain.

Figure 3. One receipt, four open standards, each answering one of the four needs. Condensed from the receipt behind the bank’s pull request, which shows two of its eleven check results.
A receipt on its own is a claim. Two more pieces turn it into a decision.
The rules are a policy file your security team owns: apm-policy.yml, the same file that can already govern which skills a project may install. It lists the approved factory versions by fingerprint, the trusted signer, the allowed skill sources and any revoked skills. It can be set once for the organization and inherited by every repository, and inheritance is tighten-only: a repository can narrow the rules, never loosen them. An excerpt of the factory section:
factories:
allow:
- "acme/checkout-factory@sha256:0311c27f3d7b..."
require_signed: true
signers:
- workflow: danielmeppiel/apmx/.github/workflows/run.yml
workflow_sha: fae2067a0dc6ff07beda714015ff9e648f41ce63
repo: acme/factories
revoked:
- purl: "pkg:github/acme/style@3f2a..."
bodySha256: "dead..."The gate is one required check at merge that reads the receipt against those rules; in the implementation linked at the end, it is apmx audit. It reads the policy from the base branch, never from the pull request, so a delivery cannot loosen its own rules. It looks up every changed file by its SHA-256 in the trusted signer’s attestation store, and a pull request that changes anything the signed delivery does not cover fails. Pull requests written by people fail it too, as “not a factory delivery”, and take your normal review path. The gate then reports row by row, and I group the rows under the four needs: checks for verification; dependencies and revocation for enforcement; factory and outputs for traceability; integrity and identity for security. On the bank’s pull request it took 22 seconds.
Green means something specific. It means you know which factory built the change, that it is a version you approved, that nothing was altered after signing, and which of your checks passed. It does not mean the code is right. Green is exactly as good as the checks you approved.
A factory whose every delivery carries a receipt a gate can check is what I mean by a verifiable factory.
Where the supply-chain analogy breaks
The analogy breaks in two places, and that is where the new work is.
You can’t rebuild an agent’s output, so you re-check it. Reproducible builds let a second party rebuild an artifact and compare bytes. Agents do not work that way: run the same contract twice and you get two different diffs. So instead of rebuilding, we keep the bytes and re-check them. The checks are fixed in the contract before the run, inside the fingerprint, so the agent cannot quietly change what it will be judged by. After the agent finishes, a separate job with no agent and no model token reruns those checks on the delivered files, and the receipt records those results, not the agent’s account of them.
The builder is the least trusted actor, so the verifier signs. In SLSA, the build service signs its own provenance, and we trust it because we hardened it. Here the builder is a model that can be wrong, can be prompt-injected, and can find creative ways to turn a test green. So the signature does not come from the builder. It comes from a pinned CI workflow, in a job the agent cannot reach, which verifies the receipt and signs a SLSA verification summary over the delivered files. The trust anchor moves from the producer to the verifier. This is the handbook’s boundary between proposing and deciding, made concrete: the model proposes, and something it cannot touch decides.
Three smaller breaks limit what a receipt can claim. The source is intent, not code: provenance pins exactly what was asked, not whether it was the right thing to ask. The model is recorded, not attested: the receipt records which model the harness reported, and nothing independently verifies it. And loaded is not followed: an SBOM lists components inside the binary, while an ABOM lists skills given to the agent. Whether the agent followed them is what the checks are for.
Questions an enterprise can now answer
On a Monday morning, questions land from production, security, audit and the platform team. Here are five examples, of many, with how each is answered and where the answer stops.
Production broke. Which factory, which step? Start from the file running in production and take its SHA-256 digest. CI stored the signed attestations under that digest, so the digest finds them, as long as the file is unchanged since delivery. The provenance names the factory and version, the contract steps that produced the delivery, and the skills and checks involved. That tells you what built it, not where the bug is. Whether the fix belongs in a skill, a contract or a missing check is still your call.
A skill was compromised. Who is exposed? Every receipt carries an ABOM, so you can find every delivery whose ABOM names that skill. Security adds it to the revoked list in the rules, by package identifier and content digest, and the gate blocks every new delivery built with it. Then you patch the skill and ship a new factory version. Two edges: revocation blocks new deliveries; it does not recall code that already merged. And searching every receipt across an organization is, today, a script you write over the attestation store, not a product.
The checks passed. Did the agent change them? Not quietly. The checks live in the contract, inside the factory’s fingerprint; changing one produces a new fingerprint your rules have not approved. They run in a separate job, without the agent. And the gate requires a passed result for each declared check. In the bank’s factory, a scope check also rejects any patch that edits existing tests or policy, or touches anything outside src/ and tests/. The agent was judged by the checks you approved, which are only as good as you wrote them.
We added payment checks. Are they mandatory? New checks mean a new factory version: 2.0 becomes 2.1, with a new fingerprint. Security allows only 2.1 in the rules. Anything built by 2.0 is turned away at the gate and goes to a human. The new checks are mandatory from the next merge, with no change to any repository’s gate.
Which skills and factories may our agents use? Security writes one set of rules for the organization. Skills may come only from allowed sources, checked when they are installed. Factories are allowed only in approved versions, by fingerprint. Every repository inherits the rules and can only tighten them, and the gate checks both again at every merge. Set once for the organization; enforced at install and at every gated merge.
Others follow from the same mechanisms. Which deliveries did factory v2.0 produce? Each signed receipt names its fingerprint, so the same search over the attestation store finds them. Can an auditor reconstruct, months later, what ran and what was checked for a given change? As long as you retain the attestations, the change’s own file digests lead back to the factory, the skills it was given and every check result.
Now go back to the queue from the start of this essay. A pull request from an approved factory, with its signed receipt, meets one gate that reads the receipt against your rules. The factory’s own checks are not rerun, and nobody has to read the diff to establish where it came from. Whether the change is right still rests on the checks you approved, so that is where your reviewers’ time should go. Your integration tests can, and should, still run. Anything that does not hold goes to a human, with the failing row as the reason.
What this does not do
- Green is not a statement that the code is right. If your checks are weak, green is weak.
- No SLSA level is claimed. The receipt uses SLSA formats; it does not assert a SLSA build level.
- Models are recorded, not enforced. The rules do not restrict models today.
- Revocation blocks new deliveries. It does not recall merged code.
- Skills loaded are not skills followed. The ABOM says what the agent was given, not what it did with it.
- Laptop receipts are unsigned. Only the CI signer authenticates.
- The trust roots are your CI, GitHub’s OIDC issuer and attestation store, Sigstore, and the pinned signing workflow. Whoever controls your main branch controls the gate.
- The format itself is draft 0.1. It is an invitation, not a standard.
What the industry needs
Software wove its fabric of trust in the open. Agentic factories need theirs now, and I do not think any single vendor should own it. Three things would get us most of the way:
- Define factories as code, in an open format. Agent Contracts: portable across teams and coding agents.
- Version them. Emit standard evidence. SLSA, in-toto and a CycloneDX ABOM, so any tool can verify it.
- Gate on evidence.
The first is the one that does not exist yet. The standards for the receipt are mature; what is missing is a shared way to write down the unit of agent work, and a shared profile for what an agent bill of materials should contain. I have written a first draft of both: Agent Contracts & Receipts — format draft 0.1. It is deliberately small, aligned with SLSA, in-toto and CycloneDX rather than competing with them, and I would like to work with those communities on the parts that belong upstream.
Help shape an open format for agent contracts and their receipts. Draft 0.1 is open: read it, break it, say what’s missing. The place to do that is the discussions.
You can check my claims against code rather than prose. I built two open-source projects that implement what this essay describes. APM, Microsoft’s open-source Agent Package Manager, installs the factory: it pins each skill and package to a commit and content hash, and governs them with one org-wide policy. APMX, one open-source implementation of the format, independent and experimental, runs the factory on your coding agent, writes the receipt and provides the gate. apmx --from 'danielmeppiel/apmx-demo-factory#v2.0.0' --plan shows the bank’s factory, its contracts and checks, without calling a model. Neither project is required by the format; a better runner or gate from someone else would mean the format is working. If you want to try it in your organization, start small: one repository, one factory, the gate running as a check that is not yet required, then make it required.
Go back to the pull request at the bank. Three files, one sentence of intent, one green check. With a receipt behind it, “would you merge it without reading it?” turns into three questions about your own system: did you approve this factory, do you trust its signer, and are the checks you wrote good enough to stand behind? We already answer those for every dependency we ship.
A factory is a program, so treat it like one. Version your factory, not just your code.
Help shape the format
Agent Contracts & Receipts is draft 0.1: an invitation, not a standard. Read it, break it, say what’s missing.
Get the handbook and new essays by email
The Agentic SDLC Handbook arrives right away, then new essays as they are published. Unsubscribe anytime.