In addition to the points raised by the other comments, a big reason we decided not to use `engines` in Volta is that `engines` can be a range: One of the design goals of Volta is to allow for reliable, reproducible environments, and a range is necessarily not static (new versions are released all the time).
Yeah, conceptually the setting is intended to be closer to a lockfile than a semantic version.
Additionally, even with semantic versions, `engines` is often specified as something like `12 || 14 || >= 16`, so they span multiple major versions, which is where breaking changes can (and do) show up.
The engines field is generally used for package consumers so when you do an `npm install` you know if the package is compatible with your local node version.
Pinning the Node.js version for tools like nvm is used by developers of the package or app developers who want to use the same version of node locally and in production, for example.
It functions more like a suggestion than a hard restriction. And, as far as I'm aware, tools such as NVM plain ignore it in favour of their own configuration files.