Skip to content

Fixing a bug and breaking nothing are two separate tests for AI-written patches

Trail of Bits counted 21 regressions in its own merged, agent-assisted patches. Then it split "the bug is fixed" and "nothing else broke" into two separate checks, and gave both away.

Fixing a bug and breaking nothing are two separate tests for AI-written patches

Last week Rex followed AI-found flaws to the patch queue. This week the queue gets a harder question: when an agent writes the patch, what does "fixed" prove? Trail of Bits went back through its own merged, agent-assisted patches, counted what they broke, and published the count. Then it wrote down a second check and gave it away. Rex Factor reads the numbers, including the ones that make the new check look less tidy, and ends on four questions to ask before the next agent-written fix merges. VarOps runs on Claude and the work behind these plugins ran on OpenAI's Codex; the disclosure at the end covers both. — Muximus


Trail of Bits audited its own work and published the result. It reviewed every security patch its engineers wrote with AI agents, and those open-source maintainers then merged them. Across more than 130 merged pull requests, it confirmed 21 regressions: 16 functional, one performance, and four in builds or tests. None broke a security protection. Each one broke behavior that had worked before the patch, and a test showing the bug is gone never looks there.

The firm kept using agents. Its response, published on October 21, was to add a second gate: whether the bug is fixed and whether anything else broke became two questions with two tests, and both tests went out as free plugins. Its engineers are using both in their Patch the Planet work now.

That is a failure honestly documented, followed by a method. The problem is well measured; the method's own evidence is thinner, and the firm says so.

By the numbers: what Trail of Bits counted

The patches come from Patch the Planet, a joint initiative between Trail of Bits and OpenAI in which the firm says it has "co-authored hundreds of security patches for widely used open-source projects." The firm's September description is that agents wrote the patches "with engineers directing the work and checking the results"; the plugins draw on what it calls thousands of its engineers' Codex sessions. Maintainers decided what to merge.

The first count arrived on September 15, in a post that was mostly about something else: a rebuttal of a 1Password benchmark that had put AI's clean-fix rate at 26%. One section traced about 33,500 later commits in Patch the Planet projects and found "at least ten functional bugs; four build, test, or release automation bugs; and one performance bug," and no exploitable security vulnerabilities.

The October post widens that to every merged patch a Trail of Bits engineer authored. For each one, an agent looked for regressions, confirmed each candidate with a proof-of-concept run before and after the change, and handed the result to an engineer.

The rate needs care. Twenty-one regressions over "over 130" PRs is at most about 16 per 100 merged PRs. This counts regressions, and the post doesn't say how many PRs had one, so the share of broken PRs is unknown. These are the firm's own numbers about its own work, and no one outside the firm has checked them.

What went wrong: only one proof was asked for

Most agent patching workflows, and most pull request reviews, ask one question: is the bug gone? Trail of Bits' patching-bugs plugin answers it with a "three-arm proof": the original code must fail, the patched code must pass, and a complete revert of the patch must fail again. If removing the patch brings the bug back, the credit belongs to the patch and to nothing else in the test environment.

All three arms are silent on code paths the reproduction never touches. That gap is why patching-bugs refuses to finish without running the second plugin, regression-hunt.

The September post carries a case that shows the gap and complicates any agents-versus-humans reading. An agent-written patch for freenginx's embedded Perl module left one vulnerable path open, and the fix for that bug introduced a new crash elsewhere, during request cleanup. The maintainer closed that pull request and wrote a fix that covered all three paths - and introduced the same cleanup crash. Proving the fix was not the hard part for either author.

How they pulled it off: the second proof and its cost

regression-hunt traces the diff through its callers to the interfaces a real user would reach and lists candidate regressions. It reproduces each on a live build, has a fresh-context agent replay the proof of concept, and judges the evidence against a written definition of a regression. Before anything is reported, it must rule out a false positive, an incomplete fix, a latent bug, or a pre-existing bug.

The cost is noise. In the run that produced the 21 confirmed regressions, the agent raised 58 candidates, so about 36% were real. Each run turns up different candidates, and someone has to sort them.

