Thanks for sharing the interesting article Dave.
You noted that "I was building a product not a library; fixating on how to satisfy these library-oriented constraints was the cause of my product-versioning woes:"
I will add that with libraries, it is quite common to install old versions (for example, to use a compatible library version for your current framework). npm, pypi, etc. allow you to download older package versions. However, with Chrome extensions, there is only one supported version and that is the latest version (older versions are not even listed!). Therefore, it has a totally different way to think.
I will also add another way to do versioning, which is to increment:
1. minor version for every public (prod) release,
2. patch version for every private (beta) release, an
3. build version for each internal (alpha version for the colleagues) release.
Thanks to this, whenever you see a new version number in your analytics/error logs, you would know what release channel it corresponds to. For example: 2.8.0.0? That must be a public release. 2.8.1.2? That is a alpha release. 2.8.1.0? That is a beta release.
So, in this way, instead of using numbers to focus on the severity of the change, you can use it to indicate the release channel.