Generated code should enter a repository through the same narrow door as human code.
That door is not “the agent said the task succeeded.” It is a deterministic sequence: inspect the patch, classify risky paths, run repository checks, require the right reviewer, and only then allow a merge.
This tutorial builds the first gate as a small POSIX shell script. It does not judge whether the implementation is correct. It rejects patches that are too large for the chosen review budget, touch sensitive paths without escalation, or contain whitespace and conflict-marker errors detected by Git.
Define what the gate owns
The gate answers three questions:
- Is the patch within a reviewable size budget?
- Does it touch a path that requires an explicit owner?
- Does the diff pass Git's structural checks?
It does not replace tests, type checks, security scanning, or human review. Keeping the scope small makes its result explainable.
Add the script
Save this as scripts/verify-patch.sh:
#!/bin/sh
set -eu
base_ref=${1:-HEAD^}
max_files=${MAX_FILES:-20}
max_lines=${MAX_LINES:-800}
files=$(git diff --name-only --diff-filter=ACMR "$base_ref"...HEAD)
file_count=$(printf '%s\n' "$files" | awk 'NF { count += 1 } END { print count + 0 }')
line_count=$(git diff --numstat "$base_ref"...HEAD | \
awk '{ added += $1; deleted += $2 } END { print added + deleted + 0 }')
if [ "$file_count" -gt "$max_files" ]; then
printf 'FAIL patch touches %s files (limit %s)\n' "$file_count" "$max_files" >&2
exit 1
fi
if [ "$line_count" -gt "$max_lines" ]; then
printf 'FAIL patch changes %s lines (limit %s)\n' "$line_count" "$max_lines" >&2
exit 1
fi
if printf '%s\n' "$files" | grep -Eq '(^|/)(\.env($|\.)|infra/|migrations/|CODEOWNERS$)'; then
printf 'FAIL sensitive path requires explicit review\n' >&2
printf '%s\n' "$files" >&2
exit 1
fi
git diff --check "$base_ref"...HEAD
printf 'PASS files=%s changed_lines=%s\n' "$file_count" "$line_count"
Make it executable:
chmod +x scripts/verify-patch.sh
Then compare the current branch with the target branch:
MAX_FILES=20 MAX_LINES=800 ./scripts/verify-patch.sh origin/main
The triple-dot diff means “changes on this branch since its merge base with the target.” That is usually the patch a pull request reviewer needs to inspect.
Test the gate in a disposable repository
The script should prove both acceptance and rejection. From an empty temporary directory:
git init
git config user.email test@example.com
git config user.name PatchGateTest
mkdir -p scripts src
cp /path/to/verify-patch.sh scripts/verify-patch.sh
printf 'export const answer = 41;\n' > src/value.js
git add . && git commit -m baseline
printf 'export const answer = 42;\n' > src/value.js
git add . && git commit -m safe-change
./scripts/verify-patch.sh HEAD^
Expected result:
PASS files=1 changed_lines=2
Now test a sensitive path:
mkdir -p infra
printf 'resource "example" {}\n' > infra/main.tf
git add . && git commit -m sensitive-change
./scripts/verify-patch.sh HEAD^
Expected result and exit status 1:
FAIL sensitive path requires explicit review
infra/main.tf
I ran these paths on macOS with Git 2.50.1 and the system POSIX shell. The safe patch passed; the infrastructure patch failed as intended.
Wire it into CI
For GitHub Actions, fetch enough history to identify the merge base and call the same repository script:
name: patch-policy
on: [pull_request]
jobs:
verify-patch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: ./scripts/verify-patch.sh "origin/${{ github.base_ref }}"
Pin third-party actions to a full commit SHA in a security-sensitive repository. The version tag above keeps the example readable but is a mutable reference.
After this patch-policy job, run the repository's normal formatter, type checker, tests, dependency review, secret scanning, and build. Use CODEOWNERS or an equivalent rule to route sensitive changes rather than merely blocking them forever.
Choose budgets from review behavior
The example limits are not universal safety numbers. Start with the distribution of recent pull-request sizes and the team's review capacity. A generated dependency lockfile may add thousands of legitimate lines; a one-line authorization change may be high risk.
Useful extensions include:
- separate limits for generated and hand-maintained files;
- deny binary additions unless explicitly approved;
- require tests when application code changes;
- require migration rollback notes when schema files change;
- identify newly executable files or permission changes;
- emit a machine-readable result for the pull-request UI.
The gate should tell the author what happened and how to escalate. A mysterious red check encourages bypasses.
Apply it to an AI development platform
The MonkeyCode repository describes AI tasks running in managed development environments. If a team uses MonkeyCode—or any coding agent—to create repository changes, this gate belongs in the target repository's CI. That keeps the merge policy independent from whichever model or task interface produced the patch.
This article does not test MonkeyCode's generated patches or claim that it lacks these controls. The verified artifact is the repository gate and its disposable Git test.
Disclosure: I contribute to the MonkeyCode project. The workflow connection is based on public product documentation; the patch-policy script is tool-independent.
Developers evaluating that workflow can join the MonkeyCode Discord. The team can discuss integration questions and current availability, eligibility, and limits for free model credits.
Generated code becomes ordinary code at the repository boundary. That is a feature: deterministic policy, project-owned tests, and accountable review remain useful even when the generator changes next month.
Top comments (0)