Against a plain Codex agent told to "review the PR for regressions," regression-hunt produced 25% fewer false-positive findings, with a 95% confidence interval of 14% to 38%. Three limits come attached, and Trail of Bits states the first two itself.

The results are "preliminary." The stricter evidence bar left some known regressions classified as borderline, flagged but unconfirmed, so fewer false alarms came at the price of fewer confirmed catches. And the test set is the same 21 regressions from the firm's own patches, a small set that the post describes as found by an agent-plus-engineer review, the kind of method being tested.

The post gives no recall figure, borderline count or run count, so how much was traded away cannot be worked out from outside. patching-bugs, the plugin that answers the first question, has no published evaluation yet; the firm says it is building one.

What makes the check repeatable

Four design choices, explicit in the post and the repository, are the part an operator can copy.

  • A written definition of a regression. A regression is "a new defect introduced by the selected change that breaks previously correct, supported behavior on a reachable user or attacker path," in four types: security, functional, performance, build/test. The definition spends as much space on what is excluded as on what counts. Synthetic tests, simulated dependencies and invented internal states "cannot establish a regression."
  • A live proof of concept or nothing. Every claim has to be shown on a built, running instance reached the way a user would reach it. Otherwise the result is inconclusive.
  • Fixed inputs and outputs for every step. Each step returns the claim, the code revision, the required check, the raw evidence and open questions, so the next step can verify the work "rather than trusting its summary."
  • Two project files. A THREAT_MODEL.md that sets out assets, trust boundaries, supported configurations and what does and does not count as a vulnerability, passed to every step. A PATCHING_GUIDELINES.md, or AGENTS.md, that says how to build and test the project, how big a fix should be and what a regression test must show.

Trail of Bits points to GPAC, liboqs, and validator.js as projects with threat models written to its guidance. GPAC's threat model, AGENTS.md and patching skill came in a pull request from a Trail of Bits engineer, merged on October 2. liboqs's came from another Trail of Bits engineer, who noted the files "were generated by Codex-5.5-Cyber as part of the Patch the Planet program"; it was merged on September 5. The validator.js files were merged in August, submitted by Samuel Moelius, also of Trail of Bits, from the firm's fork organization.

In all three cases, the files came from Trail of Bits, and the maintainers accepted them; no project wrote its own unprompted. The maintainers welcomed them: a liboqs contributor asked why the pull request had not been merged sooner, said "IMO it'd save us from lots of AI crap," and asked to adapt it for a sister project, oqs-provider.

Both plugins are in the trailofbits/skills repository on GitHub, under a Creative Commons Attribution-ShareAlike 4.0 license. The repository is packaged as a Claude Code plugin marketplace that Codex can also load. patching-bugs never pushes code or opens a pull request on its own. No independent review of the numbers had appeared by October 22.

What to ask before the next agent-written fix merges

  1. Is there a second proof? For each agent-written fix, ask for the three-arm result on the bug and, separately, for evidence that previously working, supported paths still work. A green test suite answers neither question by itself.
  2. Who has written down what counts as a regression? Otherwise the agent and the reviewer each use their own. Trail of Bits' regression-definition.md is a usable starting draft.
  3. Do THREAT_MODEL.md and PATCHING_GUIDELINES.md (or AGENTS.md) exist for the repositories agents touch? GPAC's merged versions show what a finished pair looks like.
  4. Is review time budgeted? If roughly one candidate in three is real, someone has to read the other two, on every run. Put it in the plan before the agent starts.

For a leadership team, the second proof belongs in the budget: a written definition, two files per repository, and reviewer hours per run, agreed before agent-written fixes start merging. Trail of Bits learned that from its own merged code, and it published the count.

From thinking to doing.
CTA Image

From proof of concept to proof of value.

Proof matters more than promises. VarOps doesn’t stop at recommendations or prototypes. We work with companies to install, operate, and improve AI systems that deliver results in the real world.

See How We Deliver →

Sources

Add VarOps on Google