fix(subos): decouple storage from sandbox + transparent bwrap probe errors#293
Merged
Conversation
…rrors V6 storage isolation (image/tmpfs) auto-forced `--sandbox` entry, fusing two axes that V4 design explicitly kept orthogonal. A user with `storage=image` would silently require root, bwrap, and a working mount namespace just to switch shells — and any failure cascaded into a `run: xlings install bwrap` loop with no real diagnostic. Four changes, all in subos.cppm: - `use_spawn_shell` / `use_emit_shell`: removed the auto-upgrade to sandbox when storage != shared. Storage now only takes effect on the explicit `--sandbox` path. New `warn_storage_dormant_on_shell_` helper writes a one-line hint to stderr (eval-safe for the `--shell <kind>` output mode) so the user knows the storage attribute is dormant in this entry. - `probe_bwrap_`: switched from `system()` + 2>/dev/null + bool to `platform::run_command_capture` + `platform::shell_quote`, returning `(ok, captured_output)`. New `classify_bwrap_probe_error_` matches three known failure modes (setuid build-mode mismatch, AppArmor uid_map block, kernel-disabled userns) and returns actionable hints; unmatched output falls through to "raw stderr" so users always see the truth. - `use_sandbox_mode_`: when image/tmpfs storage is rejected because backend fell back to proot, re-probe bwrap and surface the classified error instead of the stale `xlings install bwrap` suggestion. - `remove`: detect a live `<subos>/.mountpoint` (image storage) and `unmount_image_` first. Without this, `rm -rf` either hit EBUSY on the mountpoint or recursed into the live filesystem and erased image contents before EBUSY surfaced (home.img marked `(deleted)`). Linux-only branch (`#if defined(__linux__)`). Docs: changelog entry, V6 design doc updated to reflect orthogonality, followup-fixes plan added (.agents/docs/sandbox-v6-followup-fixes- 2026-05-15.md) tracking remaining items (stale-mount scan on sandbox entry, `subos new` cross-platform storage validation).
Sunrisepeak
added a commit
that referenced
this pull request
May 15, 2026
Includes: - fix(subos): decouple storage from sandbox + transparent bwrap probe errors (#293) - fix(subos): avoid bwrap prompts for piped sandbox commands
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.
Summary
V6 storage isolation auto-forced
--sandboxentry whenstorage=image|tmpfs, fusing two axes that V4 design kept orthogonal. Result:xlings subos use <image-subos>silently required root + bwrap + working mount namespace just to switch shells, and any failure cascaded into arun: xlings install bwraploop with no real diagnostic.This PR is a UX hotfix covering four items from
.agents/docs/sandbox-v6-followup-fixes-2026-05-15.md:P0-1 — Decouple storage from sandbox:
subos use <name>without--sandboxalways enters shell-level regardless of storage. Image / tmpfs only take effect on the explicit--sandboxpath. Newwarn_storage_dormant_on_shell_helper emits a one-line stderr hint (eval-safe for--shell <kind>output mode).P0-3 —
probe_bwrap_transparency: replacedsystem() + 2>/dev/null + boolwithplatform::run_command_capture + platform::shell_quote, returning(ok, output). Newclassify_bwrap_probe_error_matches three known failure modes (setuid build-mode mismatch, AppArmor uid_map block, kernel-disabled userns) and returns actionable hints; unmatched output falls through to raw stderr so users always see the truth.P0-3 (continued) — Re-probe on image-rejects-proot: when image/tmpfs hits the proot fallback rejection, re-probe bwrap and surface the classified error instead of the stale
xlings install bwrapsuggestion.P0-4 —
subos removeumounts image first: detect a live<subos>/.mountpointandunmount_image_beforerm -rf. Without this,rm -rfeither hit EBUSY at the mountpoint or recursed into the live filesystem and erased image contents (home.img marked(deleted)). Linux-guarded.Cross-platform impact
removesafely umounts beforerm.subos new) is tracked as a separate followup.User-facing behavior change
Before:
After (with bwrap broken/missing on host, but user wanted shell-level only):
After (when user explicitly does
--sandboxbut bwrap build is broken):Test plan
xmake build xlings— clean compile (subos.cppm rebuilt, no errors/warnings on changed code)bash tests/e2e/subos_sandbox_test.sh— passes (S1-S2 verified; S3+ skipped pending live backend, which is the existing behavior)bash tests/e2e/subos_install_remove_isolation_test.sh— passes (remove path unchanged for shared-storage subos)bash tests/e2e/subos_workspace_c2_schema_test.sh— passes (workspace schema unaffected)subos use --shell sh— stdout is eval-safe (exports only), stderr has the storage hint,eval "$out"thenecho $XLINGS_ACTIVE_SUBOSreturns the subos namesubos remove(no live mount) — succeeds cleanly, directory removedsubos use --shell sh— no storage hint emitted (correct)Followups (separate PRs)
Tracked in
.agents/docs/sandbox-v6-followup-fixes-2026-05-15.md:.mountpointon sandbox entry (kill -9 / force-close recovery)subos new --storage image|tmpfscross-platform validation (reject at create time on macOS/Windows)xim:bwrapinstall hook sudo prompt UX