You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 54bd233
Browse filesBrowse the repository at this point in the historyBrowse files
[agent] 2026-11-15: Bundler (RubyGems) bug-hunt run
2
+
3
+
**Tested:** main `63f791d` (5.1.0; same SHA as the last two runs, so the run went to the backlog). Linux. Ruby 3.3.6 with Bundler 4.0.18, 2.6.9 and 2.5.22; Ruby 3.2.6 with 2.4.19.
4
+
5
+
**Harness:** a `rails new` app (Rails 7.1.6, 81 gems, 8-platform lock, bootsnap boot, `Bundler.require(*Rails.groups)`) with seven mock patches: rack and rails-html-sanitizer (transitive), puma and bootsnap (direct, native), web-console and capybara (in `group … do` blocks), nokogiri (precompiled). The Python mock was rebuilt from the state file's notes; each patched gem is the upstream `.gem` with one Ruby file changed and `checksums.yaml.gz` recomputed.
6
+
7
+
**Re-triage:** main has not moved, so nothing to re-check. #1109 is `agent:needs-human`.
8
+
9
+
**Cells**
10
+
11
+
| Cell | Result |
12
+
| --- | --- |
13
+
| Hosted, Rails app: scan, dev / test boot, frozen install, lock stable, `vex`, deployment clone with `BUNDLE_WITHOUT=development:test`, production boot, rollback, `pristine`| pass on 4.0.18, 2.6.9 and 2.5.22, pair byte-exact; nokogiri refused as documented |
14
+
| Hosted, Rails app: `bundle cache`, then a `--local` deployment install from `vendor/cache`| pass on 4.0.18 (the cache holds the patched archives) |
15
+
| Hosted lock written by one Bundler, installed by another (2.5.22 and 2.6.9 locks on 4.0.18; 4.0.18 lock on 2.5.22): deployment, plain install, `vex`, re-scan | pass (only `BUNDLED WITH` and Bundler's own lines change) |
16
+
| Agent, Rails app with a warm bootsnap cache: scan, boot, frozen install, `apply --check`, `vex`| pass on 4.0.18 |
17
+
| Agent, CI clone with `BUNDLE_DEPLOYMENT` and `BUNDLE_WITHOUT`: `apply`, boot, `apply --check`, `vex`| pass on 4.0.18 (the two group gems are skipped with a note, exit 0) |
18
+
| Agent and hosted common path, 2-gem project | pass on 2.4.19 |
19
+
| Switching agent to hosted |**fail #2089** on 4.0.18 and 2.6.9 (with CHECKSUMS), 2.6.9 and 2.5.22 (without) |
20
+
| Switching hosted to agent: scan, `apply`, `pristine`, `vex`, rollback | pass on 4.0.18 (clear `hosted wiring live` warning, pair byte-exact after rollback) |
| Vendored, group gems rewritten as top-level `gem "x", group: :test`: scan, deployment clone without the groups | pass on 4.0.18 |
23
+
| Vendored then hosted on one project (mixed): frozen install, boot, `vex`| pass on 4.0.18 (6 gems attested) |
24
+
| Mixed vendored + hosted: `rollback`, `remove <vendored purl>`, `vendor --revert`|**fail #2090** on 4.0.18, 2.6.9 and 2.5.22 |
25
+
26
+
**Filed**
27
+
-https://github.com/SocketDev/socket-patch/issues/2089: a hosted scan over an agent-patched project leaves the upstream `.gem` in `vendor/bundle/…/cache` under a lock that pins the patched sha256, with no warning. `bundle pristine` / `--redownload` exit 37, remove the gem, and every later `bundle install` exits 37 too. Without CHECKSUMS they reinstall the unpatched gem.
28
+
-https://github.com/SocketDev/socket-patch/issues/2090: reverting a vendored gem while another gem is hosted puts its spec into the hosted gem's `GEM` section (`record_gem_section` takes the first one). A fresh `bundle install` exits 7 and `rollback` then refuses both gems. `remove` exits 0 while doing it.
29
+
-https://github.com/SocketDev/socket-patch/issues/2091 (`ux`): on the stock Rails Gemfile vendored mode fails 5 of 7 gems and no error names a remedy; top-level `group:` and `--mode hosted` both work.
30
+
31
+
**Commented / closed:** nothing.
32
+
33
+
**Ruled out**
34
+
-`vex` in a CI clone that leaves out `development:test` attests the hosted group gems from the lock pin. Already listed (documented rule).
35
+
- A hosted lock installed by another Bundler gets a new `BUNDLED WITH` (and 2.5.22 drops the `bundler` CHECKSUMS line of a 4.0 lock). That is Bundler.
36
+
- After agent to hosted, `list` shows each gem twice (manifest record and hosted pin) and step 2 says to reinstall. Noted in #2089, not filed separately.
37
+
-`rollback` after agent to hosted (without a `pristine` in between) restores the pair, the files and the manifest.
Copy file name to clipboardExpand all lines: known-non-bugs/bundler.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -165,3 +165,6 @@ Documented limitations and verified false positives. One bullet each. Search thi
165
165
-`scan --mode vendored` over a hosted project with a native gem exits 1, vendors the pure-Ruby gems and leaves the native one hosted. Documented refusal (`native_extensions_unsupported`); the mixed state lists, attests and rolls back correctly (2026-11-14).
166
166
-`gem "x", force_ruby_platform: true`, or `bundle config set force_ruby_platform true` plus `bundle lock` over the existing lock, keep every platform variant in a Bundler 4.0.18 lock, so hosted mode still refuses the gem (`redirect_gem_platform_unsupported`). Only a new lock or `bundle lock --remove-platform` gives a `ruby`-only lock. Bundler's behavior, documented refusal; the `vex` problem after the switch is #2087 (2026-11-15).
167
167
- Hosted `rollback` / `remove` without `--gem-refresh-shared` leave the patched copy in a shared gem home and warn. That part is documented; the remedy that fails afterwards is #2086 (2026-11-15).
168
+
- A hosted lock installed by a different Bundler than wrote it changes only `BUNDLED WITH` (and Bundler 2.5.22 drops the `bundler` CHECKSUMS line of a 4.0 lock); the hosted sections, the patched installs and `vex` are unaffected. That is Bundler (2026-11-15).
169
+
- Vendored mode refusing `group … do` gems, native-extension gems and precompiled platform gems on a Rails Gemfile is by design (#340); only the missing remedy in the messages is filed (#2091). Top-level `gem "x", group: :test` is accepted (2026-11-15).
170
+
-`scan --mode agent` over a hosted project keeps the hosted wiring and warns ("left the hosted wiring live"); `apply` reports the copies as already patched. By design (2026-11-15).
Copy file name to clipboardExpand all lines: state/bundler.md
+11-11Lines changed: 11 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,18 @@
1
1
[agent] Progress ledger for the scheduled Bundler (RubyGems) bug-hunt routine (label pm:bundler).
2
2
3
-
Last run: 2026-11-15, main `63f791d`, release 5.1.0, newest Bundler 4.0.24 stable and 4.1.0.beta3 prerelease (tested so far: 2.3.27, 2.4.19, 2.5.22/23, 2.6.9, 4.0.18, 4.0.24, 4.1.0.beta3). Ruby 3.1.6, 3.2.6 and 3.3.6.
3
+
Last run: 2026-11-15, main `63f791d`, release 5.1.0, newest Bundler 4.0.24 stable and 4.1.0.beta3 prerelease (tested so far: 2.3.27, 2.4.19, 2.5.22/23, 2.6.9, 4.0.18, 4.0.24, 4.1.0.beta3). Ruby 3.1.6, 3.2.6 and 3.3.6. Second run of 11-15.
4
4
5
5
The ledger was reset on 2026-11-13. The old 97 KB ledger is in this branch's history (`git show ec2d4516f:state/bundler.md`); search it with `git grep`, don't copy it back.
6
6
7
-
Harness notes: the sandbox reaches rubygems.org but not the Socket patch API. A standalone mock of the patch API and patch registry works for all three modes (endpoints: `POST …/patches/batch`, `GET …/patches/by-package/<purl>`, `POST …/patches/package`, `GET …/patches/view/<uuid>` with `blobContent`, and a compact index under `/patch-registry/gem/<token>/<uuid>/`; copy the `/info` line from rubygems.org and swap the checksum). Build the patched gem by repacking the upstream `.gem` with its `metadata.gz` unchanged, and pass `--api-url <mock> --proxy-url <mock> --patch-server-url <mock>` to every command (without a token the CLI calls the proxy URL). For vendored mode the grant's `tarball` artifact needs `integrity.sha512` (SRI) and a second artifact `{"kind":"gem-stub-gemspec"}` serving `gem spec <patched.gem> --ruby`. Give test repos a `**/vendor/bundle/` ignore line. `--api-token fake --org test` works in place of the proxy route. For a gem with precompiled builds, `nokogiri 1.16.0` compiles from source in under a minute here. rbenv Rubies are in `/opt/ruby-3.1.6` (Bundler 2.3.27, 2.6.9), `/opt/ruby-3.2.6` (2.4.19, 4.0.18), `/opt/ruby-3.3.6` (2.5.22, 4.0.18); `gem install bundler -v 4.0.24` / `4.1.0.beta3` works there.
7
+
Harness notes: the sandbox reaches rubygems.org but not the Socket patch API. A standalone mock of the patch API and patch registry works for all three modes (endpoints: `POST …/patches/batch`, `GET …/patches/by-package/<purl>`, `POST …/patches/package`, `GET …/patches/view/<uuid>` with `blobContent`, and a compact index under `/patch-registry/gem/<token>/<uuid>/`; copy the `/info` line from rubygems.org and swap the checksum). Build the patched gem by repacking the upstream `.gem` with its `metadata.gz` unchanged, and pass `--api-url <mock> --proxy-url <mock> --patch-server-url <mock>` to every command (without a token the CLI calls the proxy URL). For vendored mode the grant's `tarball` artifact needs `integrity.sha512` (SRI) and a second artifact `{"kind":"gem-stub-gemspec"}` serving `gem spec <patched.gem> --ruby`. Give test repos a `**/vendor/bundle/` ignore line. `--api-token fake --org test` works in place of the proxy route. For a gem with precompiled builds, `nokogiri 1.16.0` compiles from source in under a minute here. rbenv Rubies are in `/opt/ruby-3.1.6` (Bundler 2.3.27, 2.6.9), `/opt/ruby-3.2.6` (2.4.19, 4.0.18), `/opt/ruby-3.3.6` (2.5.22, 4.0.18); `gem install bundler -v 4.0.24` / `4.1.0.beta3` works there (2.6.9 on 3.3.6 too). A patched gem can also be made without Ruby: copy the upstream `.gem`, change one file in `data.tar.gz` and recompute `checksums.yaml.gz`. A realistic project: `gem install rails -v 7.1.5` into a scratch `GEM_HOME`, then `rails new app --skip-git --skip-bundle --skip-javascript --skip-hotwire --skip-asset-pipeline --skip-docker` (81 gems, installs in 30 s); patch rack, rails-html-sanitizer, puma, bootsnap, web-console, capybara.
8
8
9
9
## Coverage matrix
10
10
11
11
Linux only. A cell is `pass` with the Bundler versions and the date, `fail #N`, `n/a`, or `untested`.
| Common path: scan, patch, fresh `bundle install`, app loads patched code, `vex`, rollback, `bundle install` again | pass 2.4.19, 2.5.22, 2.6.9, 4.0.18; Rails 7.1 app with bootsnap and a CI clone without groups on 4.0.18 (11-15) | pass 2.5.22, 2.6.9, 4.0.18, 4.1.0.beta3, CRLF pair too (11-15); `vex` warning fail #2076; on a Rails Gemfile 5 of 7 gems are refused with no remedy, fail #2091| pass 2.3.27 to 4.0.24, 4.1.0.beta3 (11-14); Rails 7.1 app on 2.5.22, 2.6.9, 4.0.18, cross-Bundler installs and `bundle cache` too (11-15) |
16
16
| System or user gem home (no `BUNDLE_PATH`) | pass 4.0.18, 2.5.22 with `GEM_HOME` (11-15) | fail #2075 (2.6.9, 4.0.18) | pass 4.0.18: warning, `scan` and `rollback` with `--gem-refresh-shared` (11-15); the remedy after a plain rollback / remove fail #2086|
17
17
|`bundle config set path vendor/bundle`| pass 2.6.9 (11-13) | pass 4.0.18 (11-14) | pass 2.3.27 to 4.0.18 (11-14) |
18
18
| Deployment and frozen installs (`BUNDLE_DEPLOYMENT`, `BUNDLE_FROZEN`, `.bundle/config`) | pass frozen 2.6.9, 4.0.18 (11-13) | pass frozen and deployment clone, with `BUNDLE_WITHOUT` too, 4.0.18 (11-14) | pass frozen on all, deployment clone 2.5.22, 2.6.9, 4.0.18 (11-14) |
@@ -28,22 +28,22 @@ Linux only. A cell is `pass` with the Bundler versions and the date, `fail #N`,
28
28
| Monorepo: several Gemfiles, nested projects, scan from the repo root | untested (agent scans one project by design) | untested | pass 4.0.18: scan, `list`, rollback from the root (11-14) |
29
29
|`setup` and the Bundler plugin it installs | n/a: `setup` and the plugin were removed in v5 (CLI_CONTRACT "…no longer published"); only `gem_bundler_plugin_stale` detection is left, untested | n/a | n/a |
| Switching modes on one project |untested | hosted to vendored: pair and mixed state pass 4.0.24; rollback afterwards leaves patched installs, fail #2083| vendored to hosted refused by design (not re-run)|
31
+
| Switching modes on one project |hosted to agent pass 4.0.18 (11-15); agent to hosted leaves the upstream archive, `pristine` / `--redownload` fail #2089| hosted to vendored: pair and mixed state pass 4.0.24; rollback afterwards leaves patched installs, fail #2083|hosted beside vendored gems (mixed) installs and attests 4.0.18 (11-15); any revert of the vendored gem then corrupts the lock, fail #2090|
| Bundler 1.x refused where the docs say so | untested | untested | untested |
34
34
35
35
## Backlog
36
36
37
-
1.Friction pass as a first-time user following only the CLI's messages and `docs/usage.md`. Known candidates: `redirect_gem_no_checksums_section` says "bundler < 2.6 does not write one" on a 2.6.9 lock (its remedy works); vendored mode refuses every gem inside a `group do` block, which is most Rails Gemfiles (by design, #340: is the message's remedy clear?); `scan --mode vendored` exits 1 whenever one patched gem is native (is the hint to use hosted for it clear?); `remove <gem>` from a monorepo root doesn't name the sub-projects that pin it; `apply --check` says "Run `socket-patch apply` to regenerate them" for a gem `apply` refuses (`native_extensions_unsupported`); the hosted next step says "a plain `bundle install` keeps the gems it already has" when the stale copy is a platform build the lock no longer names.
38
-
2.A realistic Rails-sized project (a Rails 7 or 8 Gemfile with groups, bootsnap, a `Bundler.require` boot) through hosted mode end to end, on Bundler 2.5, 2.6 and 4.0.
39
-
3.Vendored mode, the rest: `remove` / `vendor --revert` after a hosted to vendored takeover (#2083 covers `rollback` only), `scan --prune`.
40
-
4.Agent mode, the rest: Bundler 2.4, the system gem home under `/opt/ruby-*` itself, switching agent to hosted and back, `apply --dry-run` starts no Ruby, a relative crawl root (#2048), an interrupted rebuild, a monorepo.
41
-
5. Other flags the nested apply of `scan --mode agent` may drop (same cause as #2069: `nested_apply_args_from_params` fills `GlobalArgs` from defaults).
42
-
6. Hosted shared gem home, the rest: `--gem-refresh-shared` with two projects pinning the same gem version (the documented cost), `remove` of one gem out of several, `SOCKET_GEM_REFRESH_SHARED=1`.
37
+
1.Mixed and switched states, the rest (#2089 and #2090 came from here): agent to hosted with a native gem or a shared gem home; agent to vendored and back; hosted first and then `vendor <one purl>`; `scan --prune` and `repair` on a mixed project; a re-scan when a newer patch supersedes one of a mixed pair.
38
+
2.Friction pass, the rest. Still open candidates: `redirect_gem_no_checksums_section` says "bundler < 2.6 does not write one" on a 2.6.9 lock (its remedy works); `scan --mode vendored` exits 1 whenever one patched gem is refused, with next steps that read like success (noted in #2091); `remove <gem>` from a monorepo root doesn't name the sub-projects that pin it; `apply --check` says "Run `socket-patch apply` to regenerate them" for a gem `apply` refuses; the hosted next step says "a plain `bundle install` keeps the gems it already has" when the stale copy is a platform build the lock no longer names; `docs/usage.md` never mentions Ruby.
39
+
3.The Rails app, the rest: a Rails 8 Gemfile (kamal, thruster, solid_*), the default dev setup with a shared rbenv gem home, `bin/setup`, a Dockerfile-style `BUNDLE_PATH=/usr/local/bundle` install, `bundle update` / `bundle update rails` with hosted pins (beyond #2070), Dependabot-style `bundle lock --update <gem>`.
40
+
4.Vendored mode, the rest: `remove` / `vendor --revert` after a hosted to vendored takeover (#2083 covers `rollback` only), `scan --prune`.
41
+
5.Agent mode, the rest: the system gem home under `/opt/ruby-*` itself, `apply --dry-run` starts no Ruby, a relative crawl root (#2048), an interrupted rebuild, a monorepo. Other flags the nested apply of `scan --mode agent` may drop (same cause as #2069).
42
+
6. Hosted shared gem home, the rest: `--gem-refresh-shared` with two projects pinning the same gem version, `remove` of one gem out of several, `SOCKET_GEM_REFRESH_SHARED=1`.
43
43
7. Bundler 4.1 lock sections `OVERRIDES` and `CONTENT ADDRESSES`: find which Gemfile or setting makes 4.1.0.beta3 write them, then hosted and vendored. Ruby 3.4 is not in the sandbox.
44
44
8. Deployment mode and `.bundle/config` shapes around the stale-install guard. #1109 is open and waiting on a maintainer decision; don't re-file it.
45
45
9. Bundler 1.x refused where the docs say so (needs a Ruby that still runs Bundler 1.17; none in the sandbox).
0 commit comments