A green run that proves nothing
A shopping cart with four passing tests. An agent is asked to add promo codes. It does, and it adds three tests for the new behaviour.
$ node --test tests/*.test.js
# tests 7
# pass 7
# fail 0
Four tests became seven. Nothing failed. The feature works. Coverage went up. A customer whose cart comes to exactly 50 has just started paying for shipping, and the test that would have said so was edited, in the same commit, until it could no longer fail.
Every check a project normally runs got better here, which is the point. A green run and a green run over checks that cannot fail look the same from outside, and only one of them means anything.
A rule system checks the code an agent wrote. Runtime guardrails check its inputs and tool calls while it works. Neither checks what the agent claims about its own work once the work is done, which is what this project is for: fourteen proof obligations for a delivery report, five of them checked by a hook on every commit, tooling that runs the same way in Claude Code, Cursor, Codex, GitHub Copilot, CI, or a plain pre-commit hook with no agent at all, and an MCP server for an agent that would rather ask than be stopped.
Seven worked examples
Each one run for real, with the exact output it produced. They open in the repository on GitHub.
Install
npm install --save-dev agent-delivery-gates
npx adg init
git config core.hooksPath .githooks
init writes a git pre-commit hook, AGENTS.md, an empty
gate tally log, a CI workflow, and the hook and MCP configs for the agents
listed below, and only ever creates a file that does not already exist.
--dry-run prints what would happen without writing anything,
--force overwrites a file that already exists, and
--dir PATH targets a directory other than the current one.
Every check is a command of its own, read here out of the command line
entry point: validate-report, test-diff, mutate, census, induce, tally, scan-prose, check. Each is an ordinary program with an exit code,
so it runs from any pre-commit hook or CI job.
agent-delivery-gates mcp starts a local MCP server on stdio: a
client starts it, writes to its stdin and reads its stdout, and nothing about
a project's code or reports leaves the machine.
Node 22.18 or newer. No runtime dependencies. Licensed under Apache 2.0.
Where it runs
| Agent | Wiring |
|---|---|
| Claude Code | a plugin that wires its own hooks in with no init step needed, or the lines init prints for .claude/settings.json |
| Cursor | .cursor/hooks.json, written by init |
| Codex | .codex/hooks.json, written by init |
| GitHub Copilot | .github/hooks/agent-delivery-gates.json, written by init |
| CI, no agent | .github/workflows/agent-delivery-gates.yml, written by init |
| Command line, no agent | validate-report, test-diff, mutate, census, induce, tally, scan-prose, check, run directly or from any pre-commit hook |
The Codex, Cursor, and Copilot hook configs use each platform's tool names as best guesses. Only the Claude Code plugin has run against the real tool, so the other three configs have not been loaded and confirmed by the coding tool they target.
The fourteen rules
All fourteen are recorded in
the rules directory, one JSON file per
rule. Everything below is read out of those files at build time, so this page
cannot describe a rule the records do not carry. Grouped by each record's own
enforcement field.
Enforced by a hook (5)
Checked mechanically on a relevant tool call or on every commit.
-
commit-before-mutationCommit before mutation
A claim that a deliverable is finished and safe to hand to a reviewer for mutation testing.
Emits
missing-commit-line -
filesystem-allowlistFilesystem allowlist
A claim that a build agent's filesystem access stayed within its intended scope.
Emits
path-allowlist-confinement -
full-finding-listFull finding list
A deliverable that runs an automated or human reviewer over the work and then reports on the review.
Emits
finding-list-incomplete,open-finding-not-carried -
induced-failure-requiredInduced failure required
Robustness, safety, and correctness claims: a report that says something is handled, isolated, recovered, prevented, rejected, or validated.
Emits
unproven-robustness-claim,evidence-not-durable -
test-diff-reported-apartTest changes reported apart from source changes
A claim that a fix works, resting on a test run that came back green.
Emits
assertion-removed,assertion-weakened,test-case-removed,test-file-declassified,skip-added,tolerance-widened,timeout-raised
Carried by prompt instructions (7)
No mechanical check today. These depend on the agent following the instruction and on a person reading the report afterward.
-
artifact-inputs-reproducibleArtifact inputs reproducible
A claim that a step produced an artifact whose content depends on specific inputs, such as a generated image with a prompt and a seed, a scaffold built from a template, or a dataset pulled from a query.
-
coverage-as-gap-finderCoverage as gap finder
A claim that test coverage supports confidence in a phase or step.
-
expected-value-derived-apartExpected value derived apart
A claim that something was checked: a test, an assertion, a gate, or a report stating that a page, a document, or a count agrees with the record behind it.
-
named-spec-files-fail-loudNamed spec files fail loud
A claim that a prompt needing specification or reference files used the right ones.
-
one-fail-loud-setup-scriptOne fail-loud setup script
A claim that a deliverable's manual setup steps are ready for a human to run.
-
red-before-greenRed before green
A claim that a bug fix actually fixed something.
-
standing-adversarial-self-reviewStanding adversarial self-review
A claim that a build step is finished and ready to hand off, before any reviewer has looked at it.
Needs a human gate (2)
No script can confirm these from the outside. They can be arranged for and then checked.
-
builder-reviewer-separationBuilder reviewer separation
A claim that independent review happened during a build.
-
cross-cutting-auditCross-cutting audit at phase boundaries
A claim that a multi-step build is internally consistent across steps, not just correct step by step.
What the gates caught here
Building this project produced its own record of what its gates caught, logged in the gate tally as the work went: 98 entries, dated 2026-09-07 to 2026-09-09. Each entry says where to see the result, so any row can be checked instead of taken on trust.
| Rule | Entries |
|---|---|
induced-failure-required | 31 |
full-finding-list | 19 |
cross-cutting-audit | 13 |
named-spec-files-fail-loud | 11 |
commit-before-mutation | 5 |
filesystem-allowlist | 5 |
one-fail-loud-setup-script | 4 |
coverage-as-gap-finder | 3 |
test-diff-reported-apart | 3 |
standing-adversarial-self-review | 2 |
expected-value-derived-apart | 1 |
red-before-green | 1 |
artifact-inputs-reproducible | 0 |
builder-reviewer-separation | 0 |
A zero does not mean a rule was unnecessary. It means the work stayed clean on that rule for the life of this build, or nothing looked closely enough to catch anything on it yet, and the count alone cannot tell you which.
Questions
Does this need an AI agent to run?
No. The command line tools are ordinary programs with exit codes. The same checks run from a git pre-commit hook, from CI, or by hand, with no agent involved.
Does anything leave the machine?
No. The MCP server is a local subprocess on stdio, not a hosted service. Nothing about a project's code or reports leaves the machine, and there is no analytics or telemetry.
How many of the fourteen rules are checked mechanically?
Five of the fourteen are enforced by a hook that runs on a tool call or a commit. Two commands go further than that grouping suggests: census runs a change's new tests against the code from before the change, which is the mechanical half of red-before-green, and induce runs a declared failure with the handling in place and again with it taken away, which is what induced-failure-required asks for. The rest are carried by prompt instructions or need a person, and the catalog says which is which.
What does a rule with zero tally entries mean?
A zero does not mean a rule was unnecessary. Two of the rules sit at zero. It means the work stayed clean on that rule for the life of this build, or nothing looked closely enough to catch anything on it yet, and the count alone cannot tell you which.