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. 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.
Three questions a green run cannot answer
Each one is a command with an exit code, and each answers by running something and reporting what happened, never by reading a diff and forming an opinion about it.
adg mutate
Would your tests notice if the code broke?
It breaks the code in known ways, runs the suite against every break, and reports the breaks no test failed on.
killed 2, survived 3, timeout 0, skipped 0
adg census
Did your new test ever actually fail?
It runs the tests a change added against the code from before the change. One that passes there would have passed without the fix.
not-red-before-green: passing against the base source
adg induce
Does your error handling actually run?
It runs a failure you declare twice, once with the handling in place and once with it taken away, and fails the claim when the check passes both times.
proven 0, handler-did-not-fire 0, check-does-not-measure 1, could-not-run 0
A fourth question is what the agent then writes about the work. A rule system checks the code an agent wrote, and runtime guardrails check its inputs and tool calls while it works; neither checks the account of the work once the work is done. That is fourteen proof obligations for a delivery report, five of them checked by a hook on every commit, running 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
Hardest first. Each one run for real, with the exact output it produced. They open in the repository on GitHub.
What the gates caught here
This repository ran its own gates while it was being built, and logged what they caught in the gate tally as the work went: 103 entries, dated 2026-09-07 to 2026-09-09. Each entry is dated and says where to see the result, so any row can be opened instead of taken on trust. It is a receipt, not a claim.
| Rule | Entries |
|---|---|
induced-failure-required | 31 |
full-finding-list | 19 |
cross-cutting-audit | 14 |
named-spec-files-fail-loud | 11 |
filesystem-allowlist | 6 |
one-fail-loud-setup-script | 6 |
commit-before-mutation | 5 |
coverage-as-gap-finder | 3 |
test-diff-reported-apart | 3 |
expected-value-derived-apart | 2 |
standing-adversarial-self-review | 2 |
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.
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.
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.