Skip to content

[NemoClaw][Linux] Brew policy preset applies network rules but does not provision brew binary, so brew install step in test cannot succeed #3757

Description

@zNeill

Description

[Description]
When the brew policy preset is applied to a NemoClaw sandbox, the documented test case expects both: (a) network egress to Homebrew endpoints (formulae.brew.sh, raw.githubusercontent.com, ghcr.io, GitHub) and (b) a working brew CLI inside the sandbox so brew install hello can complete. In practice, after applying the brew preset, all the curl and git network probes succeed from inside the sandbox, but brew install --quiet hello fails with bash: brew: command not found. This shows that the preset correctly configures network access but does not ensure that the Homebrew/brew binary is installed in the sandbox, so the final “brew install hello” validation step in the test case cannot be executed as written.

[Environment]
NemoClaw: v0.0.44
OpenShell CLI: 0.0.39
OpenClaw: 2026.4.24 (cbcfdf6)
Sandbox OS: Linux (default NemoClaw base image, x86_64)
Container runtime: Docker on DGX Spark host
Network: outbound HTTPS generally allowed; no proxy errors for Homebrew endpoints

[Steps to Reproduce]

Pre-condition:

  1. NemoClaw sandbox new-sb is running.
  2. No additional network-policy presets have been applied yet.

Steps:

  1. On the host, apply the brew preset:nemoclaw new-sb policy-add

    When prompted, select the "brew" preset and confirm.


  2. Verify it is active:nemoclaw new-sb policy-list

    Confirm that brew shows as ● (applied) in the preset list.


  3. Connect into the sandbox:nemoclaw new-sb connect

    You land at sandbox@...:~$.


  4. Inside the sandbox, probe the Homebrew registry:curl -sI --max-time 8 https://formulae.brew.sh

  5. Still inside the sandbox, fetch the Homebrew install script:curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh -o /dev/null

  6. Check git access to the Homebrew repo:git ls-remote https://github.com/Homebrew/brew.git HEAD

  7. Probe ghcr.io:curl -sI --max-time 8 https://ghcr.io

  8. Try to install a package via brew:brew install --quiet hello

  9. Exit the sandbox:exit

[Expected]

  1. nemoclaw new-sb policy-add with the brew preset applies the Homebrew-related network policy; policy version increments.
  2. nemoclaw new-sb policy-list shows brew as ● (applied) for sandbox new-sb.
  3. nemoclaw new-sb connect enters the sandbox successfully.
  4. Inside the sandbox, curl -sI --max-time 8 https://formulae.brew.sh returns HTTP 200 or 301, confirming the Homebrew registry is reachable via /usr/bin/curl (which the test spec assumes is in the brew preset’s binary allowlist).
  5. curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh -o /dev/null succeeds, confirming access to the install script.
  6. git ls-remote https://github.com/Homebrew/brew.git HEAD succeeds (no TLS errors), confirming git access to the Homebrew repo.
  7. curl -sI --max-time 8 https://ghcr.io returns HTTP 200 or 301, confirming ghcr.io is reachable for bottle downloads.
  8. brew install --quiet hello succeeds end‑to‑end: the brew binary exists in the sandbox PATH, downloads from ghcr.io / pkg-containers.githubusercontent.com / objects.githubusercontent.com succeed without “server certificate verification failed” errors, and the hello package is installed.
  9. Sandbox exits cleanly.

[Actual]

  1. nemoclaw new-sb policy-list shows the brew preset as applied (● brew — Homebrew (Linuxbrew) package manager access), alongside other presets (brave, discord, huggingface, local-inference, npm, pypi, etc.).
  2. nemoclaw new-sb connect enters the sandbox successfully and reports an inference route using vllm-local/meta/llama-3.1-8b-instruct.
  3. Inside the sandbox:
    • curl -sI --max-time 8 https://formulae.brew.sh returns HTTP/2 200 with GitHub/varnish headers, confirming the registry is reachable.
    • curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh -o /dev/null completes successfully (no output, zero exit code).
    • git ls-remote https://github.com/Homebrew/brew.git HEAD returns a valid commit hash (e.g., a7f3847d5f52c123207873b6ca5093e79701d468 HEAD), confirming git access.
    • curl -sI --max-time 8 https://ghcr.io succeeds with HTTP/1.1 200 Connection Established followed by HTTP/2 405, showing TLS and connectivity to ghcr.io are working.
  4. However, attempting to install a package via brew fails immediately:sandbox@2549dec54185:~$ brew install --quiet hello bash: brew: command not found

    indicating that the brew binary is not installed in the sandbox at all, even though the brew policy preset is applied and all the network probes succeed.


  5. The final step of the test case (“brew install hello SUCCEEDS end‑to‑end”) cannot be executed as written because there is no brew CLI in the sandbox PATH.

[Impact / Notes]

  • The brew preset correctly configures network access to the Homebrew registry, GitHub, and ghcr.io, but does not ensure that the Homebrew/brew CLI is present inside the sandbox.
  • The documented test case for the brew preset implicitly assumes a working brew binary, so the QA scenario “apply brew preset → brew install hello” cannot be validated in a fresh NemoClaw sandbox without manually installing Homebrew first.
  • This may be resolved either by:
    • Updating the test plan/docs to state that the user must install Homebrew inside the sandbox before running brew install checks, or
    • Enhancing the brew preset / onboarding flow to optionally install Homebrew (or to check for the presence of brew and warn clearly if it is missing).

Bug Details

Field Value
Priority Unprioritized
Action Dev - Open - To fix
Disposition Open issue
Module Machine Learning - NemoClaw
Keyword NemoClaw, NEMOCLAW_GH_SYNC_APPROVAL, NemoClaw-SWQA-RelBlckr-Recommended, NemoClaw-SWQA-Sprint4-Blocker

