What if the implementation of some (signature-identical) function changed its performance characteristics dramatically, such that it was no longer valid for use in certain scenarios (i.e. something that previously checked the filesystem now makes a costly query against a remote database)?
What if a function that was previously thread-safe changed, and became non-thread-safe?
What about changes in space (memory) consumed by a function?
These aren't rare classes of behavior change, and they certainly aren't rare pathologies for bugs. And, at least in Go, there's no easy way to encode them in the signatures and/or memory layout of your package in such a way that two non-identical versions can be tested for compatibility automatically. These aren't edge cases.
Of course, this still depends on humans to type the correct commit message. Especially with Node libs, and I can imagine the same is true for go libs, there's no four eyes requirement, little to no review before a version is released.
Yes, Go uses static linking by default, but it also supports dynamic linking and also has a plugin concept built on top of it.
See https://news.ycombinator.com/item?id=17123583
I don't see a vgo issue.
The problem with this solution is that behavior is part of the api, but it is not encoded anywhere that can be compared automatically.
That's exactly what happened in the example in the linked article. Two new fields were added (no problem, that's allowed), and the implementation of another field was changed. This change is either fine because it doesn't change the behavior (refactoring, optimization, fix a bug, etc) or not fine and it changes behavior that breaks existing code, which is what happened in the example.
This behavior was not encoded anywhere, so an automatic publishing gate wouldn't have caught this.