All three shared a failure mode: the build stays green while doing something
other than what the config says.
composeBom was "2026.+". The Compose BOM numbers as YYYY.MM.PP, so the year is
the major -- that float stops finding releases on 1 January 2027 and keeps
building happily against a frozen BOM, with nothing in CI or the diff to say so.
Bare "+" now, which is safe only because the prerelease guard is there.
smart-exception was floating on "0.+". Under semver a 0.x minor may break, and
this library is load-bearing precisely where breakage hides: the ffmpeg-kit
wrapper reaches for smartexception.java.Exceptions only when a call FAILS, so a
moved class shows up as an R8 missing-class error at release, or as a crash on
the error path -- the least-exercised code in the app, by its own comment.
Pinned, with that written down. It was noticed while the float was being written
and shipped anyway, which is the actual mistake here.
The prerelease guard permitted detekt's alpha by accident. The pattern wanted
digits straight after the marker word, and detekt reads "2.0.0-alpha.6" with a
dot -- so it passed on punctuation. Had it read "alpha6" the build would have
broken with no way to see why from the config. There is now an explicit
prereleasePermitted set, and the pattern tolerates both spellings, so the
exemption is a decision instead of a coincidence.
Also corrects a comment that was confidently wrong: componentSelection rejects
STATIC prerelease versions too, not only floating ones. Naming "2.12.0-alpha01"
in the catalog does not get you that alpha, it fails to resolve -- verified, not
assumed, because the obvious guess is the opposite. Prereleases are taken by
adding the group to prereleasePermitted.
Two stale references to Gradle 9.5 updated to 9.7.1.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>