> Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it SHOULD be precise and comprehensive.
If it's not in the API, it is not bound by the rules. Many ecosystems come up with various norms, like Rust has, to help guide people in this. But it's almost certainly not a semver violation to make the change described in the XKCD because "handle unknown unknowns" is not possible. That doesn't mean that we should throw out the entire idea of software assisted upgrades to dependencies.
The breaks happen regardless, but you have a principled way of defining whose fault/problem it is.
That's the thing: I feel like people tend to call "dependency hell" what I would consider downright malpractice. "Shared libraries don't work because they require good practice" is, IMO, not a good argument against shared libraries. If you need to design your tool with the constraints that "users will use it wrongly", then it's already lost.