It would be impossible to do so perfectly for a turing complete language. You could get close by running the previous minor version's test suite against the new update, but that would essentially make the package repository into a continuous integration server, which is expensive to maintain. There's another, less perfect way of detecting API breakage, which is to use the rustdoc tool to export the projects documentation as json. This would let cargo detect whether items had been added, removed or renamed, which covers a large number of cases in which API compatibility is broken. If it encourages developers to up the version number rather than fix the flagged incompatibilities, then it will also drastically reduce the number of incompatibilities in the package repository that can't be detected by rustdoc. While it's impossible to completely eliminate the human element in upholding the version number contract, software can limit the number of errors in the system.
How hard would it be to get usable type signatures out of the compiler as well? It seems like diffing two sets of type signatures would capture everything but purely semantic api incompatibility. Also seems like "here's a machine-readable version of all the types in this package" is a useful thing for a compiler toolchain to produce.
Because, of course, Mozilla is paying you to sit around on your hands.