I agree that reproducible builds are absolutely necessary. Nobody's proposing taking those away.
There's a distinction here between how you pick a version in production, and what happens when you do an `npm update` or `gem update`. I'm getting the sense since my last comment that in the Java world the second flow doesn't actually exist. What is your typical workflow for updating your libraries (fixed in the Gradle lockfile) to newer versions? In the Rails world you specify your dependencies in a file called Gemfile, and running `bundle install` fixes the versions chosen for them in a file called Gemfile.lock. In this context, Steve Losh is complaining about the former. Versions in Gemfile.lock are absolutely fine. It's auto-generated after all. Versions in the manually managed Gemfile are a smell.
Does this make sense? I think we have a misunderstanding rather than a fundamental disagreement. I'm actually kinda glad to hear that you had this confusion even after reading the OP (and thanks for doing so!). It makes me feel better about my own writing.
Ok this makes sense. So the way we do this with Nebula + the dependency locking plugin is that we specify a version constraint for each dependency. Typically that would be something like latest.release for internal dependencies, major.+ for important 3rd party dependencies like guava, and potentially a specific version number for less important 3rd party dependencies.
Re-generating the lock file would pull the latest versions that satisfy the constraints. That lock file is not supposed to be edited manually.
> the fact that manually specifying version numbers to avoid running newer code is commonplace, expected, and a “best practice” horrifies me
I think version pinning is not only a "best practice", I think it is absolutely necessary. I demand reproducible builds.