Roseau accuracy dataset (replication kit)
mavenSourceOn hand-built Java library version pairs with exhaustively enumerated API breaking changes, does Drift produce the same set?
- In the dataset
- 267
- Evaluated
- 267
- Scored
- 255
- Excluded
- 12
ground-truth-contested
157 of the scored cases are negative controls — changes labelled not breaking. They are what make a false positive measurable.
Precision
98/99
99.0%
Recall
98/98
100.0%
F1
0.995
harmonic mean
TP 98 · FP 1 · TN 156 · FN 0
| breaking-change detection recall | 98/98 (100.0%)95% 100–100% |
What this does not establish. Nothing about Drift on real-world Java projects: this dataset is constructed to enumerate API change kinds exhaustively, which is what makes precision meaningful and also what makes it unrepresentative of an actual upgrade.
Methodology, provenance and per-slice results
The one corpus here with real negatives. 267 hand-built Java version pairs, each labelled by hand for whether the change is binary-breaking, and roughly half labelled *not* breaking — which is what makes precision, a false-positive rate and F1 defined here and nowhere else in this benchmark.
Drift runs its real Java surface diff: computeSurfaceDiff from the shipped build, routed to the japicmp provider, shelling out to the japicmp binary. The dataset ships source rather than jars, so both trees are compiled with javac and served to production's own fetchArchive as though Maven Central had them. The substitution is transport; every line of analysis between the download and the result is production's.
Scored against the isBinaryBreaking column, because japicmp compares classfiles and binary compatibility is the question it answers. The source-compatibility label is carried in every case artifact for anyone who wants to score it the other way.
The replication kit's own recorded labels for Roseau, Japicmp and Revapi travel in each artifact. They are labels as recorded in the kit, produced on the authors' machines with their tool versions — not re-run here — and any comparison drawn from them should say so.
6 reported change(s) did not belong to any of the 267 labelled case packages; 0 are unexplained. Each remaining unmatched change is classified below rather than silently discarded:
- testing_lib.accessModifierClazzNestedClazzAccessDecreaseProtectedToNon.AccessModifierClazzNestedClazzAccessDecreaseProtectedToNon$Clazz — non-benchmark-source-package: accessModifierClazzNestedClazzAccessDecreaseProtectedToNon is present in the Roseau source tree but absent from results/bench/jezek_dietrich.json, so it is not one of the 267 labelled benchmark cases and cannot change a per-case TP/FP/TN/FN assignment.
- testing_lib.accessModifierClazzNestedClazzAccessDecreaseProtectedToNon.AccessModifierClazzNestedClazzAccessDecreaseProtectedToNon$Clazz.AccessModifierClazzNestedClazzAccessDecreaseProtectedToNon$Clazz — non-benchmark-source-package: accessModifierClazzNestedClazzAccessDecreaseProtectedToNon is present in the Roseau source tree but absent from results/bench/jezek_dietrich.json, so it is not one of the 267 labelled benchmark cases and cannot change a per-case TP/FP/TN/FN assignment.
- testing_lib.accessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate.AccessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate$Clazz — non-benchmark-source-package: accessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate is present in the Roseau source tree but absent from results/bench/jezek_dietrich.json, so it is not one of the 267 labelled benchmark cases and cannot change a per-case TP/FP/TN/FN assignment.
- testing_lib.accessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate.AccessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate$Clazz.AccessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate$Clazz — non-benchmark-source-package: accessModifierClazzNestedClazzAccessDecreaseProtectedToPrivate is present in the Roseau source tree but absent from results/bench/jezek_dietrich.json, so it is not one of the 267 labelled benchmark cases and cannot change a per-case TP/FP/TN/FN assignment.
- testing_lib.accessModifierClazzNestedIfazeAccessDecreaseProtectedToNon.AccessModifierClazzNestedIfazeAccessDecreaseProtectedToNon$Ifaze — non-benchmark-source-package: accessModifierClazzNestedIfazeAccessDecreaseProtectedToNon is present in the Roseau source tree but absent from results/bench/jezek_dietrich.json, so it is not one of the 267 labelled benchmark cases and cannot change a per-case TP/FP/TN/FN assignment.
- testing_lib.accessModifierClazzNestedIfazeAccessDecreaseProtectedToPrivate.AccessModifierClazzNestedIfazeAccessDecreaseProtectedToPrivate$Ifaze — non-benchmark-source-package: accessModifierClazzNestedIfazeAccessDecreaseProtectedToPrivate is present in the Roseau source tree but absent from results/bench/jezek_dietrich.json, so it is not one of the 267 labelled benchmark cases and cannot change a per-case TP/FP/TN/FN assignment.
Provenance
Dataset version: 10.5281/zenodo.15536418
Licence: see the replication kit
Citation: Roseau replication kit, Zenodo, DOI 10.5281/zenodo.15536418; tool at https://github.com/alien-tools/roseau
Drift commit: ac9c8b852a
Run date: 2026-09-16
Platform: linux/x64, Node v22.23.2
Run id: roseau-accuracy
Ground truth
Granularity: api-symbol
Exhaustive at that granularity: yes
Metrics it can support: recall, precision, f1, category-accuracy
Constructed library pairs with every API breaking change enumerated at symbol level, which is what supports precision and F1.
Label mapping coverage
This corpus’s vocabulary is not Drift’s. Only exact and compatible mappings are scored for category correctness; ambiguous and unsupported ones are counted here rather than forced into the nearest Drift kind.
- exact: 267
Breakdown
Every rate again, split by the dataset’s own labels. A pooled figure hides both directions of the interesting result, so it is never the only number here.
| Slice | breaking-change detection recall |
|---|---|
| groundTruthSourceBreaking: false | 20/20 (100.0%) |
| groundTruthSourceBreaking: true | 78/78 (100.0%) |
| label: binary-breaking | 98/98 (100.0%) |
Toolchain the run actually had
- node: v22.23.2
- npm: 10.9.8
- git: git version 2.55.0
- java: openjdk version "21.0.12.1" 2026-08-18 LTS
- mvn: Apache Maven 3.9.16 (2bdd9fddda4b155ebf8000e807eb73fd829a51d5)
- docker: Docker version 28.0.4, build b8034c0
- python3: Python 3.12.3
- uv: not installed
- japicmp: installed (version unknown)
Reproduce
npm run eval:external -- roseau
Artifacts, including every per-case prediction and label, are in eval/results/roseau-accuracy/.