
All How to Stop Coding Agents from Merging Bad Code
November 2, 202610 min read
Somewhere in the last two years a lot of developers stopped reviewing code. For some teams, trading a real review for a faster merge is acceptable. If you ship an internal dashboard, a bad merge costs you a couple of hours.
But if the software you develop stores personal data, moves money, runs a medical device, or controls a commercial jet, the math changes. And even if none of that applies to you, you presumably want your colleagues to understand the codebase.
This is a guide to making sure you and your team are not merging bad code into main.
It covers the decisions to make before you let Claude Code, Codex, Cursor, or whatever coding agent you use open pull requests, the controls that enforce those decisions, and how to test that the controls hold. The decisions take an afternoon, and they are the difference between an agent you supervise and an agent you hope won't make mistakes.

Decide Which Tools You Trust to Block a Merge
Before you decide which checks are allowed to block a merge, you have to decide which tools you trust to make that call. There are two broad types of code analysis tools:
- Deterministic tools can block: linters and static analyzers, secret and dependency scanners, type checkers, test runners and coverage reporters, plus the platforms that run or aggregate them, like Codacy, SonarQube, Semgrep or Snyk. Run any of them twice on the same commit and you get the same result twice.
- Probabilistic tools can only advise: AI reviewers like CodeRabbit, Greptile, Copilot code review, Claude Code's own /review, Codex code review or Cursor Bugbot. Useful, but the same diff can get a different set of comments on different runs.
A check that can pass on one run and fail on the next cannot be a required check, so only tools from the first group should hold one. The second group is still worth running, as long as its comments go to the agent or a reviewer as advice.
Decide Which Checks Block a Merge and Which Only Warn
Even a tool you trust should not block a merge on everything it finds. Here is a starting policy for which checks block and which only warn:
Check | Block or warn |
| New critical or high security finding (SAST, secrets, vulnerable dependency) | Block |
| New issue at or above your agreed severity from static analysis | Block |
| Tests fail | Block |
| Diff coverage below threshold | Block |
| Duplication or complexity over threshold | Warn |
| AI reviewer comments (CodeRabbit, Copilot, Claude, Codex) | Warn |
Two habits make this stick:
- Gate on new issues the change introduces rather than on the repo's total, or every PR against a legacy codebase is red on arrival and everyone learns to ignore red.
- Make the blocking checks required in branch protection, with no admin bypass for the bot account. If the agent can push to main around the gate, you do not have a gate.
On GitHub, that means a branch protection rule or ruleset on main that requires a pull request before merging, lists every blocking check as a required status check, and leaves the bot account off the bypass list. GitLab and Bitbucket have equivalent settings.
The warn-only checks still run and post their results, but they stay off the required list. The checks on that required list are, together, the gate.
See more
Data Pipeline Architecture: How to Build Reliable Flows from Scraping to Business Intelligence
Read nowDecide Which Checks Run Pre-Commit and Which Wait for CI
By default every check above runs in CI, which means the agent finds out it failed after it pushed, by which point it is three tasks further on. Humans pay the same cost: about 23 minutes to get back into an interrupted task.
So split the checks by where they run:
- Anything fast, deterministic and scoped to the changed files runs on the developer's machine before the commit exists: formatting, linting, secrets detection, static analysis on the diff, dependency checks. A hardcoded API key gets caught in the same sitting the code was written.
- Anything that needs the whole repo or an environment stays in CI: the full test suite, full-repo analysis, builds, compliance records, deploy gates.
CI stays the gate of record; the pre-commit run contains the same rules applied early so the gate passes on the first try. For an agent, the local run can be a git pre-commit hook, a line in its instructions file telling it to scan the diff before every commit, or both.
A hook is harder to forget, but git commit --no-verify skips it, which is why the same rules still have to be required in CI.
Decide What the Coding Agent May Change Without Asking
An agent with repo write access will, given enough time, touch everything. Some of that is fine. Some of it should require a person to say yes first, and you want that list written down before the agent starts working.
A workable default for most teams:
- Change freely: application code inside the feature it was asked to work on, tests for that code, documentation, formatting.
- Change, but a human reviews the specific file: anything in the sensitive paths: database migrations, anything under auth/, payments/ or whatever your equivalent is, public API contracts, dependency manifests (package.json, requirements.txt, go.mod).
- Never change without an explicit instruction: CI configuration, branch protection, the static analysis configuration itself (.codacy.yml, .eslintrc, sonar-project.properties, whatever holds your rules), secrets and environment files, the agent's own instructions (CLAUDE.md, AGENTS.md, .cursorrules).
The last group needs particular attention. When a check fails, changing its configuration may be easier than fixing the code. If you tell an agent to “make the PR green,” it may take that shortcut: the checks pass, but the underlying problem remains.
Add the list to the agent’s instructions file, then enforce the restrictions outside the agent. This keeps them in place even if the agent ignores its instructions.
Use a CODEOWNERS file to assign the second and third groups to named owners, and require code owner approval through branch protection. A PR that changes payments/ or .eslintrc then needs approval from the relevant owner before it can merge.
Protect CODEOWNERS itself, too. Otherwise, the agent could change the ownership rules to bypass review.
Decide How the Agent Handles False Positives and Other Exceptions
Every static analysis tool produces false positives, and an agent hitting a false positive has three options: fix code that was not broken, suppress the finding, or complain.
Left to itself it will often pick an inline suppression comment. Do that a few hundred times and your codebase is wallpapered in // eslint-disable-next-line and # nosec and the tool is no longer telling you anything. The rule that works: a false positive gets handled in the tool, never in the code.
If a pattern fires wrongly in one place, ignore that one finding in the tool, with a written reason attached to it, so a human can see it later. If it fires wrongly in ten places, the pattern is wrong for your codebase and you disable or retune it at the rule level, once, in the configuration the agent is not allowed to touch.
The agent is allowed to do the first. The second only happens when a person says so.
The rarer exception is a fix that has to ship while a required check is red.
Give that bypass to named people, never to the bot account, and make every use of it leave a record: which check was skipped, why, and a ticket to clear it afterwards. If the bypass gets used more than now and then, the check is set wrong and needs retuning, not working around.
Decide Where a Human Still Signs Off on Agent-Written Code
When agents generate code faster than engineers can review it, asking people to inspect every line can turn careful review into skimming. Focus engineers’ attention where mistakes would cost the most:
- Did it touch anything on the sensitive-paths list?
- Did any finding get ignored, and does the reason hold up?
- Is this a design we want to live with?
These questions help engineers spend their review time on decisions that need their judgement.
Run the Same Rules on the Agent’s Machine and in CI
Local checks help the agent catch problems early. Required pull request checks prevent unresolved issues from reaching the main branch. Both should follow the same rules, even when CI runs more extensive checks.
Before the Commit
The agent scans staged files to catch issues before committing. If the scan finds a problem, it returns a failing result, prompting the hook or the agent to stop the commit until the issue is fixed. Where supported, the scan runs entirely on the machine and uses default rules if the repository has no central configuration.
Before the Pull Request
The agent scans all changes on the branch since it diverged from main, including earlier commits. This broader check catches issues that may have slipped through when a local hook was skipped.
At the Pull Request
CI runs the checks that are too broad or costly to run locally: full-repository analysis, the complete test suite, and coverage checks for changed lines. Upload coverage from the feature branch and main to establish a baseline for comparison.
Some analyzers run only in CI, so this stage may uncover findings that the local scan missed.
Keep One Ruleset in Both Places
Use the same shared rules for local scans and the CI gate. If the team adjusts a rule locally, require human approval before updating the central configuration.
Keeping these rules aligned makes local results more reliable. A local pass should indicate that the change meets the shared rules, while CI verifies it through additional checks.
Close the Feedback Loop
When a pull request fails the gate, the agent reads the findings in a machine-readable format and reviews them alongside the diff and coverage gaps. It fixes valid issues and adds missing tests.
For false positives, the agent records a dismissal and its reason in the analysis tool rather than adding a suppression comment to the code. It then reruns the analysis and waits for the result before handing the pull request to a reviewer.
Give Reviewers a Clear Decision Record
The reviewer receives a pull request that has passed both local and CI checks. Each finding has either a corresponding code change or a recorded reason for dismissal that the reviewer can assess and challenge.
Test That the Gate Blocks a Merge
Verify that the gate works before the agent opens its first real pull request. Create a test PR with deliberate problems:
- A fake API key that matches a format your secret scanner detects.
- A failing test.
- A new, untested function that breaches your coverage threshold.
- A one-line change to a protected lint configuration file.
Skip the pre-commit hook when pushing these changes so you test CI independently of local checks.
Confirm that each problem triggers the expected response. The secret scan, test run, and coverage check should fail and block merging. The lint configuration change should require approval from its code owner.
Also, use the bot account to attempt both a merge of the failing PR and a direct push to main. Both attempts should be rejected. This confirms that the restrictions apply to the agent’s account, too.
Pair Coding Agents with Consistent Quality Checks
Obvious mistakes are easy to spot in a review. Code that looks correct is harder to question, especially when an agent produces a convincing explanation alongside it.
Deterministic gates check that code against defined rules, regardless of how convincing it looks. Tests, security scans, and coverage requirements give engineers evidence to guide their review. They cannot catch every flaw, but they help teams use coding agents without relying on appearances alone.
How SapientPro Helps You Integrate AI into Development
SapientPro helps businesses connect AI agents to their systems and workflows.
For development teams, this means defining what agents can change, how their work gets checked, and which decisions require an engineer’s approval. We can help you:
- Connect coding agents to your repositories, development tools, and CI workflows;
- Set clear permissions for sensitive files, configuration changes, and merge access;
- Automate quality checks with tests, code analysis, and coverage requirements;
- Build review workflows that let engineers assess changes, investigate findings, and approve exceptions.
Planning to introduce coding agents into your team?
Contact SapientPro to discuss your development workflow, identify a practical starting point, and define the checks you need before rollout.
Integrate Coding Agents with Confidence
Work with SapientPro to connect coding agents, automate checks, and define approval workflows.




