Nebius x NVIDIA Global AI Hackathon · Coding and Agentic Engineering
AI fixes that show their receipts.
PatchProof runs AI-written security patches in a locked-down sandbox and judges them against a test the model never saw. We measured four NVIDIA Nemotron models on eight hand-built vulnerabilities. Patches that look fine are sometimes still wrong.
What we found
One-shot fixes pass easy cases and fail subtle ones
99 of 100 patches were verified on five common flaw types. On open redirect, 20 of 20 passed the existing tests and failed the hidden oracle.
A hidden oracle catches what ordinary tests miss
On the prefix-traversal, HTML-escaping and open-redirect cases it flagged 33 patches that looked correct and were not.
An AI-written test and retries did not measurably help
Lightning, Nano, Super, Ultra on 8 cases: 112/160 verified with the loop against 126/160 one-shot. The 95% intervals overlap slightly, so we cannot call it worse, but it was not better, at about 12x the tokens.
How it works
Every run follows the same pipeline.
Finding
A plain-English description of one vulnerability and the function it affects.
AI writes an attack test
A Nemotron model writes a test that must fail on the vulnerable code.
AI writes the patch
The model edits app.py only, and may retry using the verifier's output.
Sandbox verifier
Plain code runs every test in Docker: no network, read-only files, dropped privileges.
Hidden oracle
Benchmark only: a hand-written test the model never sees has the final say.
The ledger
One-shot fixes: four models, eight cases.
| Lightning | Nano | Super | Ultra | |
|---|---|---|---|---|
| 01 SQL injection | 5/5 | 5/5 | 5/5 | 5/5 |
| 02 Path traversal | 5/5 | 4/5 | 5/5 | 5/5 |
| 03 Prefix path traversal | 5/5 | 5/5 | 4/51 false fix | 4/51 false fix |
| 04 ORDER BY injection | 5/5 | 5/5 | 5/5 | 5/5 |
| 05 Command injection | 5/5 | 5/5 | 5/5 | 5/5 |
| 06 Unsafe eval | 5/5 | 5/5 | 5/5 | 5/5 |
| 07 HTML escaping | 1/54 false fixes | 0/55 false fixes | 3/52 false fixes | 5/5 |
| 08 Open redirect | 0/55 false fixes | 0/55 false fixes | 0/55 false fixes | 0/55 false fixes |
Verified runs out of five. Green is all verified, red is none. A false fix passed the existing tests and failed the hidden oracle.
Does the retry loop help?
The black line is the 95% interval. Overlapping lines mean this data cannot separate the two.
We tried to rescue the loop
Two more designs, tried after the first results. Neither beat a single call.
Attack-variant library, on held-out cases 09 and 10
Cases 09 to 11 were built after the library was written, so they are an independent test of it. Lightning was truncated on every library run, which explains much of the gap.
| agent | verified | 95% interval | false fixes | tokens per run |
|---|---|---|---|---|
| One-shot fix | 76/80 (95%) | 88% to 98% | 4 | 1339 |
| AI test + retries | 67/80 (84%) | 74% to 90% | 2 | 13211 |
| AI test + retries + attack-variant library | 40/80 (50%) | 39% to 61% | 1 | 21112 |
Hybrid agent, all 11 cases
The hybrid keeps the one-shot patch and uses an AI-written test only as extra evidence. It was designed after all 11 cases had been seen, so this is a development result.
| agent | verified | 95% interval | false fixes | tokens per run |
|---|---|---|---|---|
| One-shot fix | 183/220 (83%) | 78% to 88% | 35 | 985 |
| Hybrid: one-shot patch, AI test as extra evidence | 183/220 (83%) | 78% to 88% | 37 | 10570 |
Runs labelled verified by the AI test that also passed the hidden oracle, by label (passed/runs): contested: 14/20, unproven: 17/17, verified: 152/183. The label did not predict correctness, so we dropped it.
Receipts
Real runs, saved as recorded. Open one to see the AI's test and the patch.
Super · run 1 · one-shot fix
The patch passed the existing tests. The hidden oracle rejected it because ///evil.test/ was still accepted: Python's urlparse reports no host for that form, so the patch treated it as a relative path, and browsers commonly resolve it as a link to another site.
Open the receipt →Super · run 2 · AI test + patch
The patch uses a plain startswith check, so a sibling folder such as files_private still passes. The AI's own test only tried ../secret.txt, so it passed, but the hidden oracle failed the patch.
Open the receipt →Super · run 2 · AI test + patch
The AI's attack test failed on the vulnerable code, the patch passed it, and the hidden oracle confirmed the fix.
Open the receipt →Super · run 2 · AI test + retries
The first test only checked that an unknown column raises ValueError, which is not an injection test, and was rejected. The second attempt used a weaker username-DESC test. The hidden oracle, which tries canary payloads, confirmed the final patch.
Open the receipt →Nano · run 2 · AI test + retries
Neither attempt produced a test that failed cleanly on the vulnerable code, so the run stopped before any patch.
Open the receipt →Lightning · run 1 · AI test + patch
The model's reasoning hit the 16,000-token output limit before it finished a test, so there is no usable test or patch.
Open the receipt →Under the hood
Models
- NVIDIA Nemotron Lightning, Nano, Super and Ultra, through the Nebius Token Factory API.
- Tool calling worked on all four. Reasoning tokens count against the output cap.
Sandbox
- Docker with no network, a read-only root filesystem, dropped Linux capabilities and a non-root user.
- Memory, CPU and process limits, plus a 45 second timeout inside the container.
Verifier
- Plain code decides pass or fail, never the model.
- Test files are hash-checked so a patch cannot edit the tests it is judged by.
Tavily
- A runtime web search adds advisory context to the test-writer in one agent variant.
- In a 12-run test on one case the results were mixed, so we report no measured benefit.
Evidence
- Every result file, the eight cases and their reference fixes are in the repository.
- Read the full summary table.
Limits
- Small samples: five runs per cell and eight hand-built cases. These measure this setup and are not a general benchmark.
- In the benchmark, verified means the AI's test, the existing tests and a hidden oracle all passed. On real code there is no hidden oracle, so a verdict is only as strong as the AI-written test.
- Ultra was available when its runs were made but was no longer listed on the account when checked on Oct 13, 2026.
- The early experiments used the API's default temperature, where Super sometimes returned identical replies. The main evaluation used temperature 0.7.
- Truncated means the model hit the 16,000-token output limit set by the test harness.
- The attack-variant library was written after we had seen the oracles for cases 01 to 08, so only cases 09 to 11 test it fairly. The hybrid agent was designed after all 11 cases had been seen.
- This page shows recorded runs. The agent itself runs locally with Docker.