maintainability-agent docs
Plan and evidence

Extending the calibration corpus to eight languages

Genre: empirical. Every number here is reproducible from checked-in pinned inputs: tools/calibration/corpus.json names the repositories and the commits, tools/calibration/measurements.json holds the readings, and tools/calibration/measure.py --check re-derives the constants from them.

The question

Every score this tool reports is a multiple of a corpus median. Through 1.10.1 that corpus was 40 repositories of Python, TypeScript and JavaScript, while the scanner parsed eight languages. Java, C, C++, C# and Fortran were scored against medians measured on none of their code.

The motivating observation was a single number: audited against the old anchor, LAPACK reported declarations at 7.18x the median, and fortran-lang/stdlib at 1.10x. The first is a true statement about LAPACK relative to mature open-source web code, and not a statement about Fortran, because no Fortran was in the comparison set.

Method

Selection is mechanical and unchanged: language:X stars:>N created:<2021-01-01 pushed:>2026-01-01, under an 800 MB size cap, filtered by a name-marker list for curricula and link collections, then verified by cloning each candidate and requiring ≥20 source files and ≥100 declarations. Only the language list changed.

One deliberate exception. The star bar is per language, because 3,000 stars is not the same statement in every ecosystem. Fortran has zero repositories above it; its most-starred serious projects sit between roughly 900 and 1,900 (LAPACK, WRF, Elmer, stdlib, CP2K). A single threshold would have measured popularity rather than maturity and excluded the language outright, so Fortran entered at 500. The thresholds are recorded in corpus.json under selection.min_stars.

The original 40 rows are unchanged and still pinned to the commits they were measured at. Adding languages is the only variable, so the constants moved because of the languages and not because the corpus was re-rolled.

One member was replaced after selection. CPlusPlusThings is a C++ teaching repository; the marker list gained "things" so that category is excluded mechanically rather than by veto. It was found by its measurements (declarations 0.0078 against a 0.1005 reference) rather than by its name — the outcome-triggered discovery a mechanical corpus exists to prevent, and recorded here for the same reason 33-js-concepts was. Re-running selection with the new marker changed exactly one member; googletest took its place.

The corpus

112 repositories, all measured --with-analyzers:

Language Repositories Star threshold
C++ 16 3,000
C 16 3,000
TypeScript 15 3,000
C# 15 3,000
Java 14 3,000
Python 13 3,000
JavaScript 12 3,000
Fortran 11 500

What the constants did

Dimension 1.x 2.0 Move
file_size 0.0858 0.0952 +11%
declarations 0.1005 0.0908 −10%
duplication 0.28 0.3222 +15%
risk 0.0737 0.0826 +12%
gates 0.05 0.05 —
CALIBRATION_C 5.8843 8.7161 +48%

CALIBRATION_C is fitted by bisection so the corpus median rolls up to 4.0 through the full rubric — aspects, then categories, then the overall — not through a closed-form curve. measure.py --check re-derives all six values from the stored measurements and reports no drift.

The result that contradicted the motivation

declarations fell. The number that motivated this work implied the opposite, and the per-language medians explain why. Each cell is that language's median reading as a multiple of the new reference:

Language file_size declarations duplication risk n
Fortran 2.36x 3.90x 4.30x 1.02x 11
C 2.34x 2.07x 1.19x 2.42x 16
C++ 1.33x 0.93x 1.08x 2.04x 16
Python 1.01x 0.78x 0.49x 1.75x 13
JavaScript 0.79x 0.96x 1.28x 0.31x 12
TypeScript 0.73x 1.08x 0.78x 0.98x 15
C# 0.72x 0.92x 0.88x 0.52x 15
Java 0.65x 0.41x 0.69x 0.58x 14
All 112 1.00x 1.01x 1.00x 1.00x 112

"Systems code" was the wrong unit of analysis. C (2.07x) and Fortran (3.90x) do carry denser declarations, exactly as LAPACK suggested. Java (0.41x), C# (0.92x) and C++ (0.93x) carry fewer — and there are 45 of those against 27 of the first, so the aggregate median fell. The languages do not behave as a bloc, and one dramatic repository predicted the direction of the whole corpus incorrectly.

Two further readings worth stating:

What this does not establish

Reproducing it

# Re-derive the constants from the pinned corpus; writes nothing.
python3 tools/calibration/measure.py --check --with-analyzers --reuse \
  --cache-dir /path/to/cache

# Re-measure from scratch (roughly 90 minutes, ~7 GB of clones).
python3 tools/calibration/measure.py --with-analyzers \
  --cache-dir /path/to/cache

--reuse reuses a stored row only when its pinned commit, analyzer population and scanner fingerprint all still match, and measures the rest — so adding a ninth language costs its own repositories rather than all 112. The fingerprint is a digest of the modules that can change a measurement, not the release number: keying on the version re-measured 112 repositories for a documentation release and would have said nothing if the scanner changed within one version.

A corpus measured on two different versions of one analyzer is not a corpus, so a run that would mix them refuses to fit constants and names the tool.