Kelvin versioning

This will be a relatively short post which nearly got included as part of last weekend's "Lua as a practical "soft-bedrock" language", but at the last minute I felt like I was cramming too much in.

I spoke in that post about software "cooling off", "solidifying" and "freezing". I feel like the visual timeline of Lua releases really invites this thermodynamic analogy, with the interval between consecutive releases quickly getting longer and longer. It reminds me right away of how heat energy flows between bodies in contact at a rate proportional to the difference in their temperature, so it starts off quick but then slows down, the hotter body exponentially cooling to equilibrium. Perusing Devine Lu Linvega's XXIIVV wiki a few years ago, I stumbled upon an idea which takes this analogy right to its logical conclusion: "Kelvin versioning". The idea originates with the Urbit project which is...some kind of weird blockchain-based P2P *something*, with apparent links to various politically unsavoury entities. The concept of Kelvin versioning lifts cleanly right out of that context, thankfully, although the extent to which it genuinely applies anywhere else is perhaps quite limited. It's more of an ideological than a practical tool, but I like it never the less.

The original mention of kelver, with deep urbit context, circa 2010

A much later discussion, circa 2020, which tries to formalise kelver

Brief summary of some of the formalised kelver concepts at XXIIVV

In Kelvin versioning (or "kelver"), software version numbers are non-negative integers, like 3 or 5 or 42 or 1337, typically written with an appended K, e.g. 42K, just like a physical temperature measurement in the SI standard unit Kelvin. There are no decimals involved, in contrast to more familiar schemes like semver. When new versions of software are released, the counter goes down, not up. Version 42K is followed by version 41K, which is followed by version 40K, and so on. Since negative versions are not allowed, this convention leads immediately to the defining characteristic of kelver - development must, at some point, cease. The program is eventually frozen at 0K, the bottom of the physical temperature scale, popularly known as "absolute zero".

There's more. If software X depends on software Y, then a release of X is not allowed to declare a lower version number than the then-current version of Y. Release 42K of an app is allowed to depend on lib-foo 16K and lib-bar 5K, but not on lib-baz 69K. This makes all the sense in the world. Calling a release of an application 42K is tantamount to promising there will be no more than 42 future releases. This promise cannot be made in good faith if the developers of all dependencies have not made similar promises that fewer than 42 future releases will be made. That would leave open the possibility that a compatibility-breaking change in a dependency would happen after the program had frozen at absolute zero, leaving it broken forever.

There is in fact a little more even than that, there is also a requirement that when a new version of some software is released then all software which depends on that software is obligated to also make a new release. I personally don't like that idea all that much. Maybe it makes sense within the limited context of urbit's little fantasy world, I don't really know and don't really care. It's the first two principles outlined above which I think represent a perfectly enlightened approach to software engineering. All software ought to aspire to freezing, and stable houses cannot be built on shifting sand, and kelver enforces both of these things.

One interesting aspect of all this is that a developer is forced to make a decision about what to call a program's first release. While traditionally this would simply be something like 1.0.0, when you are counting down and not up there is no obvious starting point. The decision has consequences, however. The smaller a number you start with, the fewer releases you can make before hitting absolute zero. You basically need to forecast how many releases will be required, which is famously tricky. Of course, you can always just start out at, say, one million K. The actual formal kelver spec simply says that each release must receive a version number which is *lower* than the previous one, you are not strictly limited to decrementing by one. I suppose one could, say, begin at one million K and then drop down to one-hundred thousand K at some point when they might otherwise jump from 1.x.y to 2.0.0. The number of orders of magnitude you start with is then something like a total number of major versions you expect to make, in conjunction with a sort of commitment to the total number of minor releases per major version will constantly decrease. A nice thing about this is that the initial release of a program carries with it a clear signal of the author's intentions. Anything launched with a two-digit temperature is obviously intended to be small and simple with a clearly-defined scope, and to iterate pretty rapidly toward something resembling its final form. This is really the kind of thing I prefer to write these days. Honestly, for something like one of my typical OFFLFIRSOCH entries, which I usually don't even bother versioning, launching at 10K would suit me just fine. I might actually try that next year. If I'd known about kelver sooner, I would seriously have considered using it for Gemini specifications, too.

Proxied content from gemini://zaibatsu.circumlunar.space/~solderpunk/gemlog/kelvin-versioning.gmi (external content)

Gemini request details:

Original URL
gemini://zaibatsu.circumlunar.space/~solderpunk/gemlog/kelvin-versioning.gmi
Status code
Success
Meta
text/gemini
Proxied by
kineto

Be advised that no attempt was made to verify the remote SSL certificate.