Skip to content

The Drift Log · Governing agents that write code

Separating Agent Proposals from Repository Mutation Gates

9 September 2026 · 4 min read · 789 words · established

A crystal shard held at a red-lit gateway in a black wall

Prevent agents from polluting git history by routing proposed diffs through an ephemeral validation gate before granting write access.

Most setups for AI coding agents give the model direct write access to a local checkout or a remote git branch. The agent reads a prompt, alters three files, runs a formatter, and commits. When the code contains a hallucinated package import, an invalid schema change, or an unresolved license mismatch, that error is already recorded in the git tree.

CI might catch a compile failure three minutes later, but CI was built for human review cycles, not high-frequency machine writes. Treating a git branch as an agent's scratchpad creates noisy commit histories, wastes compute, and pushes triage onto downstream maintainers.

Effective agent governance requires pulling the boundary back: an agent should propose a change, but a dedicated build gate must validate that proposal before the repository mutates.

The failure mode of direct mutation

When human developers write code, they run continuous mental assertions against the project’s conventions: package boundaries, private API rules, typing constraints, and licensing obligations.

AI coding agents do not possess an internal model of these local invariants unless explicitly forced to run them. When an agent has direct file-system access, its intermediate failures become repository state.

Consider a typical agent workflow tasked with updating an internal database query:

  1. The agent writes a new migration file directly into db/migrations/.
  2. It introduces a foreign key that violates a tenant-isolation invariant.
  3. It creates a commit: git commit -m "add tenant foreign key".
  4. The hook fails, or worse, the remote CI fails after pushing.
  5. The agent is prompted with the error output, attempts a corrective commit, and creates an orphaned state or dirty rollback in the branch.

This cycle confuses code review automation and breaks developer trust. The agent is treating the repository itself as its working memory.

[Agent Context] ──(Direct Write)──> [Git Working Tree] ──> [CI Failure / Dirty History]

Isolating proposals into an evaluation phase

The fix is architectural. Separate the act of code drafting from the act of repository mutation. The agent should emit a structured proposal (a patch, a manifest, or an explicit build intent) into an isolated staging layer rather than writing to disk.

[Agent Draft] ──> [Structured Proposal] ──> [Build Gate Validation] ──(Pass)──> [Repository Write]
                                                    │
                                                 (Reject)
                                                    │
                                                    └──> [Machine-Readable Error to Agent]

In this model, the proposal is an ephemeral payload. The gate evaluates the payload against explicit mechanical checks:

  • Syntactic and structural integrity: Does the proposed patch parse cleanly without altering generated locks or sealed paths?
  • Schema and interface contracts: Do the proposed changes satisfy existing interface boundaries before any compilation step? (See evaluating agent code proposals before commits happen).
  • Dependency and licensing invariants: Does the change introduce external packages that violate project policy?

If the proposal fails, the gate rejects it immediately and returns a structured, terminal diagnostic payload back to the agent. No files change on disk. No git commit hash is generated. The agent can adjust its approach using the diagnostic feedback without having left broken artifacts across your working tree.

This pattern is the core operational principle behind governing code agents at the build intent gate: mutations are only granted to code that has already met the contract.

What a validation gate requires

To build a reliable boundary between proposals and writes, your gate needs three properties:

  1. Model-independent execution: The evaluation engine must run standard static analysis, type checks, and policy evaluations using deterministic linters or test harnesses—never another LLM prompt making a subjective judgment call.
  2. Stateless evaluation: The verification harness (such as our certification harness) must execute against the proposal in memory or within an isolated temporary directory, discarding the context immediately after returning the verdict.
  3. Structured error payloads: When a proposal is rejected, the output returned to the agent must be machine-actionable. Sending back a 200-line unstructured stderr dump forces the agent to guess what broke; sending back { "invariant": "SEALED_PATH_MUTATION", "file": "src/core/auth.ts" } gives it the exact constraint to satisfy on the next iteration.

What to build first

If your team is deploying coding agents locally or in CI pipelines, start by revoking the agent's direct git commit and git push permissions on working branches.

Wrap the agent’s write tool in a simple staging proxy:

  1. Configure the agent tool to output standard unified diffs or JSON payloads instead of applying file edits.
  2. Pipe that payload into an ephemeral validation script that runs your linter, AST parser, and license checks against the proposed diff.
  3. If the script exits 0, apply the patch to the working tree.
  4. If it exits non-zero, capture the exit code and failing rules, abort the write, and pass the structured failure back into the agent loop.

By isolating the draft from the commit, you eliminate broken intermediate states, keep branch history clean, and turn code governance into an automated gate rather than a post-facto triage problem.

This post supports the longer argument in Governing Code Agents at the Build Intent Gate.

Keep reading

Next in the log

The Strategic Master Library · written and reviewed under the house's own epistemic rules: nothing claimed that we cannot show.