Agent-generated PRs are not just bigger; they are a different species. A coding agent can produce hundreds of coherent-looking changes in one commit, but coherence is not correctness. Treat every diff from an agent as unverified input. The only way to keep you sane is to split the diff into three buckets: trust, revert, and prove.
The framework below takes about 15 minutes per PR and needs nothing more than git, a text editor, and an isolated sandbox. It won't catch every subtle bug, but it will stop the dangerous ones from reaching main.
Why agents need a stricter protocol
Human developers leave context. They know the history of a function, the reason behind a weird sorting algorithm, and the legacy constraint nobody wrote down. Agents do not. They generate code that looks idiomatic because it was trained on millions of similar lines, but they also:
- call APIs that don't exist
- copy Stack Overflow one-liners without the surrounding error handling
- swallow exceptions to make tests pass
- add tests that pass for the wrong reason
The result: a PR with a clean summary, a green CI run, and a hidden time bomb in the auth/ folder.
So stop reviewing agent PRs line-by-line. Bucket the hunks, then act on each bucket with a different policy.
Bucket 1: Trust (only mechanical changes)
Mechanical changes are the only safe default to trust without deep investigation. They include:
- variable and function renames that leave interfaces identical
- formatting changes (indentation, import ordering)
- moving code blocks without modifying logic
- regenerated lockfiles or config files that match repo conventions
To spot them quickly, use diff options that detach movements and whitespace from content:
git diff -M -w master...HEAD
If the output shows only rename or move markers, and you can visually confirm the semantics didn't change, you can approve those hunks without running extra tests.
Bucket 2: Revert by default
Some changes are so risky that they should be reverted the moment you see them, no matter what the agent claims. Put these into the revert bucket:
- any touch to authentication, encryption, payment logic
- changes to code performing side effects: network calls, file writes, environment mutation, database migrations
- exception handling that now catches
Exceptionor uses bareexcept: - dynamic execution with
eval,exec,os.system, orsubprocessin a context that didn't have it before - any line that removes a
checkor boundary validation "to improve performance"
This list is deliberately strict. Agent-generated code in these areas has a high probability of introducing security or correctness regressions.
For each offending commit, revert it, file an issue, and let a human write a minimal fix with proper tests. Do not attempt to fix it inside the same massive PR.
Bucket 3: Prove with tests
Everything else falls into the prove bucket: logic changes, new features, refactoring that alters behavior, or any change with existing test coverage. For these, the requirement is simple: you must run the tests and you must add a test that would fail against the original code.
The agent's own test run means nothing. It may have used a different environment, or the test may pass for the wrong reason.
A reliable proof loop looks like this:
- Check out the agent's branch.
- Run the full test suite in a clean environment.
- Revert the agent's logic change but keep the new test.
- Run the test again. It should fail.
- Apply the agent's change again. It should pass.
If the test passes both before and after the logic change, it is a tautology—don't count it as proof.
A decision table for the moment of review
| Bucket | Example | Action |
|---|---|---|
| Trust | Renamed tmp to temp in a function body |
Approve after visual spot-check |
| Revert | Added eval() for "dynamic config" |
Revert the commit, create an issue |
| Prove | New validation logic with a claimed edge-case fix | Require a test that fails against old code |
When in doubt, move the hunk down a bucket. It costs far more to debug a production incident than to ask for another test.
Catching the dangerous ones with a script
Reading every added line is slow. Instead, scan the diff for high-risk patterns. Here's a small Python script that flags the most common red flags:
import re, subprocess
def get_added_lines():
diff = subprocess.check_output(
["git", "diff", "master...HEAD"], text=True
)
return [line[1:].strip() for line in diff.splitlines()
if line.startswith("+") and not line.startswith("+++")]
RISKY_PATTERNS = [
r"\beval\s*\(",
r"\bexec\s*\(",
r"\bexcept\s*:",
r"\bsubprocess\s*\.",
r"\bremove\s*\(.*,\s*True\s*\)",
r"\bdelete\s+from\s+",
r"(password|secret)\s*=",
]
for line in get_added_lines():
for pattern in RISKY_PATTERNS:
if re.search(pattern, line):
print(f"RISK: {line}")
break
print("Scan complete.")
Run it inside the booted branch. If it prints anything, those lines belong in the revert bucket.
Using a free sandbox to run the proof loop
To actually execute Bucket 3 you need an isolated environment. This is where MonkeyCode's free server option is useful. It gives you a throwaway Linux sandbox where you can clone the branch, run the test suite, and mutate the code without polluting your local machine or burning CI minutes.
Inside that sandbox, the workflow becomes:
git clone <repo> && cd <repo>
git checkout <agent-branch>
# run the full suite
pytest -q
# revert the agent's logic manually, then rerun a specific test
pytest tests/test_new_feature.py -q
The free model access, meanwhile, is enough to ask a second model for a list of failure scenarios against the proposed change. Prompt it like this:
Here is the diff. Do not tell me if it's correct. List every possible edge case that could break this code.
That gives you a checklist to turn into test cases, not a rubber stamp.
(Disclosure: This article was prepared as part of MonkeyCode's product outreach.)
Limitations and who should skip this
The bucket framework is a filter, not a proof of correctness. It misses:
- subtle arithmetic or off-by-one errors that don't match risky patterns
- race conditions hidden behind multithreading
- business logic errors that are syntactically perfect but semantically wrong
For those, only deep human review or property-based tests help. Also, if you're building a one-off script or a personal project with no users and no production impact, you can skip most of this—just glance at the diff and merge. But as soon as there's a login page, a database, or an external customer, the protocol becomes mandatory.
The 15-minute routine
- Run the pattern scanner on the diff.
- Revert every commit that hits the red-flag list.
- For everything else, spin up a sandbox and run the existing test suite.
- Write one new test that exercises the changed branch and verify it fails against the old code.
That's it. The next time an agent opens a PR, don't read it start-to-finish. Bucket it, revert what's risky, and let a test prove the rest. Your future self—and your users—will thank you.
Top comments (0)