Security · AI · Critical infrastructure
EdgePatch checks AI-written security patches for C code, completely offline. It runs a fixed set of automated checks on each patch and gives a person one report to approve or reject.
TL;DR · the 60-second version
For systems with no internet access, where a bad patch is hard to undo: an AI suggests the patch, EdgePatch runs automated checks on it, and a person makes the final call.
Who it's for: teams that run offline, high-stakes systems — critical infrastructure, industrial control, regulated finance and healthcare, defense and allied networks — and the engineers who have to approve a machine-written fix. Not for a connected team with full cloud access and testing infrastructure; they have easier options.
How it works
An AI can write a patch that looks right. Whether it's actually correct is a separate question. In these systems the margin for error is even smaller — a bad patch can mean downtime, a failed audit, or a safety problem, and you often can't simply undo it. So you need a way to check the fix that doesn't depend on the AI that wrote it. EdgePatch does this with a fixed sequence of checks: each one looks at the patch and either stops it or passes it to the next. Only a patch that passes every check reaches a person.
The patch can come from an AI model on-site, a secure system, or an official update — EdgePatch treats them all the same. What actually arrives is a diff: a list of the exact lines to remove and add.
Every diff says "find these exact lines and change them." EdgePatch does a dry run: it takes the lines the patch expects to find and checks they actually exist, exactly, in the real file — without changing anything yet. If the file has moved on, or the patch is malformed, the lines won't match and it's rejected right away, before any more effort is spent.
This check runs only when we have a known-correct fix to compare against (for example, an official fix delivered offline). Here's how it works: EdgePatch reads the patch to see which lines changed, then scans the code to find which function those lines belong to. It does the same for the known-correct fix, then compares the two — same file? same function? about the same size? If they line up, the patch is in the right place. If it's in a different function, or far bigger or smaller, that's a red flag.
This is where correctness is checked, and it doesn't need a reference. In a safe, separate environment the patched code is compiled and run: does it build, is the original crash gone, and do all the existing tests still pass? Those results are recorded and passed to EdgePatch. (EdgePatch reads the results — it doesn't run the code or trigger the vulnerability itself.)
EdgePatch collects everything — did it apply, did it land in the right place, does it build and pass tests, plus the supporting evidence — into a single report. The report gives a clear verdict, the reasons for it, and the evidence behind it. It also serves as the audit record: a durable account of what was checked and why the decision was made, so the approval can be reviewed later.
A person reads the report and makes the call. EdgePatch never applies the patch itself — it lays out the evidence and recommends; a person approves or rejects. If approved, the fix is then applied through the site's normal change-control process (a maintenance window, the usual sign-offs) — a deliberate, human-run step, not something EdgePatch does. The rule for a ready verdict is strict: the patch must apply, build, stop the crash, pass all tests, and — when checked — land in the right place.
EdgePatch is deliberately narrow — that focus is what makes it reliable:
This is an early-stage need: AI help with patching reaches offline, high-stakes systems last, and matters there most. The same pattern — a change that has to be checked and approved by a person — also fits regulated cloud and cross-domain work.
What's next
v1 is the core: the checks, the report, and the benchmark that proves the checks work. The next steps add stronger evidence and cover more code.
Why it matters
AI is going to write a lot of security patches. The hard part isn't getting a model to suggest a fix — it's knowing whether to trust one, especially offline and in systems where a bad patch is hard to undo. EdgePatch turns an AI's suggestion into a checked report a person can approve, and gives the same answer every time. The AI writes the patch; the checking doesn't rely on the AI. That's what these systems need, and it works today.
Appendix — the evidence
This follows the six steps above: how the patches were graded, then the results for the "right place" check, then the full build-and-test run, then what the report can say, then how to reproduce it.
Setup · how the patches were graded
To test whether the checks are any good, we needed cases where the right answer was already known. So we used old bugs that have long since been fixed, and treated each real fix as the answer key. Only patches whose correct answer was established independently count toward the score — three kinds qualify; a fourth is analyzed but never counted.
The expected result for each case was written down before scoring, so the grading can't drift to fit the outcome.
Step 3 · the "right place" check
Across the nine graded patches, every one was classified correctly in both directions — good patches accepted, bad patches rejected — with no misses.
| Metric | Value |
|---|---|
| Graded patches | 9 |
| Classified correctly | 9 / 9 |
| Good patches accepted | all |
| Bad patches rejected | all |
| Mistakes | 0 |
| By library | Right | By bug type | Right |
|---|---|---|---|
| zlib | 2 / 2 | out-of-bounds read (CWE-125) | 3 / 3 |
| libpng | 3 / 3 | integer overflow (CWE-190) | 4 / 4 |
| expat | 2 / 2 | out-of-bounds write (CWE-787) | 2 / 2 |
| libxml2 | 2 / 2 |
We also pointed the checks at three unverified AI patches — kept out of the score above — and each was caught for a different reason:
| Library | Caught as | In plain terms |
|---|---|---|
| expat | malformed | the diff didn't even apply |
| libpng | wrong function | changed the wrong part of the code |
| libxml2 | incomplete | too small to be the real fix |
Step 4 · building and testing
The nine results above are all from the "right place" check. Exactly one case — zlib CVE-2022-37434 — was carried all the way through: the patch was built and run, the crash confirmed gone, and the existing tests confirmed still passing. So read it as one full build-and-test run plus nine "right place" checks — not nine full fixes.
Step 5 · what the report can say
For the "right place" check, a patch is marked as right place or flagged as wrong file wrong function incomplete too broad malformed.
Combining that with the build-and-test evidence, the overall verdict is one of: READY READY, WITH CAVEATS NEEDS REVIEW NEEDS TESTING REJECT — wrong location REJECT — broke a test REJECT — incomplete CAN'T TELL — missing evidence. The key rule: READY requires the crash resolved and tests passing and a matching location. Nothing is marked ready on location alone.
Reproduce
| Library | CVE | Bug type | Where the fix goes |
|---|---|---|---|
| zlib | CVE-2022-37434 | CWE-787 | inflate.c · inflate |
| libpng | CVE-2025-64505 | CWE-125 | pngrtran.c · png_set_quantize |
| expat | CVE-2022-25315 | CWE-190 | xmlparse.c · storeRawNames |
| libxml2 | CVE-2022-40303 | CWE-190 | parser.c · xmlParseNameComplex |