Skip to content

Fix gem pair model ignoring custom lockfile and Bundler 1 twins (#749, #751) - #768

Merged
Mikola Lysenko (mikolalysenko) merged 30 commits into
mainfrom
agent/fix-gem-loaded-pair-model
Oct 8, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 30 commits into
mainfrom
agent/fix-gem-loaded-pair-model

Conversation

@mikolalysenko

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

Copy link
Copy Markdown
Collaborator

Fixes #749
Fixes #751

Summary

Hosted gem mode wired the wrong files in two Bundler layouts. In both, the scan reported success (and --vex attested the patch) while Bundler installed the unpatched gem or every frozen install failed. Both are now refused before anything is written.

Root cause

formats::gem::manifest::LoadedManifest is the single model of "which manifest/lock pair does Bundler load", and hosted mode (keep_bundler_loaded_gem_files) and vendored mode (gem_manifest_refusal) both rely on it. It modelled BUNDLE_GEMFILE, but:

Fix

  • LoadedManifest::with_lockfile resolves the configured lockfile the way Bundler::CLI does (env first, then app config, then the global ~/.bundle/config that Gem settings resolution skips Bundler's global config (~/.bundle/config / BUNDLE_USER_CONFIG), so a global cache_path or gemfile gets no warning or refusal and VEX attests an unpatched install #577 / Fix Bundler global config being ignored (#577) #621 added; BUNDLE_IGNORE_CONFIG honoured; relative to the project root). If it names the loaded pair's own lock, nothing changes. Anything else is the new UnsupportedLockfile:
    • hosted mode refuses with redirect_gem_bundle_lockfile_unsupported (nothing written, nothing attested);
    • vendored mode refuses with gemfile_not_loaded.
  • A Gemfile + gems.rb twin under default discovery is refused with redirect_gem_twin_manifest_ambiguous (manifest::twin_manifest_refusal), whatever its locks' BUNDLED WITH say. Nothing is written or attested. BUNDLED WITH records which Bundler wrote a lock, not which one installs it, and the twin's pair depends only on the running major. Lock inventory and VEX discovery read no lock for a twin (gem_lock_unsupported). A spelling counts as present whenever Bundler's File.file? may see it, which includes one this run couldn't read (symlinked, unreadable or non-UTF-8). BUNDLE_GEMFILE naming either spelling still selects that pair, and a lone Gemfile or gems.rb is unchanged. This matches vendored mode, which already refused twins. An earlier revision picked the pair from BUNDLED WITH; see the security-review follow-up below.
  • Docs: CLI_CONTRACT.md (new additive warning codes), docs/ecosystems.md (RubyGems row). The CHANGELOG entry was dropped in 7c84ba8.

Tests (red → green)

Issue Test Without fix With fix
#749 hosted_memory_engine::a_bundler4_custom_lockfile_is_refused FAILED (rewrote the leftover lock) ok
#749 e2e_redirect_gem_build::gem_hosted_bundler4_custom_lockfile_redirects_nothing (real Bundler 4.0.17) FAILED: redirected: 1, rewrittenFiles: [Gemfile, Gemfile.lock], vex statements: 1 ok; frozen bundle install of the untouched project succeeds
#749 ruby_crawler::loaded_manifest_reads_the_lockfile_setting (disk, no leftover lock; env vs config priority; BUNDLE_IGNORE_CONFIG) new API ok
#749 × #577 manifest::with_lockfile_accepts_only_the_pairs_own_lock (global tier, shadowed by the app config) and ruby_crawler::loaded_manifest_reads_the_global_config_below_local_and_env (bundle config set --global lockfile) new (merge) ok
#749 vendor::gem::a_bundler4_custom_lockfile_is_refused new ok
#749 hosted_memory_engine::a_lockfile_setting_naming_the_default_lock_is_wired (control) ok ok
#751 hosted_memory_engine::a_gemfile_gems_rb_twin_is_refused (1.x, 2.x and mixed stamps) FAILED (wired gems.rb) ok
#751 engine::twin_redirects_nothing_whatever_the_locks_say FAILED ok
#751 engine::twin_with_an_unreadable_spelling_redirects_nothing (memory symlink / non-UTF-8 spelling) FAILED ok
#751 engine::twin_with_an_unreadable_disk_spelling_redirects_nothing (mode-000 gems.rb, non-root) FAILED ok
#751 lock_inventory::tests::gem_inventory_diagnoses_a_lock_it_cannot_read (symlinked twin spellings) FAILED ok
#751 engine::default_discovery_wires_a_lone_gems_rb (control) ok ok
#751 e2e_redirect_gem_build::gem_hosted_twin_redirects_nothing (every Bundler line; checks the untouched twin still installs frozen) FAILED (wired gems.rb, attested) ok (Bundler 4.0.17)
both manifest.rs unit tests (with_lockfile_*, config_lockfile_*) new ok

Local results

  • cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo fmt --all -- --check is not clean on main itself (≈500 diffs, and CI has no fmt gate), so I formatted only the hunks I touched.
  • cargo test --workspace --all-features --lib --bins: the core lib has 4848 passed and 4 failed. All four (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_*) are chmod-based write-failure tests that can't fail writes when run as root (uid 0) in this sandbox. They don't touch gem code.
  • Integration tests: hosted_memory_engine 33/33, hosted_memory_parity, in_process_vendor and e2e_redirect_gem_stale_install all ok. in_process_redirect has 104 passed and 3 failed, again only the chmod-based write-failure tests (root sandbox).
  • e2e_redirect_gem_build --ignored (real Bundler 4.0.17): new custom-lockfile, dual-boot and gems.rb arms pass.
  • I couldn't run the full cargo test --workspace locally because the sandbox's disk allowance runs out building every integration-test binary. CI runs the full suite.

Merge with main (d502a07)

main gained #577 (Bundler's global config, #621) while this PR was open, and the two overlapped in LoadedManifest. The conflicts are resolved by keeping both. Because Bundler 4 reads lockfile through Bundler.settings, which includes the global file, with_lockfile now takes the global tier too. Without that, bundle config set --global lockfile custom.lock would have slipped past the #749 guard. BundlerEnv carries the global config path, and #621's call sites use it. After the merge: cargo clippy --workspace --all-features -- -D warnings is clean; the gem/ruby core lib tests (253), crawler_ruby_e2e (26), hosted_memory_engine (34), hosted_memory_parity, in_process_vendor (106), e2e_redirect_gem_stale_install, and real-Bundler e2e_redirect_gem_build --ignored (17) all pass. The full core lib has 5010 passing and the same 4 chmod-based failures from running as root here.

Bugbot follow-up (9e7af6e)

  • Lock-only scans are no longer silent. Since Lock inventory reads only Gemfile.lock, so a gems.rb project's gems.locked is invisible and a stale Gemfile.lock is read instead #736, a gem lock bundler loads but socket-patch can't read (a custom BUNDLE_LOCKFILE, an unsupported BUNDLE_GEMFILE, or a diverging twin) left lock inventory empty with no warning. Inventory now adds a gem_lock_unsupported diagnosis, which scan and the in-memory engine report as a run-level warnings[] entry (documented in CLI_CONTRACT.md). Test: lock_inventory::tests::gem_inventory_diagnoses_a_lock_it_cannot_read (red→green). The hosted_memory_engine refusal tests assert the warning again.
  • An empty BUNDLE_LOCKFILE shadows the tiers below it, as Settings#[] does, so an empty env or app-config value now clears a global custom lock.

Security-review follow-ups (a3d31b9, d44c4fb)

  • Absolute BUNDLE_LOCKFILE on a memory view (a3d31b9). The in-memory engine compared the lockfile against /, so BUNDLE_LOCKFILE: "/Gemfile.lock" passed as the project's own lock and the pair was rewritten. An absolute value there is now UnsupportedLockfile. Test: engine::absolute_bundle_lockfile_redirects_nothing (red→green).
  • Twins no longer trust BUNDLED WITH (d44c4fb). Every default twin is refused, as described under Fix.

Notes / follow-ups

  • The Gemfile lockfile "custom.lock" DSL (issue matrix row 4) is Ruby code the model can't read. Bundler 4.0.17 itself fails frozen installs on that shape before any scan.
  • A BUNDLE_LOCKFILE setting is refused even on Bundler < 4 (which ignores it). That's a conservative, fail-closed choice.

Takeover follow-up (hourly agent run, 2026-10-08)

  • 2cb153f: merges main. Resolved the CLI_CONTRACT.md conflict by keeping main's redirect.patches[] text plus this PR's two gem codes.
  • 42657c6: setup-php pin comment # v2 → # 2.37.2 (zizmor ref-version-mismatch, the same as Label the setup-php pin in ci.yml with its real tag #1118) for the red Audit GitHub Actions check.
  • 95f1894 (Bugbot): the hosted twin refusal also counts a spelling that's symlinked, unreadable or not UTF-8.
  • d00e81f (Bugbot): the same check also asks view.is_file, so an on-disk spelling with a permission-denied read still counts.
  • 2ec14fc (security review): lock inventory's twin check (bundler_loaded_lock_diagnosed_in) fails closed on a memory-view symlinked spelling.
  • On 2ec14fc: ci-ok is green, Bugbot is clean (completed/success), and every review thread is resolved. The only checks still running are the two non-required Windows gradle hosted cells.

🤖 Generated with Claude Code

https://claude.ai/code/session_018ULgrJMQMWEBAsiuprY449

Assisted-by: Claude Code:claude-opus-5-5
Hosted mode wired the wrong gem files in two Bundler layouts, so the
scan reported success (and its VEX attested a patch) while Bundler
installed the unpatched gem or frozen installs failed:

- Bundler 4's custom lockfile (BUNDLE_LOCKFILE, env or .bundle/config)
  was ignored, so the lock Bundler reads was never pinned (#749). A
  lockfile naming anything but the pair's own default lock is now
  refused in hosted (redirect_gem_bundle_lockfile_unsupported) and
  vendored (gemfile_not_loaded) mode before any write.
- A Gemfile + gems.rb twin always followed Bundler >= 2 and wired
  gems.rb, but Bundler 1.x loads the Gemfile (#751). A twin whose locks
  say BUNDLED WITH 1.x is now wired through the Gemfile pair, and twin
  locks that disagree on the major are refused
  (redirect_gem_twin_bundler_versions_diverge).

Assisted-by: Claude Code:claude-opus-5-5
Two host capstones in e2e_redirect_gem_build: a Bundler 4 project with
`lockfile custom.lock` (and a leftover Gemfile.lock) redirects and
attests nothing and still installs frozen (#749), and a Bundler 1.x
Gemfile + gems.rb twin is wired through the Gemfile and a fresh
checkout installs the patched gem (#751). Each skips on the Bundler
line it does not apply to.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 4, 2026 09:53
@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 Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 4, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review at 731f489.

  • CI: 402/402 non-skipped checks green on the current head (9/9 workflows, path-filtered).
  • Bugbot: reviewed 731f489 and found no issues. There are no unresolved review threads.
  • Mergeable: yes, no conflicts with main. The diff is 10 files, all in the gem lane, plus docs and changelog.
  • For the reviewer: look at the LoadedManifest pair model in formats/gem/manifest.rs (the configured BUNDLE_LOCKFILE and the BUNDLED WITH major of a Gemfile/gems.rb twin) and the matching ruby_crawler.rs changes.

Generated by Claude Code

Release notes are written when a release is cut, from the merged PR
log and the code, so PRs no longer edit CHANGELOG.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) removed the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 5, 2026
Resolve the overlap with #577 (Bundler global config, #621): classify
gained the global tier, so with_lockfile takes it too. Bundler 4 reads
`lockfile` through Bundler.settings, which includes ~/.bundle/config,
so `bundle config set --global lockfile custom.lock` is now refused like
the env and app-config spellings instead of slipping past #749's guard.
BundlerEnv carries the global config path; main's positional
bundler_loaded_manifest_with_env call sites move to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ULgrJMQMWEBAsiuprY449
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

coverage (the Linux test gate) failed on the merge commit d502a07. Its one failing target is -p socket-patch-cli --lib. coverage was green on 731f489, before the merge with main.

I can't see which test failed yet. The job log's download URL (productionresultssa5.blob.core.windows.net) is blocked by my sandbox's network policy, and the MCP log tool returns only the last ~5000 of the log's 12022 lines. The CLI lib test section is earlier than that, so the panic isn't in what I can read. The check annotations only carry the exit code.

What I checked locally on d502a07:

  • cargo test -p socket-patch-cli --lib with default features and with --all-features: 835/835 pass.
  • With CI's SOCKET_PATCH_GO_E2E_REQUIRED=1 / SOCKET_PATCH_GO_E2E_VERSION=1.24 (Go 1.24.7): 835/835 pass.
  • The same test binary run as a non-root user: 835/835 pass.
  • This PR doesn't touch crates/socket-patch-cli/src. That code is identical to main's.

Next: the macOS and Windows test legs run the same CLI lib tests on this commit, and I'll use them to tell a real failure from an instrumentation or timing one. If anyone can open the job log (coverage → "Run tests with coverage", search for FAILED), the failing test name and panic would let me fix it directly.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Found it, and this PR doesn't cause it: main is red at 4646693. coverage and test-release test the PR merged into the current main. Both fail on the same two CLI lib tests, and they fail identically on main alone:

  • commands::vex_consumed::tests::hosted_expands_alias_only_copies (vex_consumed.rs:771, assert!(installed.is_empty()))
  • commands::vex_consumed::tests::hosted_reuses_expanded_npm_copies_and_merges_alias_variants (vex_consumed.rs:718, assert_eq!(installed_again, installed))

Cause: the two tests came in with #738 (#356) and assume the name-keyed resolver find_manifest_package_copies_reusing can't see aliased copies. #605 (#601/#603, merged as 4646693) made that resolver probe store entries' bundled trees, so it now returns the aliases, the nested alias and every store peer variant itself. I ran both tests on main with the asserts relaxed:

  • calls == []: Fix agent mode skipping npm-aliased copies (#356) #738's alias expansion is no longer needed.
  • The final paths set is the complete, correct one: {host/…/lp, left-pad(peer@1.0.0), left-pad(peer@1.0.1)} in the first test, and every root, alias, nested-alias and peer copy in the second.

So the behaviour is right and only the tests' premise is stale.

Proposed patch (for main, not this PR):

  • In hosted_expands_alias_only_copies, replace assert!(installed.is_empty()) and assert_eq!(calls, vec[vec[alias.clone()]]) with:
    • installed[&purl] (sorted) equals peers + [alias] (sorted);
    • calls.is_empty();
    • paths == installed[&purl].
  • In hosted_reuses_expanded_npm_copies_and_merges_alias_variants:
    • Expect installed_again[&purl] to already contain nm/lp, host/node_modules/lp and the nested peers.
    • Replace calls.len() == 1 / the alias-inputs check with calls.is_empty().
    • Keep the final sorted-set and canonical-uniqueness assertions.
    • The earlier nm/lp step (calls == [[alias]]) needs the same update if the resolver also finds that alias. On main it currently doesn't fail first, so check it when applying.

I'm not adding this to #768. It's in code unrelated to the gem change, and no fix for it is open yet. Once main is green, I'll merge it into this branch and re-run CI.


Generated by Claude Code

#605 taught the name-keyed npm resolver to probe bundled store
trees, so it now finds aliased copies (node_modules/lp) and a nested
host's store peers itself. Two vex_consumed tests from #738 assumed
that set never held aliases, so main's CI went red after both merged.

The tests now feed the alias-free set explicitly to keep covering
alias expansion, and also check the resolver's own set reaches the
same copies with no duplicates. No production code changes.

Assisted-by: Claude Code:claude-opus-5-5
(cherry picked from commit 40dac07)
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Burn-down agent: pushed 8c2ba59.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


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 Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 5, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator Author

Burn-down agent: labeled Ready for review.


Generated by Claude Code

@mikolalysenko Mikola Lysenko (mikolalysenko) removed the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 5, 2026
Conflicts resolved:
- ruby_crawler.rs: kept this branch's BundlerEnv and main's (#736)
  bundler_loaded_manifest_in / bundler_loaded_lock_in. The memory branch
  of bundler_loaded_manifest_in now also layers BUNDLE_LOCKFILE
  (with_lockfile), and bundler_loaded_lock_in follows the #751 twin rule
  (Gemfile.lock for a bundler-1.x twin, no lock for a twin whose locks
  disagree on the major), so the lock readers main routed through it
  (inventory, ledger recovery, VEX) agree with the pair the rewriter wires.
- hosted/engine.rs: keep_bundler_loaded_gem_files uses main's shared
  resolver plus this branch's twin/lockfile handling.
- vex/discover/gem.rs: the "no loaded lock" diagnostic no longer blames
  only BUNDLE_GEMFILE.
- CLI_CONTRACT.md: both texts (main's Gradle confirmation sentence and this
  branch's new gem refusal codes).
- e2e_redirect_gem_build.rs: both sets of Driver variants.
- hosted_memory_engine.rs: both sets of tests. Since #736 the memory
  engine finds gem candidates only through the lock bundler loads, so a
  custom BUNDLE_LOCKFILE or a twin with diverging bundler majors yields
  no gem candidate (same as an unsupported BUNDLE_GEMFILE on main); those
  two tests now assert nothing is redirected/written, and the refusal
  warnings are covered by new engine unit tests.

Co-Authored-By: Claude <noreply@anthropic.com>
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
@mikolalysenko
Mikola Lysenko (mikolalysenko) removed this pull request from the merge queue due to a manual request Oct 8, 2026
Resolve hosted/engine.rs: keep main's undecodable_reads retain (#724)
alongside this PR's twin-manifest-ambiguous gem refusal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Audit GitHub Actions (zizmor) is red on e029d70, but the cause is outside this PR. The finding is ref-version-mismatch at .github/workflows/ci.yml:1400: shivammathur/setup-php@f3e473d… # v2. Upstream has moved the v2 tag to 7d671baa1068, so the # v2 comment no longer matches the pinned SHA. f3e473d is tag 2.37.2. This PR doesn't touch .github/.

The same failure appeared at the same time on unrelated branches (arch-refactor/905-bom-sites, agent/fix-bun-open-issues). It passed on main 829d0af at 06:14Z, before the tag moved. The check isn't among ci-ok's needs, so it doesn't block the merge.

I found no fix PR. The proposed one-line patch matches the comment composer-compatibility.yml:115 already uses:

-        uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
+        uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2

I'm not re-running the check, because it will fail the same way until that line changes on main.


Generated by Claude Code

Resolves the CLI_CONTRACT.md conflict by keeping main's new
redirect.patches[] text and this branch's two gem warning codes.

Assisted-by: Claude Code:claude-opus-5-5
Upstream moved setup-php's v2 tag, so the "# v2" comment on the
2.37.2 commit pin now fails the Audit GitHub Actions check
(ref-version-mismatch). Same change as #1118.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] Took this PR over because its heartbeat was stale (03:28Z), the head conflicted with main, and the Audit GitHub Actions check was red on e029d70. Pushed 42657c6:

  • 2cb153f: merges main. The only conflict was the scan --mode hosted paragraph in CLI_CONTRACT.md, resolved by keeping main's redirect.patches[] text plus this PR's redirect_gem_bundle_lockfile_unsupported / redirect_gem_twin_manifest_ambiguous codes.
  • 42657c6: relabels the setup-php pin comment # v2 to # 2.37.2 (zizmor ref-version-mismatch, since upstream moved v2). This is the same one-line change as Label the setup-php pin in ci.yml with its real tag #1118, and it no-ops once that lands.

Local checks: cargo clippy --workspace --all-features -- -D warnings is clean; core lib gem/ruby/manifest/lock_inventory tests pass (684); hosted_memory_engine (37) and e2e_redirect_gem_stale_install (33) pass. CI and Bugbot are pending on the new head.


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.

Comment thread crates/socket-patch-core/src/hosted/engine.rs
A Gemfile + gems.rb twin whose other spelling is a symlink, an
unreadable file or not UTF-8 was not seen as a twin by hosted mode,
so the readable pair was still pinned although Bundler 2+ loads
gems.rb. Lock inventory already counted such a twin and warned
gem_lock_unsupported, so the scan both warned and rewrote. The twin
check now counts every spelling Bundler sees, readable or not.

Found by Bugbot on #768.

Assisted-by: Claude Code:claude-opus-5-5
@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.

Comment thread crates/socket-patch-core/src/hosted/engine.rs
Comment thread crates/socket-patch-core/src/crawlers/ruby_crawler.rs Outdated
A Gemfile + gems.rb twin whose second spelling is a regular file the
scan cannot read (permission denied, I/O error) left no trace in the
read lists, so hosted mode still pinned the readable pair. The twin
check now also asks the project view whether the file exists, the
same File.file? test lock inventory uses.

Found by Bugbot on #768.

Assisted-by: Claude Code:claude-opus-5-5
Hosted file-set scans see a git symlink Gemfile or gems.rb as a
symlink marker with no target. Lock inventory took that as absent, so
a Gemfile + gems.rb twin was inventoried from the regular spelling's
lock with no gem_lock_unsupported warning, although Bundler follows
the link and may load the other pair. The twin check now fails closed
on a symlinked spelling.

Found by the security review on #768.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

Comment thread crates/socket-patch-core/src/crawlers/ruby_crawler.rs Outdated

@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 2ec14fc. Configure here.

@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 8, 2026
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit e2d9633 Oct 8, 2026
442 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-gem-loaded-pair-model branch October 8, 2026 11:28
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Oct 8, 2026
Resolve two CLI_CONTRACT.md conflicts by keeping main's new text (the
atomic vendored-to-hosted takeover wording from #1039 and the
gem_lock_unsupported warning from #768) while re-applying this PR's
migration away from the removed spellings: `scan --apply` becomes
`scan --mode agent`, and `--apply`/`--vendor` in the lockfile
supplement become agent mode / vendored mode.

Co-Authored-By: Claude <noreply@anthropic.com>
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

3 participants