run: set a deterministic default PATH in every sandbox #2

Merged
chad merged 1 commit from sandbox/default-path into master 2026-09-24 17:50:02 -04:00
Collaborator

The parked follow-up to PR #1, now implemented: the engine sets a deterministic default PATH in every sandbox unless the entrypoint pins its own.

The problem: bwrap inherits the INVOKING HOST's environment — the engine never set PATH — so what a process sees as PATH depends on who ran bubblebox (login shell / agent shell / CI unit: all different). Worst case, on NixOS the inherited PATH is /nix/store/... store paths that don't exist inside an FHS rootfs, so every env-shebang binary (#!/usr/bin/env python3 — yt-dlp) resolved nothing: pkgs PR #15's first gate run failed exit-127 on exactly this, and the batch-9 GUI batch would have been exposed to the same class.

The change: DEFAULT_SANDBOX_PATH (standard FHS order — the same list nvim/rust-dev were already pinning by hand per AGENTS.md §3) is set via --setenv PATH when the entrypoint's [sandbox.env] has no PATH; an entrypoint PATH override wins. Other host env still passes through untouched (Wayland/D-Bus sessions rely on it). Also fixes the stale /tmp comment in build_bwrap_args: --dir does NOT cover a /tmp-less image on bwrap 0.11.2 (same EROFS mkdir as binds — validate_bind_paths from PR #1 surfaces that case early).

Verification: 3 new unit tests (119 total) pin the contract — default present when no PATH set, entrypoint override wins with no stray default, other env untouched; clippy --all-targets clean; live on bee: yt-dlp (the failing case) runs under a poisoned host PATH with the new binary.

Note for after merge: yt-dlp's explicit PATH pin in bubblebox-pkgs becomes redundant (same value) — harmless, left in place as documentation. The pkgs AGENTS.md §3 "deterministic PATH" row + wiki Entrypoints will be updated to reflect the new default.

The parked follow-up to PR #1, now implemented: **the engine sets a deterministic default PATH in every sandbox** unless the entrypoint pins its own. **The problem**: bwrap inherits the INVOKING HOST's environment — the engine never set PATH — so what a process sees as PATH depends on who ran bubblebox (login shell / agent shell / CI unit: all different). Worst case, on NixOS the inherited PATH is /nix/store/... store paths that don't exist inside an FHS rootfs, so every env-shebang binary (`#!/usr/bin/env python3` — yt-dlp) resolved nothing: pkgs PR #15's first gate run failed exit-127 on exactly this, and the batch-9 GUI batch would have been exposed to the same class. **The change**: `DEFAULT_SANDBOX_PATH` (standard FHS order — the same list nvim/rust-dev were already pinning by hand per AGENTS.md §3) is set via `--setenv PATH` when the entrypoint's `[sandbox.env]` has no PATH; an entrypoint PATH override wins. Other host env still passes through untouched (Wayland/D-Bus sessions rely on it). Also fixes the stale /tmp comment in build_bwrap_args: `--dir` does NOT cover a /tmp-less image on bwrap 0.11.2 (same EROFS mkdir as binds — validate_bind_paths from PR #1 surfaces that case early). **Verification**: 3 new unit tests (119 total) pin the contract — default present when no PATH set, entrypoint override wins with no stray default, other env untouched; clippy --all-targets clean; live on bee: yt-dlp (the failing case) runs under a poisoned host PATH with the new binary. Note for after merge: yt-dlp's explicit PATH pin in bubblebox-pkgs becomes redundant (same value) — harmless, left in place as documentation. The pkgs AGENTS.md §3 "deterministic PATH" row + wiki Entrypoints will be updated to reflect the new default.
Without it, bwrap inherits the INVOKING HOST's environment: what a
process sees as PATH depends on who ran bubblebox (login shell / agent
shell / CI unit — all different), and on NixOS the inherited PATH is
/nix/store/... store paths that don't exist inside an FHS rootfs. Every
env-shebang binary ('#!/usr/bin/env python3' — yt-dlp) resolved nothing
there: pkgs PR #15's first gate run failed exit-127 on exactly this.

DEFAULT_SANDBOX_PATH is the standard FHS order — the same list the
nvim/rust-dev entrypoints were already pinning by hand (AGENTS.md §3
'deterministic toolchain' row). An entrypoint [sandbox.env] PATH
override wins; explicit pins like yt-dlp's stay harmless. Other host
env still passes through untouched (Wayland/D-Bus rely on it). Also
fixes the stale /tmp comment: --dir does NOT cover a /tmp-less image
(same EROFS mkdir as binds — validate_bind_paths surfaces that case).

3 new unit tests (119 total); clippy --all-targets clean; verified live
on bee: yt-dlp runs with a poisoned host PATH under the new binary.
chad approved these changes 2026-09-24 17:49:59 -04:00
chad merged commit c61bb1893f into master 2026-09-24 17:50:02 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
chad/bubblebox!2
No description provided.