The Drift Log · Governing agents that write code
Resolving Build Intent Before AI Agents Commit Writes
27 October 2026 · 4 min read · 777 words · established

Intercept agent writes in-memory to validate AST syntax, license compliance, and export invariants before disk mutation occurs.
When an automated agent decides to edit a repository, the standard pattern gives its tool layer direct filesystem access. The agent emits a tool call, a local process writes the bytes to disk, and your test suite or linter runs after the fact. If the model introduces an invalid syntax node, imports a copyleft dependency into a proprietary codebase, or breaks an architectural boundary, the file tree is already contaminated.
Post-hoc CI pipelines and conventional code review automation are the wrong control layer for this. By the time a patch lands in git or triggers a review bot, runtime liabilities and dirty working trees have already entered the loop. Effective agent governance requires intercepting writes before they touch the disk.
The Gap Between Reasoning and File I/O
AI coding agents do not reason about your repository’s constraints the way an integrated toolchain does. A model generates tokens that represent diffs or whole files based on statistical likelihood. It does not parse AST invariants, track licensing boundaries across transitive dependencies, or verify interface contracts as part of token emission.
Giving an agent raw write_file or apply_patch primitives assumes the model's output is safe to stage. In practice, this creates three distinct failure modes:
- Licensing contamination: The agent imports or writes routines derived from incompatible licenses without triggering any alert until compliance scanning catches it downstream.
- Structural boundary violations: An agent mutates a private package or alters an unexported interface across a module boundary because it lacks explicit project boundary enforcement.
- Ghost mutations: An agent produces a broken AST that fails syntax parsing, leaving intermediate broken state on disk that corrupts the context window for subsequent tool calls.
The control point is not the model prompt. You cannot prompt your way to invariant safety. The control point is the interface between the agent deciding to write and the execution of that write: a build intent gate.
What Must Resolve Before Disk Mutation
A build intent gate isolates proposal from mutation. When an agent decides to modify code, it does not write to the file tree. Instead, it submits a structured write proposal to an interceptor.
{
"intent_id": "intent_01hx89...",
"target_path": "src/auth/session.ts",
"operation": "replace_range",
"declared_dependencies": ["@vendor/jwt-verify"],
"payload": "..."
}
The interceptor evaluates this proposal against deterministic validation layers before granting write authority:
- Syntax and AST validity: The proposed payload must parse into a valid AST against the project's target language version. If it produces a parse error, the gate rejects the intent immediately and returns the exact syntax error to the agent without modifying disk state.
- License resolution: Any newly declared imports or imported signatures are cross-referenced against your allowed licensing matrix. A copyleft license proposal in an internal proprietary service fails before the import statement is staged.
- Contract and export invariants: The intent is verified against exported symbol rules. If the proposal mutates an API contract without matching update intent on the corresponding consumers, it fails.
Only after these checks resolve to a clean state does the gate return a terminal verdict allowing the filesystem update. If the checks fail, the repository remains clean, and the agent receives actionable compiler-grade diagnostics rather than a generic stack trace.
How SHPBL Enforces Build Intent
At SHPBL, model-independent capability is delivered without letting agents bypass structural gates. Every write an agent performs against our software passes through a Build Intent gate first.
The proposal is registered, structural invariants and licensing rules are resolved in code, and a terminal state is returned before any change is applied. Evaluating and previewing an intent costs nothing; retrieving the verified artifact requires entitlement. Access is uniform across all four doors—our MCP server, the raw HTTP API, the typed TypeScript client (@shpbl/sdk), or the offline local edition.
A Workable Monday Posture
You do not need a complete architectural overhaul to start governing agent writes. Start by revoking direct write primitives from your agent configurations on Monday:
- Deprecate raw filesystem tools: Remove broad
write_fileorexecute_bashaccess from local agent environments. - Expose an intent endpoint: Replace raw write tools with a single
propose_file_writetool that accepts the proposed content in memory. - Run in-memory validation: In that tool's handler, parse the payload with your language parser (e.g.,
oxc,@babel/parser, ortree-sitter) and check licensing against an explicit allowlist before touching the disk. - Return typed rejections: If validation fails, return the exact AST error or license violation to the model. Do not alter the working directory.
Treating agent writes as unverified proposals rather than trusted mutations moves your governance from reactive debugging to explicit runtime enforcement.
Keep reading
Next in the log
- Separating Agent Decision Telemetry from Commit Authority
Decouple untrusted agent generation from git write authority by evaluating proposed diffs through a build intent gate before promotion.
- Verifying AST Invariants Before Agent PRs Enter Review
Block architectural violations from AI coding agents by enforcing AST-based module boundaries and sink constraints before PR creation.
- Policy-Driven Quotas for Agent-Generated Write Intent
Token metering tracks text volume rather than architectural impact. Gating registered write intents protects finite engineering review capacity.
The Strategic Master Library · written and reviewed under the house's own epistemic rules: nothing claimed that we cannot show.