docs(policy): clarify brew preset requires pre-installed Homebrew (#3757)#3846
docs(policy): clarify brew preset requires pre-installed Homebrew (#3757)#3846latenighthackathon wants to merge 4 commits into
Conversation
📝 WalkthroughWalkthroughThis PR clarifies that the ChangesHomebrew Preset Bootstrap
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/network-policy/integration-policy-examples.mdx`:
- Line 243: Split the single source line containing two sentences into two
separate lines: keep "After the first install, `brew` is on the sandbox `PATH`
and subsequent `brew install <package>` calls work directly." as one line, and
place "The bootstrap is per-sandbox; recreating the sandbox requires re-running
the install." on the following line so each sentence is on its own source line
for diff readability.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 7feb4c98-4a58-470d-bd91-6eb7036b6c2a
📒 Files selected for processing (3)
docs/network-policy/customize-network-policy.mdxdocs/network-policy/integration-policy-examples.mdxnemoclaw-blueprint/policies/presets/brew.yaml
…IDIA#3757) The brew policy preset whitelists network egress to the Homebrew registry and the binary paths under /home/linuxbrew/.linuxbrew/, but the sandbox base image does not ship the brew CLI itself. Users who apply the preset and run `brew install hello` immediately hit `bash: brew: command not found` (NVIDIA#3757, duplicates NVIDIA#1767 from 2026-04-10). The linuxbrew paths in the preset binary list are intentional: they become active once the user installs Homebrew inside the sandbox, and whitelisting them up front avoids a second policy round-trip. The preset surface just was not telling users that step is on them. Changes: - nemoclaw-blueprint/policies/presets/brew.yaml: clarify the preset description, add an inline header comment explaining the design, and group the bootstrap binaries (curl, git) vs the post-install linuxbrew paths so a future reader sees the intent. - docs/network-policy/customize-network-policy.mdx: the brew row in the preset table now links to the bootstrap walkthrough. - docs/network-policy/integration-policy-examples.mdx: new Homebrew Bootstrap section after Package and Model Tooling. Shows the preset-add + connect + install one-liner + shellenv eval sequence. Refs NVIDIA#3757, NVIDIA#1767 Signed-off-by: latenighthackathon <support@latenighthackathon.com>
CodeRabbit nit: integration-policy-examples.mdx:243 had two sentences on one line. Split per the repo's one-sentence-per-line style so diffs stay readable. Signed-off-by: latenighthackathon <support@latenighthackathon.com>
31bfdf5 to
939cec2
Compare
|
✨ Thanks for submitting this detailed PR about clarifying the brew preset requirements. This PR proposes a way to update the documentation and improve the brew policy preset to avoid confusion about Homebrew installation. Related open issues: |
…#3913) The brew policy preset advertises "Homebrew (Linuxbrew) package manager access" and whitelists the linuxbrew binary paths, but the sandbox cannot actually install Homebrew at runtime: 1. nemoclaw-blueprint/policies/openclaw-sandbox.yaml does not list /home/linuxbrew under filesystem_policy.read_write, so Landlock denies writes there. 2. The sandbox runs as the unprivileged `sandbox` user with no sudo (Dockerfile.base creates `sandbox` with HOME=/sandbox). Homebrew's install script's first step is `sudo` to create + chown /home/linuxbrew/.linuxbrew, which the sandbox cannot grant. Applying the brew preset and running the documented bootstrap line in the sandbox fails immediately with "Insufficient permissions to install Homebrew to /home/linuxbrew/.linuxbrew". The preset's binary whitelist for /home/linuxbrew/.linuxbrew/bin/* becomes dead code. This change bakes Homebrew core into the sandbox base image during build (running as root, then dropping to sandbox via gosu for the clone). The companion baseline-policy change adds /home/linuxbrew to filesystem_policy.read_write so brew can extract bottles and manage Cellar/opt symlinks at runtime. After the next base-image rebuild, every sandbox starts with a working brew at /home/linuxbrew/.linuxbrew/bin/brew. Applying the brew preset plus running `brew install <formula>` works end-to-end with no bootstrap required. Precedent: NVIDIA#3682 (in v0.0.46, closes NVIDIA#3677) baked the WeChat plugin into the sandbox base image for the same reason. Files: - Dockerfile.base: add the brew install step at the end, after the WeChat plugin block. Image-build cost is ~80 to 150 MB for Homebrew core (formulae download on demand). - nemoclaw-blueprint/policies/openclaw-sandbox.yaml: add /home/linuxbrew to filesystem_policy.read_write with an inline comment explaining the link to the Dockerfile.base step. - test/policies.test.ts: add a behavior-style assertion that the baseline read_write list includes the Homebrew prefix, so a future removal of this entry trips CI. Out of scope for this PR: - agents/hermes/Dockerfile.base. Hermes does not currently get the WeChat plugin baking either; same scoping rationale. - Adding /home/linuxbrew/.linuxbrew/bin to the system PATH. Users can run `brew` via the full path or via `eval "$(brew shellenv)"`. PR NVIDIA#3846 documents the latter. Closes NVIDIA#3913 Refs NVIDIA#1767, NVIDIA#3757 Signed-off-by: latenighthackathon <support@latenighthackathon.com>
…#3916) ## Summary Closes #3913. Bakes Homebrew core into the sandbox base image so the `brew` policy preset actually works end-to-end. Without this, applying the preset and running `brew install <formula>` inside the sandbox fails with `Insufficient permissions to install Homebrew to "/home/linuxbrew/.linuxbrew"` because the sandbox lacks filesystem write to `/home/linuxbrew/` AND runs as an unprivileged user with no sudo. ## Problem Two filesystem constraints block runtime Homebrew installation today: 1. `nemoclaw-blueprint/policies/openclaw-sandbox.yaml` lists only `[/tmp, /dev/null, /sandbox/.openclaw, /sandbox/.nemoclaw]` plus the workdir under `filesystem_policy.read_write`. Landlock denies writes to `/home/linuxbrew/`. 2. `Dockerfile.base` runs the sandbox as `useradd -r -g sandbox -d /sandbox -s /bin/bash sandbox` (no sudo). Homebrew's install script's first step is `sudo` to create + chown `/home/linuxbrew/.linuxbrew`, which the sandbox cannot grant. Result: the `brew` preset's binary whitelist for `/home/linuxbrew/.linuxbrew/bin/*` is dead code. Two QA reports already documented the symptom: [#1767](#1767) (filed 2026-04-10) and [#3757](#3757) (filed 2026-05-18). [#3846](#3846) was an interim docs-only attempt that we closed in favor of this PR; documenting a bootstrap that cannot actually succeed in the default sandbox would have set wrong expectations. ## Approach Follow the [#3682](#3682) precedent (WeChat plugin baked into the base image in v0.0.46): provision the tool at image-build time, when the build runs as root and can create + chown the prefix. - `Dockerfile.base`: after the existing WeChat plugin install block, add a step that creates `/home/linuxbrew/.linuxbrew/bin`, chowns to `sandbox:sandbox`, clones Homebrew core as the sandbox user via `gosu` at the pinned `ARG HOMEBREW_VERSION=5.1.12` tag, symlinks the `brew` entry point, and asserts `brew --version` succeeds. The `ARG` keeps the base-image layer reproducible across rebuilds and can be bumped by editing the default or passing `--build-arg`. - `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`: add `/home/linuxbrew` to `filesystem_policy.read_write` so runtime `brew install <formula>` can extract bottles and manage Cellar/opt symlinks. - `test/policies.test.ts`: behavior-style assertion that the baseline `read_write` list includes the Homebrew prefix. Trips CI if a future change drops the entry. ## Cost Approximately 80 to 150 MB on the base image (Homebrew core only; formulae download on demand). Acceptable relative to the existing ~2.4 GB sandbox image and consistent with the trade-off the project already accepted for the WeChat plugin baking. ## Follow-up docs PR planned Once this merges and the base image rebuilds, a small docs PR will land covering the new flow on the matching MDX pages: apply the `brew` preset, run `brew install <formula>`. The previous attempt at documenting a runtime bootstrap (closed [#3846](#3846)) becomes obsolete and the new docs will reflect that `brew` is included by default. ## Out of scope - **`agents/hermes/Dockerfile.base`** — Hermes does not currently get the WeChat plugin baking either; same scoping rationale. Can extend in a follow-up if maintainers want Homebrew under Hermes. - **System `PATH`** — users can run `brew` via the full path `/home/linuxbrew/.linuxbrew/bin/brew` or via `eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"`. A separate PR could add the prefix to `/etc/bash.bashrc` if a cleaner default UX is wanted. - **Option B (drop the brew preset entirely)** — discussed in [#3913](#3913); rejected because removing a Balanced-tier preset is a user-visible regression. ## Test plan - [x] `prek run --files` clean on all changed files - [x] New `test/policies.test.ts` assertion passes (`Homebrew prefix` test) - [x] Behavior-style test (parses YAML and checks the structured `read_write` array); satisfies the source-shape budget - [x] Verified the pinned `HOMEBREW_VERSION=5.1.12` tag exists upstream (`gh api repos/Homebrew/brew/releases` + direct `https://github.com/Homebrew/brew/releases/tag/5.1.12` returns 200) - [ ] **CI to verify:** sandbox base image rebuilds successfully with the new step - [ ] **CI to verify:** `brew --version` runs inside a freshly-created sandbox (covered by the build-time `gosu sandbox /home/linuxbrew/.linuxbrew/bin/brew --version` assertion in `Dockerfile.base`) - [ ] **Manual smoke after base-image publish:** `nemoclaw onboard` -> `<name> policy-add brew --yes` -> `<name> connect` -> `brew install hello` -> succeeds Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Homebrew package manager is now pre-installed and available in the sandbox environment, enabling users to install and manage software packages using standard Homebrew commands. * **Tests** * Added validation tests for Homebrew policy configuration and binary permissions. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3916?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: latenighthackathon <support@latenighthackathon.com> Signed-off-by: Aaron Erickson <aerickson@nvidia.com> Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com> Co-authored-by: Aaron Erickson <aerickson@nvidia.com>
Summary
Closes #3757 (also duplicates the earlier #1767 from 2026-04-10). Clarifies that the
brewpolicy preset whitelists Homebrew network egress and binary paths but does not install Homebrew itself; users must bootstrap brew inside the sandbox once after applying the preset.Problem
The
brewpreset's binary list includes/home/linuxbrew/.linuxbrew/bin/brewand the linuxbrew bin glob, alongside the bootstrap binaries/usr/bin/curland/usr/bin/git. The bootstrap binaries are real and present in the sandbox base image, so the user can run the Homebrew install script. The linuxbrew paths are placeholders that become real once Homebrew is installed inside the sandbox.Two QA reports (#1767 from 2026-04-10, #3757 from 2026-05-18) hit the same trap: apply the preset, connect into the sandbox, run
brew install hello, getbash: brew: command not found. The preset description"Homebrew (Linuxbrew) package manager access"reads as if it provides the manager, not just the network policy for it.Filesystem-permission caveat (root cause)
This PR is a docs-only band-aid. The Homebrew install script cannot actually succeed in the default sandbox today:
/home/linuxbrew/is not infilesystem_policy.read_write(Landlock denies writes), AND the sandbox runs as the unprivilegedsandboxuser with no sudo (Homebrew's install script's first step issudoto create + chown/home/linuxbrew/.linuxbrew).The root-cause fix lives in #3916, which bakes Homebrew core into the sandbox base image (mirroring the #3682 WeChat-plugin precedent) and adds
/home/linuxbrewto the baselineread_writelist. Once #3916 lands, users only need to apply the preset; the bootstrap step in this PR becomes optional (and would only matter for sandboxes built before the base-image rebuild).Until #3916 ships, the bootstrap one-liner in this PR will return Homebrew's "Insufficient permissions" error on a fresh sandbox. The "Untar Anywhere" alternative under
/sandbox/works as a workaround but builds formulae from source (unsupported by Homebrew).Approach
Documentation + preset description fix, no behavior change:
nemoclaw-blueprint/policies/presets/brew.yaml- update the preset description to explicitly call out the pre-install requirement, add a file-header comment explaining why the linuxbrew paths are whitelisted before brew exists, and split the binary list into a bootstrap group (curl, git) and a post-install group (linuxbrew paths) with inline comments.docs/network-policy/customize-network-policy.mdx- thebrewrow in the presets table now links to the bootstrap walkthrough.docs/network-policy/integration-policy-examples.mdx- new "Homebrew Bootstrap" section after Package and Model Tooling. Shows thepolicy-add->connect-> Homebrew install script ->brew shellenv->brew install hellosequence.Test plan
prek run --filesclean on all three modified files (yaml + 2 mdx)git grep "Homebrew (Linuxbrew) package manager"returns only the updated preset (no test fixture depends on the old description)Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com