I had an idea that I've been sitting on for a while and it looks like I'll probably never get around to it so I thought I'd offer it up for others to think about:

We've flirted with separating interface from implementation over and over again. We also talk sometimes about the tests being the actual requirements definition for the system.

If we versioned the tests and declared which version of the tests pass with a given version of the code, we might get closer to a workable system. Most of the time a bug fix should result in new tests, not changing old tests - unless there are backward incompatible changes. This may require us to up our test writing game, but that sounds like a good carrot to me.

Semver is mostly about 'increment a number on every change, increment another number when the changes are not backward compatible (covariant?)' for some definition of compatible. But if we have tried to define 'compatible' in a rigorous way, I haven't seen it. I suspect someone in Formal Methods has something up their sleeve. I'd be curious to know if they have anything we can cherry-pick.

There's been a lot of attention given to this in Rust:

- Defining semver requirements for the ecosystem: https://stackoverflow.com/questions/41185023/what-exactly-is...

- There's also a library that attempts to automatically check sermver adherence of a crate: https://github.com/rust-lang/rust-semverver

- And there has been quite a bit of effort into preventing semver requirements from fracturing the ecosystem. This revolves around the compiler working with multiple major versions of a single library: https://github.com/dtolnay/semver-trick