If this happens, then either the NPM registry has been compromised or my system's 'npm' program or your system's 'npm' program has been compromised.
If the discrepancy is due to one of us running a malicious 'npm', then that malicious 'npm' CLI program could've just not flagged the signature mismatch, so specifying a hash doesn't help us anything.
If both of us are using a non-compromised 'npm' program, and the NPM registry isn't compromised, then we will never be in a situation where my "fooapp version 7.8.9" and your "fooapp version 7.8.9" differs. If a malicious actor compromises an account with publish access for the fooapp package, then all the malicious actor can do is publish a new "fooapp version 7.8.10" that has malware. That's what has happened in every single one of these high profile NPM hacks. You can't retroactively change old versions of your own packages. So to protect against this kind of attack (which, again, means every single NPM hack to date), just not auto-upgrading between minor versions is enough.
To protect against a compromised NPM registry, I agree that we should have package checksums living in our git repositories. But NPM already has that: the package-lock.json contains checksums. I don't understand what it would give us to have that checksum in the package.json instead of the package-lock.json.