Skip to content

[NVBug 6900397] Stop local CLI agents handing the server venv to the model's shell #4522

Open

Description

@qiaochuz-nv

Queue rank 34/48 · Difficulty 3/5 · Status on main: not_fixed

NVBug: https://nvbugspro.nvidia.com/bug/6900397 · Priority: Unprioritized · ARB: Ananth Subramaniam
GitHub: none found. Related (not merged): PR #4018 (anyswe_agent runtime isolation).

Summary

The local CLI agents (opencode, codex, pi, claude_code, kilocode, cline, openclaw) launch their tool CLI with env = {**os.environ, ...}. The agent server runs with its own .venv activated, so the model's shell inherits VIRTUAL_ENV and a PATH led by .venv/bin. The model's python3/pip are the server's: a model pip install X writes into responses_api_agents/<agent>/.venv and survives rollouts, gym env start, and later runs, so eval tool availability depends on venv history and the model can alter the server's own deps.

Reproduction

Deterministic (no model), per bug Repro A: against an existing opencode_agent/.venv, activate it then probe a child built with {**os.environ}; command -v python3/pip resolve into .venv/bin and VIRTUAL_ENV is set. E2E (Repro B): run opencode_math; a row asking the model to pip install -q sympy leaves sympy/mpmath (INSTALLER=pip) in the venv.

Root cause

opencode_agent/app.py:308-309 _env() copies the full server environment and never drops VIRTUAL_ENV/PYTHONPATH/PYTHONHOME or removes the venv bin from PATH. The server is launched with its venv activated (nemo_gym/cli/setup_command.py:160 uv venv --seed, :166/:245 activate) and run with the venv interpreter, so os.environ carries the activation. requirements.txt installs are incremental, so model-added packages persist.

Status on main (not_fixed)

HEAD 75bb53e. opencode_agent/app.py:309: env = {**os.environ, "XDG_DATA_HOME": data_home} — unchanged since #1594. Siblings still copy **os.environ: codex:1085, pi:907, claude_code:457, kilocode:379, cline:488, openclaw:984. setup_command.py:160/166 still --seed + activate. Commits #4046/#3639/#4288 added a sandbox path and observability but did not touch _env. PR #4018 fixes only anyswe_agent and is still open.

Proposed fix

Add a shared helper that sanitizes the child env: drop VIRTUAL_ENV/PYTHONPATH/PYTHONHOME, strip Path(sys.prefix)/"bin" from PATH, resolve the CLI via shutil.which() first. Apply in each agent's _env() (7 agents). The fix MUST preserve the server venv's numpy/scipy/sympy for the math envs (host python3 lacks them), e.g. via a declared per-request tool Python; document that local tool commands run on the host. Tests: mirror PR #4018's test_runtime_isolation.py.

Validation

QA scripts formally referencing this bug are testcases/environments/opencode_math.py, codex_math.py, pi_math.py; claude_code_math.py is observed-exposure, not a formally referencing case. Re-run after fix; confirm the deterministic probe (Repro A) shows no venv leak and a pip install row leaves the agent .venv unchanged (no INSTALLER=pip dist-info).

Triage

Difficulty 3/5 — localized but spans 7 agents plus a shared helper and a tool-Python design choice, needs a new isolation test. Needs GPU/model: no.

Reviewer notes

Verifier confirmed not_fixed (app.py:309 and all 7 siblings copy **os.environ; PR #4018 open, anyswe_agent only) and difficulty 3. Corrections: the formally referencing testcases are opencode_math, codex_math, pi_math (claude_code_math is observed-exposure only); and any env-sanitizing fix must preserve numpy/scipy/sympy for the math envs or they regress.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions