Repository navigation
Bug hunt ledger: Bundler (RubyGems) #316
Replies: 33 comments
|
[agent] 2026-09-30: Bundler (RubyGems) bug-hunt run This is the first run, so the ledger started empty and there were no Tested: main Setup: the sandbox can't reach the Socket patch API. I used a temporary, uncommitted copy of Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-09-30: Bundler (RubyGems) bug-hunt run Tested: main Setup: a temporary, uncommitted copy of Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-01: maintainer note: test global ( This is a maintainer request, not a run report. Add it to the top of the backlog and keep it there until the cells below are covered. Ask: make sure we correctly scan global installs when Where Bundler (RubyGems) puts global installs: What to check (prove each with a real global install, not by reading source):
Add OS × Bundler (RubyGems) version cells for |
|
[agent] 2026-10-01: Bundler (RubyGems) bug-hunt run Tested: main Setup: for agent and Re-triage
Cells (global mode, maintainer checklist)Probe run: https://github.com/SocketDev/socket-patch/actions/runs/36816092864 (ubuntu, macos and windows × Ruby 2.7 / 3.3 / 3.4).
Other cells
Issues
False positives ruled out
Blocked
Next
|
|
[agent] 2026-10-01: handover from the Composer bug-hunt routine (lead, unverified for gem) While I was confirming #438 (Composer, Windows), the root cause turned out to be Composer evidence: #438 and the probe run https://github.com/SocketDev/socket-patch/actions/runs/36827949605 |
|
[agent] 2026-10-01: Bundler (RubyGems) bug-hunt run Tested: main Setup: a hold-open copy of Re-triage
Cells
Issues
False positives ruled out
Blocked
Next
|
|
[agent] 2026-10-01: Bundler (RubyGems) bug-hunt run Tested: main Setup: a copy of Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: Bundler (RubyGems) bug-hunt run Tested: main Setup: uncommitted probe tests added to a copy of Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: Bundler (RubyGems) bug-hunt run Tested: main Setup: uncommitted probes in copies of Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: Bundler (RubyGems) bug-hunt run Tested: main Setup: uncommitted probe tests in a copy of Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] Janitor: ledger drift. The coverage matrix still lists these issues as
This is a heads-up only. The janitor never edits ledgers. Generated by Claude Code |
|
[agent] Janitor: ledger drift. This ledger still lists these issues as failing, but they are now closed:
Please re-check them and update the matrix on your next run. Generated by Claude Code |
|
[agent] 2026-10-02: Bundler (RubyGems) bug-hunt run Tested: main Setup: a ~30-line Python mock of the patch API serving Re-triage
Cells
Issues
False positives ruled out
Probe branches
Next
|
|
[agent] 2026-10-03: Bundler (RubyGems) bug-hunt run Tested: main Setup: a temporary Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-04: Bundler (RubyGems) bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-04: Bundler (RubyGems) bug-hunt run Tested: main Re-triage
Cells (new focus: mode takeovers, never covered before)
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-04: Bundler (RubyGems) bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-04: Bundler (RubyGems) bug-hunt run Tested: main Setup (new, reusable): a Python mock ( Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-05: Bundler (RubyGems) bug-hunt run Tested: main Setup (re-created this run): two small Python mocks around real Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-05: Bundler (RubyGems) bug-hunt run Tested: main Setup: I re-created run 19's Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] Janitor: ledger drift. This ledger was last updated on main
Please re-verify those cells on main Generated by Claude Code |
|
[agent] 2026-10-05: Bundler (RubyGems) bug-hunt run Tested: main Setup: re-created Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-05: Bundler (RubyGems) bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-06: Bundler (RubyGems) bug-hunt run Tested: main Setup (no mock API needed): agent mode driven by a hand-written Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-06: Bundler (RubyGems) bug-hunt run Tested: main Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] Janitor: state drift for the bug-hunt routine to pick up (this ledger body is not edited). #709 (gem VEX ignoring an out-of-tree bundle path) was closed as completed by PR #712 (merge Generated by Claude Code |
|
[agent] 2026-10-06: Bundler (RubyGems) bug-hunt run Tested: main Setup (no mock API): agent cells use a hand-written Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-06: Bundler (RubyGems) bug-hunt run Tested: main Setup: the same as run 25. Agent cells use a hand-written Re-triage
Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-07: Bundler (RubyGems) bug-hunt run Tested: main Setup: throwaway copies of Re-triage
Cells
Issues
False positives ruled out
Next
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
[agent] Progress ledger for the scheduled Bundler (RubyGems) bug-hunt routine (label pm:bundler).
Last updated: 2026-10-07 (run 27), main
9c43dfc(includes #637, #621, #797, #805, #849, #731, #750, #712), latest release tag v4.0.0. Newest Bundler tested: 4.1.0.beta1 (repo gem e2e suites pass).Coverage matrix
Cells are "pass", "fail #N" or "untested". Hosted and vendored cells use a local mock of the patch API (the sandbox blocks the real one) around real
gem buildfixtures, followed by a realbundle installon a fresh checkout. The repo's own e2e suites (e2e_redirect_gem_build.rs,e2e_vendor_gem_build.rs,e2e_redirect_gem_stale_install.rs) already cover the plain single-line Gemfile cells across 1.17 → 4.x. This ledger tracks what they don't.setupand the Bundler plugin were removed in v5 (#277), so those columns are retired (the last results were 2.2–2.4 fail #389 → closed, and 2.5 / 4.x pass).Project modes
ifmodifiergroupblockBUNDLE_GEMFILEin.bundle/configGemfileonlygems.rb+GemfiletwinBUNDLE_GEMFILEgems.rbonlyvexHosted unwind (
rollback/remove, v5 upstream restore; real rubygems.org upstream)~>)groupblock + optionsOther hosted shapes (run 4)
gemspecproject (PATH)Declaration and cache shapes (run 5, hosted, Linux, Ruby 3.3.6)
eval_gemfiledeclarationgem gvendor/cacheguardcache_patheval_gemfileBUNDLE_GEMFILEenv vs.bundle/config(run 6, Linux, Ruby 3.3.6)Gemfile.next+ envGemfileGemfile.nextGemfile.nextVendored declaration shapes and lifecycle (run 7, Linux, Ruby 3.3.6)
ifmodifiergroup+platforms:gem(...)--revertbyte-exactRun 8 (Linux, Ruby 3.3.6)
groupblocksgroupdupgemspectransitiveBUNDLE_CACHE_PATHBUNDLE_APP_CONFIG+Gemfile.nextsource … do/platforms:/install_if/group:/ quotesBundler global config tier (run 9, Linux, Ruby 3.3.6)
cache_path(~/.bundle/config)cache_path(BUNDLE_USER_CONFIG)gemfile Gemfile.nextpathRun 10 (agent mode, Bundler project on system gems,
colorize@0.8.1mock patch)scan/get/vex/rollback, path with a spaceBUNDLE_PATH+ local configpathRun 11 (hosted, git-sourced declarations, Linux, Ruby 3.3.6)
git_sourcekeygitlab:"git" =>"github" =>Run 12 (Linux, Ruby 3.3.6)
git_sourcegemmirror.allin.bundle/config, no CHECKSUMSmirror.all, CHECKSUMS lockRun 13: hosted lifecycle on more shapes (mock patch API + registry, real rubygems.org upstream)
gems.rbredirect → install →rollback→ frozen installGemfile+gems.rbtwin unwindremovepurl / uuid (CRLFgems.rb)~>/group+ optsZenTest), 2-constraint declpathoutside the project (stale guard + VEX)Gemfiletoo)D:/…)Gemfiletoo)Controls for #709 (Linux, 4.0.17): config
pathrelative, configpathabsolute inside the project, envBUNDLE_PATHabsolute outside the project, andpath.system: trueall pass (stale warning;vexrefusesnot_applied).Run 14: stale-install warning flavor and
BUNDLE_IGNORE_CONFIG(Linux, Ruby 3.3.6)--cwdomitted /.../proj--cwdBUNDLE_IGNORE_CONFIG+ configpath vendor/bundlevex, same shapeRun 15: Bundler 1.17 / 2.2 / 2.3 hosted, custom lockfiles, odd files
Gemfileonlygems.rbonlyGemfile+gems.rbtwinlockfile/ envBUNDLE_LOCKFILEGemfile.lock→ pre-installvexAlso on 4.0.17: BOM
Gemfilepasses; symlinkedGemfile/ lock is refused (pass);--dry-runwrites nothing (pass).Run 16: mode takeovers (Linux, Ruby 3.3.6; OS-independent logic)
scan --mode vendored,groupdeclget --mode vendored,groupdeclvendoreject,groupdeclscan --mode hostedremove→ hosted)Run 17: vendored
repair, custom lock, standalone installs (Linux, Ruby 3.3.6)repair(corrupt / missing file / missing dir / extra file)lockfile custom.lockapply+vexonbundle install --standaloneRun 18: multi-gem hosted lifecycle and takeover (Linux, Ruby 3.3.6, real rubygems.org upstream)
rollback1 of 3, then allRun 19: single-line declaration shapes, deployment config, 2.6.9 suites (Linux, Ruby 3.3.6, real rubygems.org upstream)
# commentgem(...)y; gem "x"(patched 2nd)gem "x"; gem "y"(patched 1st)gem "x", opt; gem "y"gem "x"; gem "y"BUNDLE_DEPLOYMENTconfigvex: staleruby/<old ABI>scopegems.rb, and PR #637)Run 20 (Linux, Ruby 3.3.6, real rubygems.org upstream; plus a macOS/Windows global-mode probe)
gem "x", "1"; # c/# …; gem "y"in a commentgroup … do gem … end/gem %q(x)*V/ENV.fetch(…)/ tab /:require =>/platforms: [...]/group: [...]/"x" ,rollbackof those shapes=begin/heredoc/__END__gem "x-y", path:next to the patchedgem "x"BUNDLE_GEMFILE(6 spellings)*V/ENV.fetch(…)/CONST, require: false;now refused since #637, comment)redirect_gem_declaration_not_visible)declared_more_than_once);refused);refused)Run 21 (main
0d302dc; Linux Ruby 3.3.6 unless noted; real rubygems.org upstream)Gemfileandgems.rbpath:gem) /groupblock / CRLFGemfile, thenrollback→ frozen installPLATFORMS=x86_64-linuxonlygem(...), trailing# … if …, 2 constraints,%i[],"#{…}",!=,!true,group:+require:)gem "x", "1";/gem "x", "1"; # crollbackafter a userbundle updateof another gem--standaloneinstall (./bundle)path)CONST/*%w[]/*EXTRA/**OPTS/ two constants (after #849)uri 0.13.1), system gemsRun 22 (main
9c43dfc; Linux Ruby 3.3.6 unless noted; real rubygems.org upstream)rollback→ frozen installgems.rb+ staleGemfile.locktwin (#736 fix) + rollbackgit … do/path … do/git:(#652 fix)BUNDLE_GEMFILE= project Gemfile via symlinked dir (env /--cwd/ config);vex/rollback/tmp, ubuntu-latest)gem "x", "1"; gem "y"(bare 2nd gem)Run 23 (main
9c43dfc; Linux Ruby 3.3.6; agent mode, hand-written manifest +apply --offline)path.system: true+ leftovervendor/bundle:apply/vexBUNDLE_PATH__SYSTEM=true+ leftovervendor/bundlepath.system: true, no leftover (control)Run 24 (main
9c43dfc; Linux Ruby 3.3.6; Bundler 4.1.0.beta1)apply --offline+vex, unquotedBUNDLE_PATH: vendor/my bundle(4.1 config spelling).bundle/config(BUNDLE_PATH/GEMFILE/CACHE_PATH/PATH__SYSTEM)mirror.<patch source>quoted key vs PR #684Run 25 (main
9c43dfc; Linux Ruby 3.3.6; agentapply --offline+vexwith a hand-written manifest, realbundle install/bundle exec).bundle/configBUNDLE_PATH: .gems # comment(system copy also present)BUNDLE_PATH: .gemscontrolBUNDLE_CACHE_PATH: vendor/gems # comment+ stale archive (e2e harness case)BUNDLE_GEMFILE=gemfiles/alt.gemfile,path vendor/bundleingemfiles/.bundle/configBUNDLE_GEMFILE=gemfiles/alt.gemfile+ envBUNDLE_PATH=vendor/bundle(relative)Run 26 (main
9c43dfc; Linux Ruby 3.3.6; agentapply --offline+vex, realbundle install/bundle exec).bundledefault path (localsimulate_version 5on 4.x /default_install_uses_path trueon 2.x)BUNDLE_SIMULATE_VERSION=5/BUNDLE_DEFAULT_INSTALL_USES_PATH=true)52542dbon the #951 agent shapeRun 27 (main
9c43dfc; Linux Ruby 3.3.6;gemspeclibrary projects)redirect_gem_declaration_not_visible)gemline → fresh frozen installgemline → fresh frozen installgemline → fresh frozen installGlobal mode (
-g)scan -greport-gvs project scopingscan -g --mode hostedrefusedget -g/apply -grollback -gbyte-exactvex -g--global-prefix <gems dir>/SOCKET_GLOBAL=1Permission denied)--user-install)/Library/Ruby/Gemspartial_failure, nothing written)partial_failure, exit 1)-ginside a project leavesvendor/bundlealone)--global-prefix-ginside a Bundler projectGEM_HOME=~/.gem/ruby/<v>)@app+@globalgemsets, incl. a shadowing gemset copy)partial_failure, nothing written)-ginside a projectvendor/bundleuntouched)Backlog
mirror.allsetting, so the nextbundle installfetches the redirected gem's upstream bytes from the mirror while the in-run VEX attestsnot_affected#681 / Hosted gem stale-install warning calls the project's ownvendor/bundlea "shared gem home" when--cwdis left at its default (or relative), so it gives the wrong remedy and drops the committed cache archive from the delete list #729 / Hosted gem redirect ignores Bundler 4's custom lockfile (lockfilesetting /BUNDLE_LOCKFILE), so it never pins the lock Bundler uses and frozen installs fail with no warning #749 / Hosted gem redirect wiresgems.rbin a Gemfile/gems.rb twin locked by Bundler 1.17, which loadsGemfile, so the install stays unpatched while the in-run VEX attests it #751 / Gem hosted → vendored takeover un-hosts a gem declared inside agroupblock and then refuses to vendor it (gemfile_declaration_not_editable), so the project silently goes back to unpatched #775 / Gem hosted and vendored rewrites delete a secondgemdeclaration that shares the patched gem's line after;, so the nextbundle installdrops that dependency #826 / GemBUNDLE_GEMFILEcheck compares paths lexically, so a symlinked spelling of the project's own Gemfile (e.g. macOS/tmp/app/Gemfile) is refused, andvex/rollbackreject the hosted patch Bundler is loading #896 / Gem crawler ignores Bundler'spath.system: truewhen a leftovervendor/bundleexists, so agentapplypatches the unused copy andvexattestsnot_affectedwhile Bundler loads the unpatched system gem #915 / Gem.bundle/configreader keeps a trailing# commentin the value, so a commentedBUNDLE_PATHis missed, agentapplypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatched project copy #951 / Gem agent crawl ignores thatBUNDLE_GEMFILE=gemfiles/x.gemfilemovesBundler.root, so a relative bundle path resolves to the wrong dir,applypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatchedgemfiles/vendor/bundlecopy #952 / Gem crawler ignores Bundler's.bundledefault install path (default_install_uses_pathon 2.x,simulate_version 5on 4.x), so agentapplypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatched.bundle/ruby/<abi>copy #967 / Gem hosted and vendored lock pins ignore a gemspec development dependency on the same gem, so on Bundler 2.7+ the rewritten Gemfile.lock fails every frozen install ((= v)!vs Bundler's merged(>= 0, = v)!) #985 when fixes merge (open PRs Fix hosted gem redirect ignoring Bundler mirror.all (#681) #684, Fix gem pair model ignoring custom lockfile and Bundler 1 twins (#749, #751) #768, Fix gem takeover un-hosting a grouped gem (#775) #776, Fix gem rewrite deleting a;-joined declaration (#826) #875, Fix gem crawl ignoring Bundler path.system (#915) #916, Fix .bundle/config values keeping a trailing # comment (#951) #953). Fix gem rewrite deleting a;-joined declaration (#826) #875 head5b9953d3already passes every Gem hosted and vendored rewrites delete a secondgemdeclaration that shares the patched gem's line after;, so the nextbundle installdrops that dependency #826 shape. Fix .bundle/config values keeping a trailing # comment (#951) #953 head52542dbfixes the Gem.bundle/configreader keeps a trailing# commentin the value, so a commentedBUNDLE_PATHis missed, agentapplypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatched project copy #951 agent shape. Fix gem crawl ignoring Bundler path.system (#915) #916 covers theto_boolspellings and the hosted stale guard. Fix gem takeover un-hosting a grouped gem (#775) #776 covers every vendored-refused block shape. Fix hosted gem redirect ignoring Bundler mirror.all (#681) #684 head0e1e6cdamisses 4.1's quoted URL-scoped mirror keys.(= v)!vs Bundler's merged(>= 0, = v)!) #985 neighbours: hostedrollbackon the gemspec dev-dep shape (the exact-pin restore may then fail frozen installs),get <uuid> --mode hosted, and H→V takeover on that shape..bundledefault install path (default_install_uses_pathon 2.x,simulate_version 5on 4.x), so agentapplypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatched.bundle/ruby/<abi>copy #967 neighbours: the hosted stale guard with a stale.bundle/ruby/<abi>copy;rollbackundersimulate_version 5; other Bundler 5-mode defaults socket-patch models. When Bundler 5 ships,.bundlebecomes the plain default, so re-run everything there.BUNDLE_GEMFILE=gemfiles/x.gemfilemovesBundler.root, so a relative bundle path resolves to the wrong dir,applypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatchedgemfiles/vendor/bundlecopy #952 neighbours: underBUNDLE_GEMFILE=gemfiles/x.gemfile, checkcache_pathingemfiles/.bundle/configfor the hosted stale guard andvex, and the envBUNDLE_APP_CONFIGrelative to the moved root..bundle/configparser divergences from Bundler'sYAMLSerializer:KEY:"v"with no space, a value with trailing spaces after the closing quote,#inside a quoted value. All contrived, so low priority.gems/<name>-<ver>-<hex8>): revisit when a gem is published that way.x64-mingw-ucrtplatform gems in hosted and vendored modes; vendored cells andrepairon Windows and macOS.rollback/removeon a custom-lock project.Known non-bugs
patches-api.socket.dev/api.socket.devare blocked from the sandbox. Use a local mock API (--api-url,--api-token fake --org org). A ~60-line Python mock serving/v0/orgs/org/patches/{batch,view/<uuid>,by-package/…}withblobContentis enough for agent and-gflows; for hosted, use a hold-open copy ofe2e_redirect_gem_build.rs.--vendor-source buildis gone). To drive vendored cells, copye2e_vendor_gem_build.rs(itsprebuilt_commonfixture serves the artifact) rather than calling the CLI by hand:vendor --offlinewithout a prestaged artifact fails withvendor_service_offline_conflict, which is expected.--global-prefixtakes the package-leaf dir (<gem home>/gems), likenode_modules/site-packagesfor the other ecosystems. Pointing it at the gem home itself scans 0 packages; that's the convention, not a bug.-gagent runs keep their manifest at<cwd>/.socket/manifest.json, androllback -gremoves the entry.vex -gthen needs a freshget -gplus--product(no project to auto-detect from).bundler/gems/<name>-<sha>) isn't crawled in agent mode. Patches target registry bytes, so this is plausibly intended (unconfirmed with the docs).gems.rb-only project can't vendor. It's documented, and the refusal isno Gemfile at …/Gemfile.redirect_gem_no_checksums_section+redirect_gem_frozen_installand needs one unfrozenbundle install. Documented.-x86_64-linux) on a CHECKSUMS-less lock is redirected, and the next install switches to the patched ruby-platform gem. It's intended. With CHECKSUMS it fails closed (redirect_gem_platform_unsupported).bundle install --deploymentexits 15 on Bundler 4 (the flag was removed). UseBUNDLE_DEPLOYMENT=true/--frozen.sourceblock inside agroup … doblock dedents it. Cosmetic.String#untaintwas removed). Use Ruby 2.7 / 3.1 (setup-ruby probe) for 1.x cells.rollback/removerefuse a gem whose upstreamGEMremote isn't rubygems.org (its CHECKSUMS can't be re-derived). To test the restore, use a real rubygems.org upstream with the patch registry mocked on loopback, and pass--patch-server-url <mock>: discovery only trustspatch.socket.devor that origin.rollback, a direct dep's original constraint (~> 1.1) comes back as the exact pin"1.1.0". That's documented in "Hosted unwind coverage".rollbackreportsManifest not found. The pin is Gemfile-only, which is documented as out of the restore's reach.bundle lock --add-checksumsto get the converged shape.^\s*gemmatch). That's cosmetic, androllbackre-derives the layout.git push --deletegets 403 from the git proxy).bughunt/bundler/20261001-global-modeis left behind; its workflow is push-triggered only.scan --vextakes--vex-product, not--product(that'svex's flag). Without either, a gem project fails withproduct_undetected.vendor/cachewith a stale archive still installs unpatched on Bundler 2.4 after the hosted scan. That's documented: theredirect_gem_stale_installremedy says to delete it.require "bundler/setup"(withoutbundle exec) reads only theBUNDLE_GEMFILEenv var, not.bundle/config; the CLI commands (install,lock,exec) let.bundle/configwin. Gem manifest resolution lets theBUNDLE_GEMFILEenv var override.bundle/config, but Bundler does the reverse, so hosted mode wiresGemfilewhile bundler installsGemfile.nextunpatched and VEX attests it #507 is about the CLI order, which decides what gets installed.if/unless), indented (group) and parenthesizedgem(...)declarations withgemfile_declaration_not_editableand writes nothing. That's fail-closed by design, unlike the hosted rewriter (Hosted gem redirect breaks a multi-linegemdeclaration (the Gemfile stops parsing) and drops a trailingif/unlessmodifier #340).BUNDLER_VERSION=<v>alongsideSOCKET_PATCH_BUNDLER_E2E_VERSION=<v>to pick a Bundler older than the Ruby default (2.5.22 on 3.3.6).scanrun from a project subdirectory (or with--cwdpointing at one) scans 0 packages: the cwd is the project root, and there's no walk-up the way Bundler does it.ffi-…-x86_64-linux-gnu) is refused withplatform_gem_unsupported. Documented.source:option (redirect_gem_source_option). With--vexthe scan exits 1 and writes no VEX. That's fail-closed by design.bundle config set <key>without--local/--global, run inside a project, writes the local.bundle/configon Bundler 2.4 / 2.6 / 4.0 (verified in run 9). Only an explicit--globalreaches the global tier (Gem settings resolution skips Bundler's global config (~/.bundle/config/BUNDLE_USER_CONFIG), so a globalcache_pathorgemfilegets no warning or refusal and VEX attests an unpatched install #577).scan -g"0 found" was a "connection refused" race, not a crawler miss.bughunt/bundler/20261002-win-recheckis also left behind (git push --deletegets 403); its workflow is push-triggered only.gem_tail_source_optionmatches substrings, so a symbol such asgroup: :gitlab_ciwould trip the:gitrefusal. It's fail-closed and contrived, so it's not filed.git:,gitlab:, customgit_source) fails closed withapply_failed("GEM specs has no entry"), because the lock check fires before the Gemfile token list matters. It writes nothing, so it's not a Hosted gem redirect treats agitlab:or customgit_sourcegem as patched, so Bundler keeps loading the unpatched git checkout while VEX attestsnot_affected#652 twin.vexstill attests the redirected gem. That's consistent with the "missing files never prove staleness" rule in CLI_CONTRACT.md.get <uuid> --mode hostedfor a version the lock doesn't hold pins (and downgrades to) the patched version, adds a second CHECKSUMS entry, and leaves a mixed pair thatrollback/removecan't see (Manifest not found) until the prescribed unfrozenbundle installconverges it (after that, rollback works). The uuid path is documented as exempt from installed narrowing (run 13).BUNDLE_FROZEN, including the pristine lock. It's Bundler's own behaviour.source … doblock with LF endings (mixed endings). Bundler, frozen installs androllbackaccept it, so it's cosmetic.rollback/removecan be exercised by hand with no Rust harness: a Python mock of the patch API + the patch-registry compact index (rebuild the real.gemwithgem unpack/gem spec --ruby/gem build), with rubygems.org as the real upstream. The run-13 entry describes it; the mock must ignore nothing the CLI checks (registryOverride.identifiers.gemChecksumSha256= the sha256 of the served.gem).bughunt/bundler/20261003-hosted-xosis also left behind (git push --deletehangs up / 403); its workflow is push-triggered only.BUNDLE_IGNORE_CONFIGis not honored when the crawler reads.bundle/configpath(it is forcache_path/gemfile). It's harmless on its own: a non-default config path still gets thegem envhomes appended. The only harmful shape is a populatedvendor/bundlethat bundler doesn't use (agent patches it,vexattests while the system copy loads), and that's the documented "vendor/bundleholds stores, so nogem envhomes" rule; a leftovervendor/bundlewith no config does the same (run 14).npm pack @socketsecurity/socket-patch-linux-x64-gnu@<ver>(package/socket-patch). v4 needs--mode hostedexplicitly.bughunt/bundler/20261004-bundler1is also left behind (git push --deletehangs up); its workflow is push-triggered only.lockfile "x.lock"DSL, Bundler 4.0.17 itself refuses frozen/deployment installs ("requires a lockfile"), even with no socket-patch involvement.starts_with(cwd)sweep (run 15): the only gem-path hits arescan/hosted.rs:218/:423(Hosted gem stale-install warning calls the project's ownvendor/bundlea "shared gem home" when--cwdis left at its default (or relative), so it gives the wrong remedy and drops the committed cache archive from the delete list #729).resolve_config_bundle_pathabsolutizes before comparing.redirect_gem_source_option("carriespath:pointing into .socket/vendor … un-vendor this gem first"), exit 0, nothing written; the gem stays vendored-patched. The remedy (remove <purl>, thenscan --mode hosted) works (run 16). It's fail-safe, so it's not filed even though the contract says takeovers work both ways.crates/socket-patch-cli/tests/that startsprebuilt_common::Server::project_with_env(<root>), writes its URI, and blocks; exportSOCKET_VENDOR_URL. The root needs.socket/manifest.json+ blobs + an unpatched install. Don't let another mock answer/patches/package(→vendor_prebuilt_integrity_mismatch). Delete the scratch file afterwards.vendor/bundle/first, or the patched install travels along (run 16 false alarm).repairdoesn't restore Gemfile / lock wiring the user reverted. It reports success with no events, matching the docs ("preserves project wiring");vexreportsvendor_unwired(run 17).source … dowrites its ownGEMsection): vendored is tracked by Vendored gem refuses a gem whose spec is not in the lock's first GEM section #779 / Read Gemfile.lock sections and DEPENDENCIES entries through formats::gem in hosted and vendored modes #780 (arch audit). Hosted redirects a gem from anyGEMremote; mirrors are legitimate, so that's policy, not a bug.pkill -f/pgrep -fa name that also appears in the same shell command; it kills the agent's own shell (exit 144).--patch-server-url <api mock>is needed so vendored mode recognizes the loopback patch-registry wiring, but it also rewrites artifact download hosts. Have the API mock proxy/artifacts/*(every non-/v0, non-/patch-registryGET) to the prebuilt server, and exportSOCKET_VENDOR_URL=<prebuilt uri>as well.gemfile_declaration_not_editableand writes nothing. The takeover can't see the unconverged hosted wiring, consistent with the documented mixed-state limits (run 18).CARGO_TARGET_DIR; reusing one silently tests the wrong head (run 18 near-miss).scandefaults to hosted mode in v5. An agent probe must pass--mode agent, or it fails with "Failed to resolve patch references" against a mock with no/patches/package(run 19).cargo test --test <t> -- --ignored --include-ignoredprints no results (conflicting flags). Use--include-ignoredalone (run 19).# commenton the patched gem's line. That's cosmetic; vendored does the same and keeps the original in its ledger.vexrefusesnot_appliedwhen any crawled copy (e.g. a leftovervendor/bundle/ruby/<old ABI>scope) is unpatched, even if the live scope is patched. It's fail-safe, so it's not filed (run 19).mock.pyagent,mock2.pyhosted grant + patch-registry compact index, with ETags) are described in the run-19 entry. Each is about 50 lines, and a rebuilt marker gem (gem unpack→ append →gem spec --ruby→gem build) is enough for full hosted cycles against real rubygems.org.get --jsonon an apply that fails (e.g. a root-owned gem dir) reportsstatus: partial_failure, exit 1,applied: 0andfailed: 0:failedcounts download failures only (get.rs:2492-2506), and the reason ("Permission denied (os error 13)") only reaches the human output. That's by design and not specific to gems, so it's not filed (run 20).=begin/=end, a heredoc or after__END__is refused withredirect_gem_declared_more_than_once(nothing written). It's fail-closed, so it's not filed (run 20).rollbackofgem "x", *V/gem "x", ENV.fetch(…)leavesgem "x", "<ver>", *V: the documented exact-pin restore plus the kept argument. The lock is byte-restored and frozen installs pass (run 20).bughunt/bundler/20261005-global-macosis left behind ifgit push --deletefails; its workflow is push-triggered only.cooldownignores versions with nocreated_atand never retracts a locked version, so it doesn't affect a hosted exact pin (checked in the 4.0.22 source, run 21).--standaloneproject says "runbundle install". Plainbundle installthen installs into system gems, and the standalone app fails loudly (LoadError) untilbundle install --standaloneis re-run, which yields the patched copy. That's a remedy wording nit with no silent unpatching, so it's not filed (run 21).rollbackcan leave one extra blank line after thesourceline in the Gemfile. That's cosmetic; the lock is byte-restored (run 21).uri 0.13.1on Ruby 3.3.6) gets a regular installed copy from Bundler 4, so the crawler sees and patches it. Default gems only exist as stdlib files (gems/<name>-<ver>/empty) outside Bundler (run 21). Clean up after agent tests on system gems: they patch the real system copy.icaclsneedsMSYS2_ARG_CONV_EXCL="*", or/denyis converted into a path. A deny-write ACE(OI)(CI)(W,D,DC)on the gem dir also makes Ruby'srequirefail, so it only tests fail-closed behavior. Don't check writability by appending to the gem file (echo >>): it changes the hash and breaks the cell (run 21).bughunt/bundler/20261005-win-rois also left behind (git push --deletehangs up); its workflow is push-triggered only.vexneeds--patch-server-url <mock>too, or it finds no hosted references.vexattests as long as the installed bytes are patched (verified on disk), and refuses oncebundle installre-resolves the lock to upstream (Bundler keeps the patched installed copy, but the reference is gone). That's fail-safe, so it's not filed (run 22).bughunt/bundler/20261005-symlink-gemfileis also left behind (git push --deletehangs up); its workflow is push-triggered only..socket/manifest.json(fileskeyspackage/<rel>, git-sha256beforeHash/afterHash) plus.socket/blobs/<afterHash>by hand and runapply --offline(run 23). Restore a patched system gem withgem pristine <gem> -v <ver>.vendor/bundlewith no config while Bundler uses system gems makes agentapplypatch the unused copy andvexattest. That matches the documented "vendor/bundleholds stores, so nogem envhomes" heuristic and isn't filed; Gem crawler ignores Bundler'spath.system: truewhen a leftovervendor/bundleexists, so agentapplypatches the unused copy andvexattestsnot_affectedwhile Bundler loads the unpatched system gem #915 covers only the explicitpath.systemsignal (run 23).pathtogether withpath.system(ordisable_shared_gems) in the same tier ("Using a custom path while using system gems is unsupported"), so the crawler's handling of that combination can't mislead an install. Only 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 (nopath, leftovervendor/bundle) matters (run 24).parse_dir_name_versionmisparses gem names that contain-<digits>.<…>(32 of 197k rubygems.org names, all obscure, e.g.citus-rails-4.2). Not filed (run 24)..bundle/configwith unquoted values and double-quotes any key containing:(URL-scopedmirror./ credential keys). The keys main reads have no:, and backslash escaping inside quotes predates 4.1 (4.0'sinspectdid it too) (run 24).overrideDSL can't silently unpatch a hosted pin (the pinned source only serves the patched version), and it isn't counted as agemdeclaration (run 24).BUNDLE_PATH: ".gems" # c→"\".gems\"") or by trailing spaces. Bundler itself breaks there, so only the unquotedvalue # commentshape (Gem.bundle/configreader keeps a trailing# commentin the value, so a commentedBUNDLE_PATHis missed, agentapplypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatched project copy #951) is a socket-patch bug (run 25).inspect-written values ("D:\\a\\proj","\u00FC"), and neither does socket-patch, so they agree (run 25).BUNDLE_GEMFILE=gemfiles/x.gemfile, Bundler readsgemfiles/.bundle/configand ignores the root.bundle/config(verified with 4.0.22: the rootpath vendor/bundlewent unused and the gem landed in system gems). setup-ruby'sbundler-cachewrites an absolute$PWD/vendor/bundle, so the crawler's defaultvendor/bundleprobe happens to find it; only relative paths hit Gem agent crawl ignores thatBUNDLE_GEMFILE=gemfiles/x.gemfilemovesBundler.root, so a relative bundle path resolves to the wrong dir,applypatches the system copy andvexattestsnot_affectedwhile Bundler loads the unpatchedgemfiles/vendor/bundlecopy #952 (run 25).mylib.gemspec+lib/into every fresh or scratch checkout; otherwise Bundler aborts with "There are no gemspecs" (a harness artifact, not a bug). A gemspec dev dependency with no Gemfile line is refused by hosted mode (redirect_gem_declaration_not_visible), which is fail-closed by design.All reactions