Keep the image's Bundler defaults when roast strips BUNDLE_* for subprocesses - #46
Merged
Merged
Conversation
… subprocesses 1.5.1 baked the skeleton's gems into the image, and `bundle check` on a workspace passes in the generator container and in a plain `docker run` of the sandbox image. It still failed inside every real sandbox run because Bundler.with_unbundled_env — used by our verify step and by the roast gem when it spawns the code agent — deletes EVERY BUNDLE_* variable, the Dockerfile's BUNDLE_PATH and BUNDLE_WITHOUT included. Without BUNDLE_PATH Bundler looks under $GEM_HOME/gems instead of $BUNDLE_PATH/ruby/<abi>/gems and reports the whole lockfile missing; without BUNDLE_WITHOUT it wants the development group the image never installs. Reproduced on production with `env -u` (all gems missing), and the pass with the two restored. - Dockerfile: the claude wrapper exports BUNDLE_PATH/BUNDLE_WITHOUT (image defaults, caller values win) so the agent and everything it runs resolve gems; the Bundler ENV block moves above the wrapper so it quotes the same values at build time. - VerifyRevision.with_clean_bundler_env restores the same two keys from Bundler.original_env inside with_unbundled_env; the comment that claimed Bundler keeps Dockerfile globals is gone. - AutoRemediate.shell runs in that scrubbed env too: under roast's `bundle exec` its `bundle install` recipe ran with BUNDLE_GEMFILE=<generator Gemfile>, "completed" in 0.6s against the generator's satisfied bundle, and fixed nothing, every revision. - Tests pin the restore, the dev no-op, and that the parent env is untouched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117StvHb26xv3MUepWHhcWy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
PR #45 put the skeleton's gems in the image, and
bundle checkon a workspace now passes in the generator container and in a plaindocker run --user 1000of the sandbox image. It still failed inside every real sandbox run (project 36, 2026-09-03 22:08: all 116 gems "missing", fix agent reinstalls them, 97s and $0.07 per revision).Cause:
Bundler.with_unbundled_env, used by our verify step and by the roast gem when it spawns the code agent, deletes everyBUNDLE_*variable, not only whatbundle execset. That takes the Dockerfile'sBUNDLE_PATHandBUNDLE_WITHOUTwith it. WithoutBUNDLE_PATH, Bundler looks under$GEM_HOME/gemsinstead of$BUNDLE_PATH/ruby/<abi>/gemsand reports the whole lockfile missing; withoutBUNDLE_WITHOUTit wants the development group the image never installs. Reproduced on production:bundle checkBUNDLE_*strippedBUNDLE_PATHrestoredWhat
claudewrapper exportsBUNDLE_PATH/BUNDLE_WITHOUT(image defaults, caller values win), so the agent and everything it runs resolve gems. The BundlerENVblock moves above the wrapper so it quotes the same values at build time.VerifyRevision.with_clean_bundler_env: restores the same two keys fromBundler.original_envinsidewith_unbundled_env. The comment claiming Bundler keeps Dockerfile globals is gone.AutoRemediate.shell: runs in that scrubbed env too. Under roast'sbundle execitsbundle installrecipe ran withBUNDLE_GEMFILE=<generator Gemfile>, "completed" in 0.6s against the generator's already-satisfied bundle, and fixed nothing, every revision.BUNDLE_PATHin the original env → nothing added), and that the parent env is untouched. CHANGELOG 1.5.2.Verified
printfcommands:sh -nclean; withBUNDLE_*stripped it exports/usr/local/bundle/development; a caller's value wins.Bundler.unbundled_envdrop confirmed locally (Bundler 4.0.9) and the failure/pass matrix above on production (Bundler 4.0.6).After merge
kamal deploy, then one change request on any project. Expected inkamal app logs --grep 'W2.4\|auto_remediate\|Cost (USD)': four[W2.4] PASSlines, noauto_remediatelines, two cost lines (code agent, docs agent).🤖 Generated with Claude Code
https://claude.ai/code/session_0117StvHb26xv3MUepWHhcWy