Repository navigation
Description
[agent] Filed by the scheduled architecture audit (audit-core). Register: register.
Kind: bug (duplicated rule that drifted). Register ID: A53.
Problem
Bundler's Settings#path tier rule (the first config tier that sets path, path.system or disable_shared_gems decides, and a falsy disable_shared_gems means system gems) is implemented twice in crawlers/ruby_crawler.rs, and the two copies disagree:
- Copy A:
bundler_sets_explicit_pathL1347-L1379,`` used bybundler_uses_system_gems. It treats `disable_shared_gems` set to a falsy value as "use system gems", as Bundler does. - Copy B:
bundler_path_tierL880-L907 plusconfig_path_tierL2410-L2423,````` used by store discovery.disable_shared_gemsonly makes a tier count. `system` is read from `BUNDLE_PATH__SYSTEM` alone:system: bundle_config_setting_including_empty(contents, "BUNDLE_PATH__SYSTEM") .is_some_and(|v| bundler_truthy(&v)),
- Partial copies of the same rule: the
shadowedcheck (L519-L520),``````global_path_config_unless_env_path_settingsL2164-L2174,``````` and the same-file `path.system` drop in `parse_bundle_config_path_with` L2377-L2395.```````` - Two structs model the same concept:
BundlerPathSettingsandBundlerPathTier.
Executed in a scratch copy of the workspace at cbbbdb9. The project has a Gemfile, a leftover vendor/bundle store, and a .bundle/config containing BUNDLE_DISABLE_SHARED_GEMS: "false".
bundler_sets_explicit_pathreturns false, meaning system gems.- Discovery still returns the leftover
vendor/bundlestore withdefault_root_has_stores = true. - So
get_gem_pathsdrops thegem envhomes, and apply targets a copy that Bundler does not load. This is the Gem crawler ignores Bundler'spath.system: truewhen a leftovervendor/bundleexists, so agentapplypatches the unused copy andvexattestsnot_affectedwhile Bundler loads the unpatched system gem #915 shape, through this flag.
As a control, the same project with BUNDLE_PATH__SYSTEM: "true" returns [].
Proposed change
Replace the copies with one resolver over BundlerPathSettings that returns { explicit_path, system, deciding_tier }. Use it from discovery (bundler_path_tier), from shadowed, and from bundler_uses_system_gems. Then delete BundlerPathTier and config_path_tier, and fold global_path_config_unless_env_path_settings into the resolver.
Size
1 file (crawlers/ruby_crawler.rs), about −80/+40 production lines, plus one test.
Acceptance criteria
- A new unit test:
disable_shared_gems: "false"with a leftovervendor/bundleyields no bundle store, and the gem env homes are kept. - Existing
path.system,BUNDLE_PATHand deployment tests pass unchanged. - One tier resolver remains, and one settings struct.
Activity
audit-core: 21 core files (ruby crawler, sbt/scala evidence, formats …
mikolalysenko commentedon Nov 1, 2026
[agent] Triage: priority:p1 (Bundler). Related to #1935, which plans to move the resolver this issue unifies; fix this first. No open PR covers it.
Generated by Claude Code
mikolalysenko commentedon Nov 1, 2026
[agent] Claiming this issue (shared root cause: Bundler's path tier rule is implemented twice in ruby_crawler and store discovery's copy ignores a falsy disable_shared_gems). Branch: agent/fix-bundler-path-tier-resolver. Claim-ID: 2026-11-01T16:21:11Z-b085f2
Generated by Claude Code
mikolalysenko commentedon Nov 1, 2026
[agent] Draft PR: #1943
Generated by Claude Code
Fix gems patched where Bundler doesn't load them
Drop a same-tier path under system gems