[NVB#6188343]

Activity

  1. added
    NV QABugs found by the NVIDIA QA Team
    UATIssues flagged for User Acceptance Testing.
    on May 18, 2026
  2. self-assigned this
    on May 20, 2026
  3. removed their assignment
    on May 21, 2026
  4. laitingsheng commented on May 21, 2026

    @laitingsheng
    Contributor

    #3916 could be a solution for this

  5. 2 remaining items

  6. self-assigned this
    on May 28, 2026
  7. added a commit that references this issue on May 28, 2026
    195bbcc
  8. prekshivyas commented on May 28, 2026

    @prekshivyas
    Collaborator

    Re-tested on NemoClaw v0.0.53 (latest tag): destroyed the old sandbox (destroy --cleanup-gateway), re-onboarded fresh with the stock image, and applied the brew preset.

    Good news: the original bug is gone

    brew: command not found no longer happens — brew now comes pre-installed in the sandbox image:

    • brew is at /usr/local/bin/brew → /home/linuxbrew/.linuxbrew/Homebrew/bin/brew
    • brew --version → Homebrew 5.1.12

    All the network checks from the original report still pass:

    Check Result
    curl -sI https://formulae.brew.sh 200
    curl -fsSL .../install.sh OK
    git ls-remote https://github.com/Homebrew/brew.git HEAD returns a commit
    curl -sI https://ghcr.io 200

    Bad news: brew install hello still fails

    It fails for two separate reasons. Neither is a network problem — the brew preset's network rules are fine. The problem is that brew tries to write to folders the sandbox user isn't allowed to write to.

    Problem 1 — brew thinks its home is /usr/local, which is read-only

    mkdir: cannot create directory '/usr/local/var': Permission denied
    Error: Can't create `brew vendor-install ruby` lock in /usr/local/var/homebrew/locks!
    

    Brew is actually installed under /home/linuxbrew/.linuxbrew, but it thinks its home folder is /usr/local. Why? The image ships a /usr/local/bin/brew shortcut (symlink), and that shortcut triggers a special rule inside brew's startup script meant for macOS:

    if [[ -L /usr/local/bin/brew && ! -L ${PREFIX}/Cellar ]]; then
      HOMEBREW_PREFIX=/usr/local

    So on Linux it wrongly settles on /usr/local. The sandbox makes /usr read-only, so brew can't create its lock folder and stops. (Trying to fix this with HOMEBREW_PREFIX=... as an environment variable does not work — brew's startup script overwrites it. Verified.)

    Problem 2 — brew's temp folder /var/tmp is blocked

    Once Problem 1 is worked around, brew gets much further (it downloads Ruby and the hello package from ghcr.io with no trouble), then fails here:

    Error: Permission denied @ dir_s_mkdir - /var/tmp/homebrew-unpack-...
    

    /var/tmp looks writable (1777), but the sandbox user can't even list it. This is not a read-only mount — it's the sandbox's Landlock policy. The policy only allows writing to a fixed list of folders:

    • allowed: /tmp, /home/linuxbrew, /sandbox, /dev/null, …
    • read-only: /usr, /etc, /var/log, /lib, …

    /var/tmp is on neither list, so it's blocked.

    Proof it's only these two things

    If I point brew at folders the sandbox does allow:

    • use its real home /home/linuxbrew/.linuxbrew (which is writable), and
    • set HOMEBREW_TEMP=/tmp

    then brew install hello works end to end:

    🍺  /home/linuxbrew/.linuxbrew/Cellar/hello/2.12.3
    $ hello
    Hello, world!
    

    Suggested fix

    • Remove the /usr/local/bin/brew symlink (it's what forces the wrong home folder) and instead add brew to PATH the normal way, via eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)". That makes brew use its writable /home/linuxbrew/.linuxbrew home.
    • Make sure brew's temp folder is an allowed path (e.g. ship HOMEBREW_TEMP=/tmp).

    Bottom line: the "brew is missing" part is fixed, but a fresh sandbox still can't run brew install without these tweaks.

  9. prekshivyas commented on May 28, 2026

    @prekshivyas
    Collaborator

    Quick follow-up: this is already fixed on main by #4459 ("fix(sandbox): keep Homebrew on Linuxbrew prefix"), merged today as a follow-up to #3916.

    It does exactly what's needed for both problems above:

    • Replaces the /usr/local/bin/brew symlink with a small wrapper script that execs /home/linuxbrew/.linuxbrew/bin/brew, so Homebrew keeps its writable Linuxbrew prefix instead of inferring /usr/local.
    • Pins HOMEBREW_TEMP=/tmp (and TMPDIR=/tmp), which is in the sandbox's writable set, so the unpack step no longer hits the blocked /var/tmp.
    • Adds build-time checks that brew --prefix resolves to /home/linuxbrew/.linuxbrew.

    My testing above was on v0.0.53, which predates that merge — that's why a fresh sandbox still showed the failure. The fix is on main now and will be fully available in the next release. Once that release ships, brew install hello should work end-to-end with no manual tweaks.

  10. added
    area: policyNetwork policy, egress rules, presets, or sandbox policy
    area: sandboxOpenShell sandbox lifecycle, runtime, config, or recovery
    enhancementNew capability or improvement request
    and removed on Jun 3, 2026
  11. added theissue type on Jun 8, 2026
  12. changed the issue type fromtoon Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

NV QABugs found by the NVIDIA QA TeamUATIssues flagged for User Acceptance Testing.area: policyNetwork policy, egress rules, presets, or sandbox policyarea: sandboxOpenShell sandbox lifecycle, runtime, config, or recovery

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions