Skip to content

feat(browsecomp_advanced_harness): sandbox workspace tools and serve sessions - #5484

Merged
yaoyu-33 merged 11 commits into
mainfrom
yuya/gymint-161-browsecomp-harness-sessions
Nov 5, 2026
Merged

yaoyu-33 merged 11 commits into
mainfrom
yuya/gymint-161-browsecomp-harness-sessions

Conversation

@yaoyu-33

@yaoyu-33 yaoyu-33 commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stack: main → this PR → #5489 (sandboxed agent sessions and pairing configuration).

BrowseComp kept its workspace and metrics on the Resources Server, and bash_command interpreted model-generated commands in that host process. This change adds typed resources sessions and moves the existing pocketshell interpreter into a Resources-owned sandbox.

Behavior

  • Seed binds state to the resources session and task. Close is idempotent; closed sessions reject late tool calls. A failed stop or workspace removal retains ownership for a retried close, and server shutdown also closes retained sandboxes.
  • workspace: per_session requires an isolating sandbox_provider. The sandbox receives the checked-out shell source, retrieved pages and manifest. Search credentials, ground truth and verification remain on the Resources Server.
  • Commands use SandboxPythonRuntime and SandboxSession. Guards, supported commands, output truncation and exit-code formatting remain unchanged. Tool, verification and close operations are serialized per session.
  • Enroot startup checks the actual PID namespace and matching /proc before any model-directed command. Missing isolation rejects the session and uses the retained cleanup path. Older Enroot versions that silently ignore ENROOT_UNSHARE_PID are refused.
  • Provider metadata is merged with task metadata, startup files use cleanup-aware delivery, and every direct exec checks both process exit and provider error.
  • allow_host_execution: true is an explicit development compatibility option. There is no automatic host fallback. workspace: none still returns inline search/browse content without a tool sandbox.

The agent and Resources Server own separate containers in the full pairing. This works with providers that cannot serialize/reconnect a live sandbox. #5489 supplies the sandboxed agent and migrates both shipped pairings; this PR alone does not qualify the complete pairing. No separate issue is needed for this focused correction to the existing BrowseComp integration.

Validation

  • Resource-only tests: 214 passed on Python 3.13.14 before the PID guard; 25 focused sandbox tests passed afterward, including 10 new namespace/cleanup cases.
  • resources_servers/browsecomp_advanced_harness/.venv/bin/pytest resources_servers/browsecomp_advanced_harness/tests -q on the merged stack: 226 passed, including the child PR's timeout-verification cases.
  • Vendored pocketshell tests on Linux: 78 passed. The combined macOS run has the two previously reported BSD wc padding mismatches; assertions are unchanged.
  • Focused pre-commit and the merged stack's pre-commit run --all-files: passed.
  • Real Linux/Enroot component smoke: cat, grep and manifest access succeeded; installed source hashes matched the candidate, mount namespaces differed from the host, host credential files were inaccessible, and owned containers were removed.

After merging main and two review passes, at 33eeb9222682 (macOS, no Docker, so no sandbox smoke for these changes):

  • pytest resources_servers/browsecomp_advanced_harness/tests -q: 232 passed. The tests added in these passes fail on the previous code:
    • A /run seed starts no sandbox until the first bash_command, and a blocked command starts none at all.
    • A sandbox that cannot start, or cannot run a command, answers the [exit_code=-2] envelope instead of HTTP 500, without the provider's error text. /verify then keeps the judged reward but masks the sample (failure_kind: provider_unavailable).
    • A command the supervisor ends at its deadline answers [exit_code=-1], as the README says.
    • A missing provider block or an unknown sandbox_config key refuses the seed with 422 instead of a retryable 500.
  • scripts/component_locks.py with uv 0.13.4: 269 projects, 0 failed. The earlier lock and component-dependency CI failures came from opencode_search, which main fixed in build(opencode_search): add the missing component lock files #5629 and this branch now includes.
  • pytest tests/unit_tests/tooling/test_component_dependencies.py tests/unit_tests/test_public_api_facades.py tests/unit_tests/config/test_global_config.py on the merged stack: 1041 passed.
  • gym env resolve on benchmarks/browsecomp/config.yaml with the vLLM policy config: resolves, with the resources server's sandbox_provider: sandbox block (previously every seed got 422 until feat(browsecomp_agent): run the session harness inside a sandbox #5489 landed). On this PR alone the benchmark still runs browsecomp_agent's /run, so an aborted run keeps its sandbox until ttl_s; feat(browsecomp_agent): run the session harness inside a sandbox #5489 moves the benchmark onto the Environment Server path, which always closes.
  • pre-commit run --files on the changed files: passed.

Pairing evidence and remaining gate

The earlier functional cluster run completed five BrowseComp rows (0/5 correct) and two reasoning_gym rows (2/2 correct), including 20 real shell calls. System Enroot 3.4.1 did not provide PID isolation, so that run is functional evidence only.

Actual final-source diagnostics verified that both guards reject system Enroot 3.4.1 and accept a complete Enroot 4.2.1 runtime with separate PID namespaces and matching /proc. The nonsecret host sentinel is absent/unreadable from the new container and signal 0 returns ProcessLookupError.

The final merged source completed one unchanged BrowseComp row (reward 0) and one unchanged reasoning_gym row (reward 1) on Enroot 4.2.1, including 5 natural shell calls. #5489 records the model/search settings, old/new runtime evidence, Evaluation gaps and retained failed attempts. Usage/lifecycle accounting, owned-container cleanup and final exact-value credential scanning passed; temporary cluster keys were deleted. The final live audit covered the resource container and PID1, but did not catch the short-lived shell runner itself; all 5 tool outputs and exact source/exec-path namespace checks are retained. This PR is ready for maintainer CI/review.

The sandbox and session migration changes deployment requirements. It does not establish benchmark score parity; #5489 documents the failure-denominator and activation-time-limit changes.

An Environment Server seeds with ResourcesSeedSessionRequest and closes
with /close_session; the harness accepted neither, and its per-rollout
state (the per_session page workspace and the provider-call metrics) was
released only by /verify, and the metrics not at all.

- /seed_session takes the typed request, keyed by resources_session_id,
  and still takes an agent /run's flat row under the cookie session.
  A typed seed is refused with 422 when task_data lacks question or
  ground_truth, or when a workspace ID is not a plain directory name;
  a seed for another episode or after the close gets 409.
- /close_session removes the workspace and the metrics, idempotently,
  through ResourcesSessionFence. A failed removal raises and keeps the
  session for a retried close.
- A tool call for a closed session gets 404 (session_lost) instead of
  recreating its workspace.
- /verify drops the session's metrics entry after reporting it, unless
  dump_session_id_to_metrics_on_exit keeps it for the shutdown dump.

Refs GYMINT-161.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33 yaoyu-33 added feature New capabilities, enhancements, or enablement work area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers labels Nov 3, 2026
@copy-pr-bot

copy-pr-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@yaoyu-33

yaoyu-33 commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 8dbe563

Every server under the resources session contract answers a verify for
a closed session with lost_session_verification, including those whose
reward reads only the response, so a closed session reads the same
everywhere. single_agent_turn verifies before it closes, so the mask
only catches an out-of-order verify.

TavilySearchVerifyResponse now inherits BaseVerifyResponse so it can
carry mask_sample and failure_kind. A session the fence never recorded
as closed, such as an agent's /run or a caller that never seeds, is
graded as before.

Refs GYMINT-161.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33

yaoyu-33 commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test c78b6f4

yaoyu-33 and others added 2 commits November 3, 2026 19:58
…from nemo_gym.server_runtime

main removed nemo_gym.testing.session_conformance; the check now lives in the
server_runtime facade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
yaoyu-33 added a commit that referenced this pull request Nov 4, 2026
…rowsecomp_agent sessions branch

Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33

yaoyu-33 commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test d7a83fb

…urces-sandbox

Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33 yaoyu-33 changed the title feat(browsecomp_advanced_harness): serve typed resources sessions feat(browsecomp_advanced_harness): sandbox workspace tools and serve sessions Nov 4, 2026
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33
yaoyu-33 marked this pull request as ready for review November 4, 2026 20:31
@yaoyu-33
yaoyu-33 requested a review from a team as a code owner November 4, 2026 20:31
yaoyu-33 and others added 2 commits November 4, 2026 12:57
…keep the shell's error envelope

- benchmarks/browsecomp/config.yaml kept workspace: per_session with no sandbox_provider, so every seed got 422 until #5489 lands. Give the benchmark's resources server the Docker provider, as #5489 does.
- An agent's /run can end without /verify (browsecomp_agent does after a timeout), and only /verify releases that path's sandbox. Start the /run sandbox with the first bash_command instead of at the seed, so only a run that used the shell can hold one, and a failed start no longer strands the seed's workspace (the failed seed's cookie was dropped, so nothing could release it). Document the remaining gap.
- A command killed at the supervisor deadline, or a provider exec failure, answered HTTP 500. Answer with the host interpreter's [exit_code=-1] / [exit_code=-2] envelopes, as the README promises, and log the detail.
- Say that only Enroot is probed for isolation, and that providers such as Apptainer bind-mount the host's home and /tmp by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33

yaoyu-33 commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test ac48bc4

yaoyu-33 and others added 2 commits November 4, 2026 17:00
…res; refuse bad sandbox config

- A /run shell sandbox that cannot start now answers the [exit_code=-2]
  envelope instead of HTTP 500 with the provider's error text, and a
  blocked command answers before any sandbox starts.
- A session whose tool sandbox failed to start or run a command gets a
  masked sample at /verify (failure_kind provider_unavailable). The
  judged reward is kept.
- A command the supervisor ends at its deadline answers [exit_code=-1],
  as the README says, instead of -2.
- A missing provider block or an unknown sandbox_config key refuses the
  seed with 422 instead of a retryable 500.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33

yaoyu-33 commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 33eeb92

@yaoyu-33
yaoyu-33 enabled stacked auto-merge November 5, 2026 05:23
@yaoyu-33
yaoyu-33 added this pull request to the merge queue Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/41974035836

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/41975510114

Merged via the queue into main with commit 208197d Nov 5, 2026
67 of 70 checks passed
@yaoyu-33
yaoyu-33 deleted the yuya/gymint-161-browsecomp-harness-sessions branch November 5, 2026 05:55
yaoyu-33 added a commit that referenced this pull request Nov 5, 2026
Main now carries #5484 as a squash commit, so the files this branch's
#5484 fixes touch conflict in overlapping hunks; this branch's side is
#5484 plus those fixes and is kept. The agent picks up main's rename of
VLLMConverter to ChatCompletionsConverter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>

This branch was previously deployed

1 inactive deployment
public — 33eeb922 Deployed Nov 5, 2026 by copy-pr-bot[bot] via release / finalize / notify #10215
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers feature New capabilities, enhancements, or enablement work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants