Breakwater

Backtest · pypa/packaging · 2026 performance PRs

Faster isn't the same as correct.

Breakwater audits performance pull requests the way an attacker would. A Nemotron adversary reads the diff, guesses which assumptions the "faster" code makes, and hunts for inputs where the new version behaves differently or runs slower. Deterministic probes and instruction counts confirm everything it claims.

9/9
documented regressions caught before merge
best no-LLM baseline: 7/9
29
merged perf PRs audited
pypa/packaging, the version library inside pip
8/10
found regressions labelled likely-bug
Ultra adjudication, evidence-checked
$2.02
Nemotron cost of these results
Token Factory, backtest + adjudication; excludes dev and superseded runs and reused perf

Documented regressions caught before merge

9 regressions in these PRs were later fixed upstream. Each approach got the same PRs, the same probes and no hint of which bugs exist.

The PRs' own tests + benchmarksthese PRs merged green
0/9
Plain Hypothesisst.text() search, no LLM
2/9
Mutations of the PR's own test stringshostile edits of literals from the project's tests, no LLM
7/9
Nemotron plan onlyUltra's example inputs, no search
6/9
BreakwaterUltra plan + Lightning strategies + search + mutations
9/9

Candidates (linked to fixes but not reproduced by hand): Breakwater 1/3. PRs with any behaviour divergence: 9/29.

Every PR

PRChangeVerdictClassesKnown issue caught Perf worstBackendCost
#997perf: better string buildingVersion · 2026-01-06no divergence––Docker$0.033
#1028perf: don't renormalize extrasRequirement · 2026-01-06no divergence––Docker$0.021
#1029perf: use fullmatch for markers tooMarker · 2026-01-04no divergence––Docker$0.018
#1030perf: translate for canonicalize_namecanonicalize_name · 2026-01-05BLOCK8unicode-lowercase4.52×Docker$0.049
#1032perf: add __slots__ to NodesMarker · 2026-01-02BLOCK1––Docker$0.026
#1058perf: 10% faster stripping zerosVersion · 2026-01-14no divergence––Docker$0.045
#1064perf: dual replacecanonicalize_name · 2026-01-19PASS7–1.10×Docker$0.039
#1076perf: Stream PEP440 filtering in SpecifierSet.filterSpecifierSet#filter · 2026-01-30no divergence––Docker$0.048
#1081perf: Skip __replace__ in Specifier comparison if not neededSpecifier · 2026-02-09no divergence––Docker$0.030
#1082perf: Add fast path for parsing simple versions (digits and dots only)Version · 2026-02-11BLOCK1 1oversized-int-exception2.85×Docker$0.10
1082@61967ccaperf: fast path for simple versions (intermediate commit 61967cca)Version · 2026-02-11BLOCK3 2inner-whitespace, oversized-int-exception, unicode-digits1.91×Docker$0.097
#1083perf: Add fast path for Version to Version comparison by skipping _key propertyVersion · 2026-03-06no divergence––Docker$0.035
#1105perf: Speed up complex SpecifierSet filtering by implementing cost based orderingSpecifierSet#filter · 2026-03-08no divergence––Docker$0.058
#1106perf: simply Specifier regexSpecifier · 2026-03-09no divergence––Docker$0.090
#1108perf: SpecifierSet use tuple instead of frozenset for _specsSpecifierSet · 2026-03-07BLOCK12 3dedup-equality, dedup-str-len, old-pickles-break-comparison–Docker$0.28
#1111perf: Speed up wildcard comparisonSpecifier#contains · 2026-03-09no divergence––Docker$0.12
#1115perf: skip hash propertyVersion · 2026-03-11no divergence––Docker$0.041
#1116perf: Overhaul _cmpkey to remove use of custom objectsVersion · 2026-03-11BLOCK1old-pickles-fail-to-load–Docker$0.12
#1118perf: Cache Version hash value in dedicated slotVersion · 2026-03-13no divergencenone–Docker$0.044
#1147perf: add __slots__ to MarkerMarker · 2026-04-05BLOCK1marker-pickle–Docker$0.027
#1236 †perf: simply work done in parse_tag a bitparse_tag · 2026-06-09PASS4–1.09×Docker$0.17
#1250 †perf(markers): cache the default environmentMarker#evaluate · 2026-07-10no divergence––Docker$0.031
#1253 †perf(specifiers): keep range caches across canonicalizationSpecifierSet#contains · 2026-06-16no divergence––Docker$0.056
#1256 †perf(utils): precompile the wheel project-name patternparse_wheel_filename · 2026-06-13no divergence––Docker$0.11
#1258 †perf: add __slots__ to token classesRequirement · 2026-06-13no divergence––Docker$0.010
#1259 †perf(specifiers): push PEP 440 logic into the range engineSpecifierSet#contains · 2026-06-15no divergence––Docker$0.082
#1320 †perf: add __slots__ to RequirementRequirement · 2026-07-07no divergencenone–Docker$0.11
#1371 †perf(markers): speed up _format_marker and benchmark str(Marker)Marker · 2026-09-25no divergence––Docker$0.10
#1429 †perf(parser): avoid literal_eval for plain marker stringsMarker · 2026-10-05no divergence––Docker$0.032

Audit runs

Single audits from breakwater audit, as shown in the demo.

RunChangeVerdictClassesBackendCost
c1a7799be95fperf: fast path for simple versions (intermediate commit 61967cca)packaging.version:VersionBLOCK6Docker$0.11
e780ff68654fperf: fast path for simple versions (intermediate commit 61967cca)packaging.version:VersionBLOCK6Sandboxes$0.18

Also audited: 10 merged AI-written speedups

PRs by the Codeflash optimiser bot, merged by maintainers. No known bugs to score against: 4 of 10 change behaviour, and the instruction counts check each claim.

See all 10

Checked on Token Factory Sandboxes: 5/8 verdicts agree

8 of these PRs were audited again with every untrusted run in a Token Factory Sandboxes microVM; the 3 perf families measured on both agree in verdict, with Ir ratios up to 44% apart. Each number cites the image UUID that reproduces it.

See the comparison

How a verdict is made

  1. Plan. Nemotron 3 Ultra reads the diff and names the assumptions the fast path makes, with example inputs that would break them.
  2. Search. Nemotron 3.5 Lightning writes Hypothesis strategies; base and head run side by side in isolated sandboxes, and counterexamples shrink to their minimal form. Hostile mutations of the project's own test strings run too.
  3. Probe. Deterministic checks compare outputs, exact exception types, equality / ordering / hashing, and whether objects pickled by the old version still load and compare.
  4. Measure. Slowdown families are confirmed by cachegrind instruction counts across input sizes from 2 to 4,096: deterministic, so a ratio is a fact rather than noise.
  5. Adjudicate. Ultra labels each divergence likely-bug, intended or needs-human. Three votes; a vote counts only if its evidence is quoted verbatim from the PR. The model can label, never delete.