R1.13.1version as breakage signaldesign

Version numbers must express how breaking a change is

Aliases: semver · breaking change signal · version encodes breakage

What it is

A version number is not a release counter. It is a breakage signal written for consumers. A major bump means call sites must change code to compile or to keep prior behaviour; a minor bump means addition only, old calls stay legal; a patch bump means internal repair, the public contract unmoved. Consumers decide “shall I take this update” from those three digits. If the digits say “nothing broke” and an interface has already been renamed, the signal is lying, and every downstream dependency policy will follow the lie.

Breakage is the public contract: prop names, defaults, slot positions, keyboard conventions, observable DOM roles. Internal rewrites, a new rendering engine, invisible bugfixes do not earn a major as long as the contract holds. Conversely, a one-line default change that flips what old calls paint is breakage and wants a major.

Why it happens

Package managers and lockfiles decide by digit: auto-accept patches, treat minors with caution, require a human nod for majors. That automation makes the version a compressed encoding of the contract. Once encoding and real breakage misalign, auto-updates carry breaks into production — or, the other way, keep security patches out (because someone labelled every change a major, and consumers stopped following).

For the signal to hold, the publisher needs a list of “what counts as public contract”, classifies every change against that list, then picks a digit. Without a list, classification is a feeling: feels big, bump major; feels like style, bump patch. Feeling has nothing to do with whether call sites must change, so the digits lose predictive power. Consumers do not see how hard you worked; they see whether their compiler will go red.

Where it stops holding

In 0.x, before stability is promised, majors may by agreement all count as unstable; the moment “you may lock 1.x” is said outside, the rule is in force. Environments where a store or host allows only one installed version still need honest digits — consumers just have no option to stay on the old major, so honesty becomes a warning in the release note rather than an optional dependency. Tiny visual tweaks treated as contract by assistive tech or screenshot tests (contrast, hit area) are also breakage and must not be patched “because it is only colour”. Dates or marketing codenames in the version number bury the breakage signal; give those a separate release name and leave the three digits alone.

Applying it

  • Keep a public-contract list (props, defaults, slots, keyboard, roles). Mark every change on that list: breaking / additive / internal. The digit follows the mark, not “how big it felt”.
  • Put the reason for the digit on the first line of the release record; a reason that does not match the mark cannot be tagged.
  • Diff a snapshot of the public API against the previous tag automatically; undeclared breakage that would ship as a patch blocks the release.
  • How to check: pick three historical releases, list the call-site edits consumers had to make, and compare to the digits used. Edits required but only a patch or minor bumped: the signal lied. Then make a commit that changes only internals: if the detector demands a major, the contract list is too wide. Ask a consumer who did not ship the release, looking only at the version, “can I follow this automatically” — if the answer disagrees with real breakage, the signal is useless.

Related

  • Same group: R1.13.2 Migration cost lands on consumers; pace is set by call-site count · R1.13.3 Design files and code versions must advance in lockstep
  • Adjacent: R1.05 Versioning and migration · R1.06 Contribution and governance
  • Search terms: version as breakage signal · semver · breaking change

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R1.13.1