Bundler makes its own version part of the application lock
Bundler 2.3 and RubyGems 3.3 cooperate to install and run the version recorded in Gemfile.lock. The change removes a fallback that let local tool installations override an application's intended installer.
A lockfile can pin an application's dependencies while leaving the program that interprets it dependent on the local machine. Bundler used to expose that inconsistency. RubyGems would try to activate the Bundler version recorded in Gemfile.lock if it was installed, but otherwise fall back to the highest installed version. The file recorded intent without ensuring that every installation followed it.
David Rodríguez's January 23 explanation of Bundler 2.3 describes the new behaviour. With RubyGems 3.3 or newer, Bundler can install the missing locked version and restart the original command under it. The application now has a way to determine which Bundler implementation processes its dependencies, even when the machine initially has another version.
I find Ruby more consistent and approachable than the Perl object conventions I came from. Its surrounding tooling matters just as much when a program grows beyond a small script. An explicit installer version makes one part of that environment less dependent on the accidents of a developer's previous installations.
A recorded version becomes an enforced choice
The relevant lockfile section is BUNDLED WITH. Rodríguez uses a file that ends with the following version.
BUNDLED WITH
2.2.33
His example starts with Bundler 2.3.5 installed. Running bundle install does not simply continue with that newer version. It reports the discrepancy, installs Bundler 2.2.33 and restarts using it. Subsequent commands use the version specified by the lockfile.
The example is useful because the automatic choice is an older version. This mechanism is not an instruction to prefer whatever tool is newest. Its rule is the exact version the application records. That can require selecting an older installed implementation or acquiring one that is missing.
This changes the meaning of a developer's local tool inventory. Before the change, the highest installed version could determine behaviour when the intended version was absent. After the change, a supporting RubyGems and Bundler installation can acquire the intended version. The local inventory determines whether installation is necessary, without becoming the application's version policy.
The distinction also explains the two version requirements. The January post specifies Bundler 2.3 and RubyGems 3.3 together. A project should not infer the new selection behaviour merely because a lockfile has a BUNDLED WITH section. That section existed under the earlier fallback behaviour as well.
The package manager supplies the starting point
The earlier RubyGems 3.3.0 announcement records Bundler 2.3.0 as a default gem. It also mentions setting BUNDLER_VERSION when the explicit bundle _<version>_ form is used. These details show that Bundler selection depends on cooperation between the installed package tools, not just a line parsed inside an application's Gemfile.
The default version is a starting implementation available through the tool installation. The lockfile may request another implementation for a particular application. Rodríguez's example demonstrates both roles in one command, since the initially running Bundler performs the installation and hands execution to the selected version.
That is a useful distinction when describing reproducibility. Installing a new RubyGems version and selecting an application's Bundler version are related operations with different scopes. The first changes the available tooling. The second follows the policy recorded for one application.
The new behaviour removes a common piece of external coordination. The January post describes earlier workarounds that manually parsed the lockfile and installed the matching Bundler before proceeding. Moving that behaviour into the tools gives the version record a normal execution path, instead of requiring every environment script to implement it independently.
Tool regressions are application dependencies too
Rodríguez identifies regressions as one reason for locking Bundler. Dependency resolution and installation have many edge cases. A newer Bundler can change behaviour even when the application has not changed the versions of its other gems. Recording the intended installer lets an application choose when that change enters its workflow.
Security fixes create the complementary reason to update the record. If an application selects a fixed Bundler version, all environments following that lockfile can use it. The mechanism itself does not decide that the recorded version is secure. It gives maintainers a way to distribute a deliberate selection.
The Gemfile's own language is another dependency. A project may use a Bundler feature an older installation does not understand. Automatic selection can move execution to the implementation intended by the application, so local tooling age does not automatically define which Gemfile features are usable.
I regard that application-level control as the main benefit. It makes an installer upgrade a change that can be recorded alongside the application. It does not require treating every tool upgrade on a machine as an implicit upgrade for every project on that machine.
Updating the lock remains an explicit action
The January post gives a dedicated operation for changing the selected Bundler version.
bundle update --bundler
The command regenerates the lockfile using the latest Bundler version. Consumers of the changed file then select that version, whether their locally installed alternative is older or newer. The file is therefore both a record of selection and the means by which that selection propagates.
This behaviour should not be generalized to every command that updates dependencies. Rodríguez lists automatic Bundler updates during an ordinary bundle update, and during installation without a lockfile, as possible future improvements. Full treatment of an arbitrary Bundler requirement in the Gemfile is also future work in that account.
Today's boundary is exact lockfile selection with cooperating tool versions. The mechanism covers a missing selected Bundler by installing it and restarting execution. That gives BUNDLED WITH an operational effect that the earlier highest-installed fallback could not guarantee, while leaving changes to the selected version visible in the application lockfile.
The announcement also explains the historical caution behind this design. An earlier attempt at strict version control caused enough trouble to be partly reverted. The current approach supplies the missing version automatically, addressing a practical obstacle to enforcing the record. Exact selection no longer depends on every user having prepared the same tool inventory beforehand.