A risk-tiering framework for AI-written code, from GitLab's 2017 data loss to Knight Capital's $460M glitch, enforced as a CI gate, not a policy.
Decide before any pull request exists which categories of change must stop for a person, then build that decision into something the pipeline enforces rather than something a reviewer has to remember. That is the fix, not asking the agent to be more careful with sensitive code. An AI agent can open a pull request that adds a health-check endpoint, and it can open one that changes how a refund gets calculated. Both land in the same queue, in the same PR format, and get the same three-minute glance if nothing has told the pipeline they are different.
Risk lives in the file path, not the diff size
Diff size is a bad proxy for risk. A three-line change to a token-verification function can be worse than a three-hundred-line refactor of a reporting script, and an agent that has learned to keep pull requests small will happily produce a small, dangerous diff. What actually predicts risk is where a change lands and what it can do if it is wrong. A tier built from file paths and change type is something a pipeline can check automatically, long before anyone reads a line of the diff itself.
The low-risk tier: safe to automate end to end
Some categories of change are low-risk almost by definition, because a mistake there is cheap to spot and cheap to undo. These are reasonable candidates for full automation through merge and deploy, provided the tests covering them are real and green:
- Documentation, comments, and README updates
- New tests, or fixes to existing tests, that do not touch production logic
- Internal developer tooling with no external users
- Refactors confined to files that already carry full test coverage
- Formatting, linting fixes, and patch-level dependency bumps with no API change
For this tier, the gate can stay simple: the full test suite passes, no file outside the declared low-risk patterns is touched, and no new external dependency is introduced. If all three hold, the change can merge and deploy without a human step. That is where automation earns its keep: an agent moving at machine speed on changes where a mistake costs an hour, not a customer's money or their data.
The high-risk tier: where a person has to sign off
The other tier is not defined by how hard the code is to write. It is defined by blast radius and reversibility: how much can go wrong, how fast, and how hard it is to undo once it has shipped. An agent can write a syntactically clean database migration or a tidy-looking IAM policy change and still be wrong in a way no test suite catches, because the failure only shows up under real production data, live traffic, or an access pattern nobody wrote a test for.
- Authentication and authorization logic
- Payment, billing, and refund handling
- Infrastructure-as-code: Terraform, Kubernetes manifests, IAM and network policies
- Database migrations and schema changes
- Any code path that reads, writes, or exports personally identifiable data
- Cryptographic code and key or secret handling
These failure modes are documented, not abstractions, and they predate AI agents by close to a decade. In January 2017, a GitLab engineer meant to wipe a lagging database replica and instead ran the delete command against the primary, removing roughly 300GB of production data, including projects, comments, and issues. The company's own postmortem is unusually candid about how a routine database operation turned into hours of data loss and a public outage. A migration or schema change written by an agent carries the same risk if nothing outside the agent checks it before it runs.
Sources: GitLab: Postmortem of Database Outage
Knight Capital lost more than $460 million in under an hour in August 2012 after a software deployment reached seven of its eight production servers, leaving a dormant trading feature active on the eighth; it began trading on its own once markets opened. The SEC's 2013 settlement order against the firm specifically cited a lack of adequate controls over code deployment and testing as a violation of the market access rule. Neither incident involved an AI agent, but both show what a fast-moving one can reproduce at machine speed if nothing outside it inspects a database or infrastructure change before it goes live.
Sources: SEC: Knight Capital Enforcement Action
A written review policy says what should happen. A merge gate decides what can happen.
A policy is advice. A gate is enforcement.
Most teams already have something that sounds like a control: a line in a contributing guide about getting a security review before touching authentication, a norm in a chat channel, a step in an onboarding document. None of it survives contact with a deadline. A rushed engineer skips the step because nobody is watching. An agent instructed to follow the review policy has no way to confirm that it did, because nothing checks. The rule itself is not wrong. A rule with no enforcement point is a suggestion, and suggestions get skipped exactly when the stakes are highest.
Building the mechanical gate
Turning a risk tier into an actual gate means making the pipeline refuse to merge on its own, not asking a person to remember a rule. Most of the pieces already exist, and they compose into something a rushed engineer or an agent cannot route around.
The first layer is ownership mapping. A CODEOWNERS file assigns specific people or teams to specific paths, so a change under an authentication or billing directory automatically requests review from whoever is responsible for that code, without anyone having to remember to tag them. On its own this is only routing. It becomes a gate once branch protection is set to require an approving review from a code owner before the pull request can merge.
Sources: GitHub: About Code Owners
GitHub extended this in February 2026, when its required reviewer rule for repository rulesets reached general availability. It lets an organization require a specific team's approval whenever a matching path changes, independent of who owns the file on paper, and exclude paths with gitignore-style negation patterns. GitHub's own example is direct: require the data platform team's review whenever a SQL file changes, and require two approvals from the security team whenever anything under an authentication path changes. That is a risk tier, expressed as a rule the platform itself will not let a merge bypass.
Sources: GitHub Changelog: Required Reviewer Rule GA
Teams that needed this logic before GitHub shipped it built it themselves. Palantir's open-source policy-bot runs as a GitHub App and evaluates rules such as requiring two approvals from a security team whenever a file under a config directory changes, enforced as a required status check independent of CODEOWNERS. It has been running in production at scale for years, which says something about how long this gap existed before the platform caught up.
Sources: Palantir policy-bot
The last piece is a required status check that inspects the changed file list on every pull request, classifies it against the risk-tier patterns, and fails if a high-risk path lacks an approval from the designated group, whether the author is a person or an agent. Branch protection makes that check mandatory, so merging is blocked at the platform level rather than at the level of someone's good judgment. An emergency override can still exist, but it should require a named person to invoke it and leave a log entry, not a silent bypass.
The risk-tier configuration itself deserves the same treatment. If the file defining which paths count as high-risk lives in the repository as plain, unprotected text, anyone, including an agent instructed to get a change merged, can quietly narrow it to exclude the very path it is about to touch. Changes to that configuration file should route through the same mandatory review, ideally from a security or platform lead rather than the team whose scope it constrains, so loosening the gate is itself a high-risk change subject to the gate.
Logging closes the loop. Every high-risk approval and every emergency override should record who approved it, which tier triggered the requirement, and how long the review took. That record becomes the evidence base for revising the tiers themselves: a category of change that keeps clearing review with no findings is a candidate to move down a tier, and a category outside the current list that keeps causing incidents is a candidate to move onto it.
Comparing the enforcement options
Laid side by side, the difference between advice and enforcement is not subtle:
| Gate Mechanism | Blocks Merge On Its Own | Survives A Rushed Skip | Applies To Agent PRs |
|---|---|---|---|
| Written policy in a wiki or contributing guide | No | No | No |
| PR template checklist | No | No | Partial |
| CODEOWNERS with branch protection | Yes | Yes | Yes |
| Path-based required status check in CI | Yes | Yes | Yes |
When one change touches both tiers
A pull request rarely respects tier boundaries cleanly. An agent fixing a bug might touch a test file and a payment handler in the same commit. The simplest rule is also the safest one: classify a pull request by its highest-risk file, not its average. If any file in the diff matches a high-risk pattern, the whole change requires sign-off, even if most of the diff is a harmless test update. Agents that learn this quickly start splitting unrelated changes into separate pull requests on their own, which is a good habit regardless of who is reviewing.
Tooling built for agent-authored code is starting to treat the merge decision itself as a mechanical construct instead of a checklist. TLM Forge, for one, blocks a merge until every critical finding from its adversarial review is resolved: a threat-modeler agent examines the design before code is written, a separate red-team agent attacks the diff afterward, and the ship or no-ship call is a score rather than a reviewer's mood. That does not replace a path-based human sign-off on a payments change; a risk-tiered gate and an adversarial review gate answer different questions. But it closes a real gap, the AI-authored code that would otherwise reach production without any independent check on it at all, low-risk or not.
Frequently asked questions
01What kinds of changes should always require human approval when an AI agent writes them?
Authentication and authorization code, payment and billing logic, infrastructure-as-code, database migrations, and anything touching personally identifiable data. These share high blast radius and low reversibility, not necessarily high complexity, which is why line count is a poor risk signal.
02Can a CODEOWNERS file alone stop a risky pull request from merging?
No. CODEOWNERS only requests a review automatically. It becomes an actual gate only when branch protection or a repository ruleset is set to require an approving review from a code owner before merge is allowed.
03Should every AI-generated pull request get a human review?
Not necessarily. Low-risk changes with full test coverage, such as documentation, internal tooling, or refactors inside already-tested files, can merge on green tests alone. Reserving human review for high-risk paths keeps it meaningful instead of a rubber stamp.
04What makes a gate mechanical instead of just a policy?
A mechanical gate is enforced by the platform itself, a required status check or branch protection rule that blocks the merge button, rather than by a document someone is trusted to remember and follow under deadline pressure.
05How should a pull request that touches both low-risk and high-risk files be handled?
Classify the whole pull request by its highest-risk file, not the average. One high-risk file anywhere in the diff should trigger the mandatory approval requirement for the entire change.