All posts

Engineering

Coding agents write most of my code. They don't decide what ships.

How shared instructions, repository-aware review, and fail-closed gates let me merge agent-written changes without lowering the quality bar.

·7 min read

Agent confidence is not evidence

Coding agents write most of my code. They do not decide when it is ready.

In my workflow, the hard part is no longer producing code. It is deciding which changes deserve to reach main.

Agents make code cheap. They also make convincing mistakes cheap. A change can compile and look polished while hiding a broken contract, a stale assumption, or a repair that introduced another defect. A model can say the checks passed without showing which checks ran. A second model can approve the same assumption with equal confidence.

So I do not ask the model whether the work is done. I ask the repository.

Every change has to meet the same bar: strict types and linting, tests, the production build, WCAG 2.2 AA accessibility checks, repository structure, synchronized instructions, and declared GitHub state. If a required check finds a problem, errors, or cannot prove what it checked, the merge stops.

That is how I use coding agents aggressively without making their confidence part of the trust model.

The boundary

An agent can propose code, repair findings, and explain its work. It cannot give itself the final verdict.

The repository has to prove the work

A green gate is an evidence trail, not an agent's opinion.

Each repository runs one required gate over the exact change it is about to merge. The gate starts by checking the shared engineering contract, then runs the repository's own code and behavior checks.

  • Strict TypeScript and Biome configuration turn warnings, type mismatches, and unsafe shortcuts into failures.
  • Unit tests and the production build check behavior and integration, not just whether the files parse.
  • Playwright and Axe scan every browser route against WCAG 2.2 AA.
  • Structure, synchronized files, generated configuration, and live GitHub settings are checked for drift.

The exact checks vary with the repository. The rule does not. Required evidence must come from the system around the change, not from the final message written by the agent that produced it.

  1. 01

    Share the contract

    Synced instructions and repo-local rules define the work.

  2. 02

    Agent writes

    A coding agent implements the change and repairs accepted findings.

  3. 03

    Gates verify

    Types, lint, tests, accessibility, and repository state run on the exact commit.

  4. 04

    Human decides

    The evidence and remaining risk return to a person for the merge.

The agent can propose and repair a change. It cannot give itself the final verdict.

One contract for humans and agents

The same non-negotiable rules have to reach every repository that uses them.

The public source of truth behind the repositories I maintain is the standards repository. Its AGENTS.md defines architecture boundaries, quality rules, package management, error handling, and the final merge process for both people and coding agents.

Reusable skills add narrower instructions for review, CI, databases, infrastructure, and interface work. The contract says where a decision belongs. The gate checks whether the repository still follows it.

The @davidvornholt/standards CLI mirrors the shared files into each consumer and records their exact state. Every consumer runs standards check before its own lint, types, tests, build, and accessibility suite. A repository cannot call itself green while the contract it claims to follow is already stale.

Why sync instead of copy

A template gives a repository a good first day. Synchronization gives it an upgrade path.

Every file needs one owner

Central rules and local decisions have to coexist without silent forks.

Making every file identical would be simple and useless. Projects need different databases, deployment targets, and product rules. Letting every project edit the shared files would be flexible and would destroy the standard.

The sync system resolves that tension by assigning every managed file to one of three classes.

01

Synced

The standards repository owns the file.

AGENTS.md

Sync replaces local edits, and check reports drift.

02

Repo-owned

The consuming repository owns the file.

AGENTS.local.md

Sync preserves it as the approved place for local decisions.

03

Generated

The engine composes the file from shared and local inputs.

.github/dependabot.yml

Hand edits are drift because the output must be reproducible.

Central rules and local choices can coexist when every file has one clear owner.

Local variation goes through named extension points. A repository adds its own instructions in AGENTS.local.md. Its repo-owned biome.jsonc extends the shared linter. Project-specific operator commands live in local.just. The shared file stays unchanged.

A weekly workflow turns upstream changes into ordinary pull requests. New rules arrive as a visible diff, run against the consumer's own gate, and wait for the same merge decision as application code. Local edits to canonical files are drift. Local decisions made through the approved seams are part of the design.

The repository itself is checked

Correct application code can still be merged through a broken process.

Tests do not tell me whether somebody enabled merge commits, removed a required status check, changed a branch rule, or let repository configuration drift away from the declared policy. Those settings decide what can ship.

The standards repository therefore declares the expected GitHub state in code. The gate compares that declaration with the live repository and fails on drift or on an API error that prevents verification. An administrator-only apply command brings the live settings back to the declaration.

This makes the delivery process reviewable. Source files, quality gates, merge policy, rulesets, and selected labels all have a versioned home. Passing tests is necessary. It is no longer the only evidence required to merge.

Strict automation can still fail

A gate can enforce a bad rule with perfect consistency.

My most expensive lesson came from an experimental review workflow in the standards repository. It kept reviewing until two consecutive passes found nothing. That sounded safer than stopping after one review.

Instead, each repair gave the next reviewers more code to inspect. A 179-line change became 37,451 added lines over 39 passes. The workflow even changed live repository settings before I stopped it after roughly 46 hours. The full failure remains public.

I removed the open-ended loop and replaced it with one bounded review, repair, and verification cycle. In a later public comparison, that workflow found fifteen material issues across two changes while CodeRabbit found no valid findings. The comparison and every finding are available to inspect.

Fail closed is one useful property. It is not proof that the process is correct. Automated work also needs a fixed scope, hard stopping conditions, explicit ownership, and a person who accepts the remaining risk.

Confidence comes from evidence, not trust

I merge agent-written code when the repository can defend the change.

The gates do not remove responsibility. I still set product intent, choose the architecture, judge tradeoffs, and own what reaches production. The system makes the evidence visible before I make that decision.

The shared contract, sync lock, workflows, checks, and pull request history are public. A reader can inspect a rule, see how it reaches a consumer, and verify whether the required gate passed.

I do not expect every team to adopt my exact opinions. The useful idea is simpler. Separate generation from approval. Give important rules an executable form, check the repository as well as the code, and keep the final merge decision with a person.

Model confidence is cheap. Merge confidence has to be earned.

Inspect the system

Read the shared contract, sync engine, quality gates, and public failure reports.

Open the repository