The Drift Log · Governing agents that write code
Build‑Intent Review Bot for Agent‑Generated Pull Requests
23 October 2026 · 3 min read · 599 words · established

A lightweight GitHub Action can enforce the Build‑Intent gate on agent‑generated pull requests, ensuring licence and invariant checks before any merge.
The failure that shows up in practice
Agents that generate pull requests often bypass the Build‑Intent gate. The code lands before any licence or invariant check runs. When the merge succeeds, the repository can contain files that violate internal policies, break downstream builds, or introduce licence incompatibilities. The damage is discovered only after the fact, when a human must untangle the change set and roll back.
What a correct gate looks like
A Build‑Intent proposal must be recorded, validated, and approved before any write operation is permitted. The gate enforces three invariants:
- Licence compliance – the artefact’s licence matches the project’s policy.
- Invariant satisfaction – required file‑structure, naming, or configuration rules hold.
- Human sign‑off – a reviewer explicitly authorises the write.
When an agent creates a PR, the gate should reject the merge until the proposal passes these checks. The gate is the single control point between “agent decides to write” and “write happens”.
Bot architecture that enforces the gate
A lightweight review bot can be built as a GitHub Action (or equivalent CI hook). The bot runs on every PR event, extracts the agent‑generated diff, and asks the Build‑Intent service whether the proposal is admissible.
Step‑by‑step flow
- Detect agent‑origin PR – agents add a known marker in the PR title or a custom label, e.g.
agent-generated. - Fetch the diff – use the GitHub API to retrieve the changed files.
- Submit a Build‑Intent query – POST the diff to the HTTP API (
/api-access) that validates licence and invariants. The service returnsCERTIFIED,PROVISIONAL,INCONCLUSIVE, orFAILED. - Interpret the verdict –
CERTIFIED– allow the PR to proceed to human review.PROVISIONAL– add a warning comment, require a reviewer to confirm the provisional status.INCONCLUSIVE– block the merge and raise a ticket for a deeper investigation.FAILED– fail the check outright; the PR cannot be merged.
- Post a status check – the bot writes a GitHub check result with the verdict and a short explanation.
- Require approval – configure branch protection rules so that the check must be
successbefore a merge is allowed.
Minimal example
name: Build‑Intent Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout PR
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Detect agent PR
id: marker
run: |
if [[ "${{ github.event.pull_request.title }}" =~ \[agent\] ]]; then
echo "agent=true" >> $GITHUB_OUTPUT
else
echo "agent=false" >> $GITHUB_OUTPUT
fi
- name: Build‑Intent check
if: steps.marker.outputs.agent == 'true'
env:
API_TOKEN: ${{ secrets.BUILD_INTENT_TOKEN }}
run: |
diff=$(git diff origin/${{ github.base_ref }}...${{ github.head_ref }})
resp=$(curl -s -X POST https://build-intent.example.com/validate \
-H "Authorization: Bearer $API_TOKEN" \
-d "{\"diff\": \"$diff\"}")
verdict=$(echo "$resp" | jq -r .verdict)
echo "verdict=$verdict" >> $GITHUB_OUTPUT
- name: Set check result
if: steps.marker.outputs.agent == 'true'
uses: actions/github-script@v6
with:
script: |
const verdict = '${{ steps.validate.outputs.verdict }}';
const conclusion = verdict === 'CERTIFIED' ? 'success' :
verdict === 'PROVISIONAL' ? 'neutral' :
'failure';
core.setOutput('conclusion', conclusion);
core.setOutput('summary', `Build‑Intent verdict: ${verdict}`);
The script is deliberately short; production bots should add logging, rate‑limiting, and retry logic. The key point is that the bot never merges without a positive verdict from the Build‑Intent service.
Integrating with the broader governance framework
The gate described here is the same mechanism referenced in the pillar post on governing code agents at the Build‑Intent gate. By reusing the same API, the bot inherits the library’s licence and invariant catalogues, and it benefits from the same certification harness that records CERTIFIED, PROVISIONAL, INCONCLUSIVE, or FAILED outcomes (see the harness for details).
Because the Build‑Intent service is model‑independent, the bot’s decision is repeatable and auditable. The PR comment includes a link to the exact proposal that was evaluated, providing a traceable audit trail without any AI‑generated artefacts.
What to do on Monday
- Add the
agent-generatedlabel to the agents you control. - Create a new GitHub Action file (e.g.
.github/workflows/build-intent.yml) with the snippet above. - Store the Build‑Intent API token in the repository’s secret store (
BUILD_INTENT_TOKEN). - Enable branch protection so the “Build‑Intent Review” check must pass before merging.
After these four steps, any PR that carries the agent label will be forced through the Build‑Intent gate, guaranteeing that licence and invariant checks run before a human ever sees the code. This simple bot turns a risky open‑write surface into a controlled, auditable workflow.
Keep reading
Next in the log
- 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.
- Immutable Log of Build‑Intent Write Proposals for Auditable Post‑Mortem Review
An immutable, hash‑chained log of Build‑Intent proposals gives a verifiable audit trail for post‑mortem review.
The Strategic Master Library · written and reviewed under the house's own epistemic rules: nothing claimed that we cannot show.