Skip to content

Fix Bundler settings resolution order (#483, #507) - #532

Open
Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
mainfrom
agent/fix-bundler-settings-resolution
Open

Mikola Lysenko (mikolalysenko) wants to merge 3 commits into
mainfrom
agent/fix-bundler-settings-resolution

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #483
Fixes #507

Summary

Gem modes now read Bundler settings in Bundler's own priority, with the local app config over the environment.

Root cause

socket-patch read Bundler settings one key at a time, with no resolver that follows Bundler::Settings priority (local app config $BUNDLE_APP_CONFIG/config / .bundle/config first, then ENV):

  • gemfile: formats/gem/manifest.rs::classify checked the environment before the app config, which is the reverse of Bundler's order. A unit test even pinned the inverted order.
  • cache_path: never read. scan/hosted.rs hard-coded <cwd>/vendor/cache in both guard flavors.

Changes

  • crawlers/ruby_crawler.rs: added bundle_config_setting(contents, key), one exact-key app-config reader that config_gemfile now uses. Added bundler_app_cache_dir[_with_env], which resolves cache_path in Bundler's priority (relative to the project root, absolute stands alone, read-only use so no containment needed).
  • formats/gem/manifest.rs::classify: the app config value now outranks the env. The one exception: an env BUNDLE_GEMFILE naming a file in another directory still decides alone. That value moves Bundler.root, so Bundler reads that root's config and never the project's. The run still refuses, now naming the env var. The inverted unit test is replaced.
  • scan/hosted.rs: both stale-guard flavors use the resolved cache dir, and the warning text now says "its cache dir".
  • Docs: CLI_CONTRACT.md (the "Gem stale-install guard" section, the redirect_gem_bundle_gemfile_unsupported and redirect_gem_stale_install rows), docs/ecosystems.md, and CHANGELOG [Unreleased] / Fixed.
  • No wrapper changes are needed (npm/, pypi/, gem/ only dispatch to the binary).

Per-issue checklist

Test evidence (Linux, Ruby 3.3.6, Bundler 4.0.17)

  • cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test -p socket-patch-core --all-features --lib: 4720 passed, 4 failed. The 4 failures (copy_tree::relax_loop_must_not_traverse_symlinked_root, vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry, pypi_poetry::wire_write_failure_…, pypi_requirements::wire_failure_rolls_back_…) fail identically on origin/main. They are permission tests that root bypasses in this sandbox, and they are unrelated to this change.
  • cargo test -p socket-patch-cli --all-features --lib: 830 passed.
  • --test e2e_redirect_gem_stale_install (25), in_process_gem_apply (11), in_process_gem_multi_platform (7), covgap_commands_scan_hosted (50), hosted_memory_parity (31), core crawler_ruby_e2e (25): all pass.
  • --test e2e_redirect_gem_build -- --ignored (9/9) and --test e2e_vendor_gem_build -- --ignored (5/5), both with real Bundler: all pass, and the non-ignored halves pass too.
  • cargo fmt --all -- --check: main itself is not rustfmt-clean (460 diffs with the pinned 1.93.1 rustfmt, and CI doesn't gate it), so I formatted only this PR's own hunks.
  • I did not run a full local cargo test --workspace --all-features: building every integration-test binary used up the sandbox's disk allowance. CI covers it.
  • CI on 477aae9: all green, 477 passed, 6 skipped, 0 failed. Bugbot: "no issues found", twice.

Follow-ups

  • Bundler's global ~/.bundle/config (priority below ENV) is still not consulted for any key. That was already true and is unchanged here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MWt5CXPnmqVEUZe4wnCfgX


Note

Medium Risk
Changes gem hosted redirect manifest selection and stale-install/VEX exclusion logic; mis-resolution previously could patch or attest the wrong manifest or miss stale committed cache archives.

Overview
Gem hosted and vendored flows now resolve BUNDLE_GEMFILE and cache_path the same way Bundler does: .bundle/config beats the environment, with a narrow exception when env points at a Gemfile outside the project root.

#507: Dual-boot setups (bundle config set --local gemfile Gemfile.next plus exported BUNDLE_GEMFILE=Gemfile) no longer rewrite and attest the ignored Gemfile. The run refuses with redirect_gem_bundle_gemfile_unsupported instead.

#483: The hosted gem stale-install probe checks committed .gem archives under Bundler's configured cache dir (BUNDLE_CACHE_PATH in app config, then env, else vendor/cache), not always vendor/cache. Stale archives there trigger redirect_gem_stale_install and exclude the purl from same-run --vex attestation.

Shared plumbing adds bundle_config_setting and bundler_app_cache_dir in ruby_crawler; manifest::classify inverts gemfile precedence and documents when env-only wins.

Reviewed by Cursor Bugbot for commit 477aae9. Configure here.


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
When BUNDLE_GEMFILE was set both in .bundle/config and in the
environment, socket-patch followed the environment. Bundler does the
reverse: local app config outranks ENV. A dual-boot project with
`gemfile Gemfile.next` committed and BUNDLE_GEMFILE=Gemfile exported
got its Gemfile rewired and attested while bundler installed
Gemfile.next unpatched.

The app config value now wins, unless the environment names a
manifest in another directory (that moves bundler's root, so the
project's config is never read). Add one app-config reader shared by
every Bundler key, and a resolver for bundler's cache dir
(cache_path / BUNDLE_CACHE_PATH, default vendor/cache) in the same
priority.

Refs #507, #483

Assisted-by: Claude Code:claude-opus-5-5
The hosted gem stale-install guard only looked for committed archives
in vendor/cache. With `bundle config set --local cache_path
vendor/gems` (or BUNDLE_CACHE_PATH), a committed unpatched archive
there gave no warning, the same run's VEX attested the gem, and
bundle install then installed the unpatched bytes.

Both guard flavors now use bundler's configured cache dir, so the
stale archive warns, joins the delete-list remedy, and keeps the purl
out of the in-run attestation.

Fixes #483
Fixes #507

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 2, 2026 06:08
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 477aae9. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 2, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review at head 477aae9b35e696e0822a04da1cb2de846b453824.

  • CI: all required checks green on this head (0 failing; remainder skipped/neutral).
  • Bugbot: reviewed 477aae9 — no issues found; no unresolved review threads.
  • Mergeable against main; awaiting human approval.
  • Reviewer focus: Bundler settings priority (local app config over BUNDLE_* env) for BUNDLE_GEMFILE / BUNDLE_CACHE_PATH resolution.

Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

2 participants