Skip to content

The Drift Log · Governing agents that write code

Metering Agent Proposals with Dry Run Build Intent

24 September 2026 · 3 min read · 645 words · established

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

Decouple agent planning from repository mutation by enforcing dry-run build intent gates before issuing write authority.

The Cost of Blind Mutation

When autonomous AI coding agents are given unrestricted write tools, they behave predictably: they read a prompt, modify files, and immediately open a pull request or push a branch.

When multiple agents run across a codebase, this creates churn. An agent attempts to solve a task by pulling an incompatible dependency, generating code that violates strict type contracts, or using a library whose license conflicts with internal policy. The pull request opens. The CI runner spins up. Three minutes later, the build fails on a static analysis or license compliance check.

By the time the runner rejects the code, the damage is already done:

  • CI runner minutes and API rate limits are spent.
  • Git history and pull request queues are cluttered with noise.
  • Context is wasted when the agent must inspect a full CI failure log rather than a structured error.

Treating CI as the first line of defense for agent output is an expensive posture. CI is designed to validate human pull requests before merge, not to act as a runtime sandbox for agent trial and error. To establish effective agent governance, the validation boundary must sit between the agent's decision to write and the write itself.

Decoupling Proposal from Mutation

The standard tool definition for an agent exposes mutations directly: write_file, git_commit, or create_pull_request. This couples planning to state modification.

A safer posture separates the intent from the mutation. Instead of writing directly to the tree, the agent must register a proposal with a build intent gate. The gate executes a zero-cost dry run against the proposed change before any file system write or Git operation occurs.

{
  "tool": "register_build_intent",
  "parameters": {
    "target_path": "packages/auth/token.ts",
    "proposed_patch": "...",
    "dependencies": { "jose": "^5.2.0" },
    "dry_run": true
  }
}

When dry_run is true, the gate resolves three checks without mutating repository state:

  1. Invariant validation: Does the patch satisfy local schema and contract requirements?
  2. Policy and licensing resolution: Are the proposed dependencies permitted under repository policy?
  3. Workspace consistency: Does the patch apply cleanly against the current HEAD without structural conflicts?

If any check fails, the gate returns a structured diagnostic directly to the agent in its current turn. The agent corrects the error immediately—without creating orphaned branches, polluting Git logs, or consuming write permissions. We explore this boundary further in our guide to separating agent proposals from repository mutation gates.

The Build Intent Gate in Practice

At SHPBL, every interaction with our library follows this exact sequence. Whether an agent connects through our MCP server, calls the HTTP API, or uses the typed @shpbl/sdk, all write operations must pass the build intent gate first.

The gate evaluates the proposal in code, validates licensing and structural invariants, and returns a terminal verdict. The dry run preview costs nothing and commits no state. Only when the proposal passes verification and the consumer requests the concrete, model-independent artifact does entitlement apply. This ensures that agent exploration never burns budget or repository integrity on invalid mutations.

Implementing Dry Run Gates on Monday

You do not need to overhaul your entire agent orchestration layer to stop blind mutation churn. You can implement this boundary in your current tool definitions:

  1. Remove direct write tools. Revoke direct access to create_pull_request and file-mutation tools from the agent's default prompt context.
  2. Introduce a two-phase tool contract. Replace mutation tools with a pair: propose_build_intent(dry_run: true) and execute_build_intent(intent_id: string).
  3. Issue single-use intent tokens. Have the dry-run gate return an ephemeral intent_id only when invariant and license checks pass cleanly.
  4. Require the token for writes. Make execute_build_intent accept only valid, unexpired intent tokens that have passed the dry run.

If an agent cannot pass static invariants and policy checks during preview, it should never be granted the authority to touch your version control.

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.