Skip to content

test(e2e): verify disabled Jetson sandbox GPU access - #8875

Merged
cv merged 10 commits into
mainfrom
codex/fix-e2e-jetson-run-31571534932
Aug 12, 2026
Merged

test(e2e): verify disabled Jetson sandbox GPU access#8875
cv merged 10 commits into
mainfrom
codex/fix-e2e-jetson-run-31571534932

Conversation

@sandl99

@sandl99 sandl99 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Issue #7610 prevents CUDA verification for a non-root user through OpenShell on the tested Jetson configuration. This PR sets NEMOCLAW_SANDBOX_GPU=0 for the existing Jetson live E2E test. The test verifies CPU-only onboarding and confirms that the sandbox excludes /dev/nvmap.

This PR does not add Jetson GPU support. The Jetson GPU implementation remains separate until issue #7610 is resolved and maintainers accept its product scope.

Related Issue

Related to #7610. This PR does not resolve or close that issue.

Changes

  • Configure the jetson-nvmap-gpu live E2E test with NEMOCLAW_SANDBOX_GPU=0.
  • Require installation and status to report that sandbox GPU access is disabled.
  • Require the sandbox to exclude /dev/nvmap, including symbolic links.
  • Remove CUDA and Jetson device-group requirements from this CPU-only test.
  • Document the tested behavior and the claims that the result does not establish.

install.sh does not accept --no-gpu. The test uses NEMOCLAW_SANDBOX_GPU=0, which selects the same CPU-only onboarding behavior.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: The review found no production, policy, credential, dependency, or privilege changes. The live E2E test requires the CPU-only sandbox to exclude /dev/nvmap.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: test/e2e/docs/jetson-dispatch.md and test/e2e/live/jetson-nvmap-gpu.test.ts; no blocking findings or further edits required.
  • Agent: Codex Desktop

Jetson E2E Evidence

  • Run 31614984721 tested commit a2624a3547d60c8817b6134ce166edaacf7b13dd on an NVIDIA Jetson AGX Thor Developer Kit. The device reported Jetson Linux R39 revision 2.1 and kernel 6.8.12-1021-tegra.
  • All seven phases passed. Installation and status reported that sandbox GPU access was disabled. The sandbox command returned absent:/dev/nvmap. Cleanup removed the NemoClaw sandbox, OpenShell sandbox, and OpenShell gateway without failures.
  • This evidence verifies CPU-only onboarding for the named commit and device. It does not verify CUDA or Jetson GPU support.

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every published commit appears as Verified in GitHub
  • The normal pre-commit, commit-msg, and pre-push hooks passed for commit a2624a3547d60c8817b6134ce166edaacf7b13dd.
  • Targeted behavior tests pass for the commit under review — npm run test:e2e-phases:check passed for 125 tests across 81 files; the live target skipped on a non-Jetson host and released its registered resources; the docs build completed with 0 errors and 2 pre-existing warnings.
  • Applicable broad gate passed — all applicable GitHub checks passed for commit a2624a3547d60c8817b6134ce166edaacf7b13dd, including 12 CLI test shards, CodeQL, CodeRabbit, and both PR review advisors.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only) — the docs build completed with 0 errors and 2 pre-existing warnings.
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: San Dang sdang@nvidia.com
Signed-off-by: Charan Jagwani cjagwani@nvidia.com

Signed-off-by: San Dang <sdang@nvidia.com>
@sandl99 sandl99 self-assigned this Aug 12, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a75266fb-024d-466d-9326-903cc213fe21

📥 Commits

Reviewing files that changed from the base of the PR and between 7b0d091 and 6819099.

📒 Files selected for processing (1)
  • test/e2e/docs/jetson-dispatch.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/docs/jetson-dispatch.md

📝 Walkthrough

Walkthrough

The change adds Jetson device detection, GPU policy grants, and a root-owned device-group bootstrap helper. Sandbox creation and recreation propagate group-preservation settings. Tests cover helper validation, image packaging, policy behavior, workflow changes, and CPU-only Jetson fallback.

Changes

Jetson GPU support

Layer / File(s) Summary
Tegra detection and GPU policy
src/lib/onboard/docker-gpu-jetson-groups.ts, src/lib/onboard/initial-policy.ts, src/lib/onboard/*test.ts
Valid Tegra character devices require a real /dev/nvmap anchor. OpenClaw policies grant detected devices read-write access and /opt/nvidia read-only access.
Bootstrap helper and image payload
scripts/jetson-device-group-bootstrap.sh, Dockerfile, src/lib/sandbox/build-context.ts, test/*
The root-only helper validates GIDs, group records, the sandbox user, and supervisor arguments before updating membership and executing the supervisor. The image packages it as a root-owned mode 500 file.
Onboarding option propagation
src/lib/onboard/docker-startup-command-*, src/lib/onboard/docker-gpu-*, src/lib/onboard/sandbox-*
OpenClaw startup-command and sandbox creation paths propagate preserveJetsonDeviceGroupMembership. Tests verify agent-specific selection and native creation wiring.
Clone and recreation handoff
src/lib/onboard/docker-gpu-patch-*, src/lib/onboard/managed-bootstrap/*, src/lib/onboard/docker-startup-command-patch.test.ts
Supplementary GIDs are normalized, deduplicated, and bounded to 16 entries. The bootstrap entrypoint receives them when preservation is enabled. Recreation checks helper availability before stopping the original container.
Compatibility validation
docs/reference/troubleshooting.mdx, test/e2e/live/jetson-nvmap-gpu.test.ts, test/e2e/docs/jetson-dispatch.md, .github/workflows/*
Troubleshooting guidance documents group propagation, access restrictions, supervisor requirements, and CUDA limitations. Live coverage validates CPU-only fallback onboarding and disabled GPU reporting.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested labels: platform: jetson, area: onboarding, area: security, platform: container, bug-fix

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the updated Jetson E2E test, but it does not identify the primary change: preserving device groups during sandbox recreation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-e2e-jetson-run-31571534932

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit a2624a3 in the codex/fix-e2e-jetson... branch remains at 96%, unchanged from commit 971811c in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit a2624a3 in the codex/fix-e2e-jetson... branch remains at 82%, unchanged from commit 971811c in the main branch.

Show a code coverage summary of the most impacted files.
File main 971811c codex/fix-e2e-jetson... a2624a3 +/-
src/lib/cua/bounded-file.ts 94% 84% -10%
src/lib/cua/run...ime-manifest.ts 91% 84% -7%
src/lib/cua/contract.ts 87% 80% -7%
src/lib/trace.ts 94% 90% -4%
src/lib/inferen...ollama/proxy.ts 36% 33% -3%
src/lib/state/o...d-checkpoint.ts 90% 87% -3%
src/lib/onboard...press-resume.ts 78% 82% +4%
src/lib/securit...ntial-filter.ts 91% 95% +4%
src/lib/onboard...der/snapshot.ts 75% 83% +8%
src/lib/actions...ocker-health.ts 61% 78% +17%

Updated August 12, 2026 16:04 UTC

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · medium confidence · 0 blockers · 1 warning · 1 suggestion
  • Model comparison: normalized findings differ; normalized terminology decisions differ; normalized E2E selections match; Nemotron reported the same number of blockers, 1 more warning, 1 more suggestion.
1 terminology difference from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • Jetson hardware target at test/e2e/docs/jetson-dispatch.md:139: selected only by the second-opinion lane as define.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

4 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — CPU-only onboarding at test/e2e/docs/jetson-dispatch.md:165: Use CPU-only onboarding for the GPU-disabled onboarding path.
  • established — sandbox GPU access at test/e2e/docs/jetson-dispatch.md:143: Use sandbox GPU access for GPU availability inside the sandbox.
  • established — commit under review at test/e2e/docs/jetson-dispatch.md:140: Use commit under review for the revision evaluated by the test evidence.
  • justified — Jetson job workspace at test/e2e/docs/jetson-dispatch.md:151: Use Jetson job workspace where the dispatch-specific workspace boundary matters.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

Manual-only E2E: cloud-inference, cloud-onboard, security-posture
The manual PR workflow does not run these selectors for the commit under review. Run them from reviewed code on main.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

Signed-off-by: San Dang <sdang@nvidia.com>
@sandl99 sandl99 changed the title fix(onboard): preserve Jetson GPU access fix(onboard): preserve Jetson device groups Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@sandl99
sandl99 marked this pull request as ready for review August 12, 2026 09:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/lib/onboard/initial-policy.test.ts (1)

362-383: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a negative case that proves no Jetson grant appears without device paths.

The suite covers the grant path. It does not prove the fail-closed default. Without a negative case, a future change that pushes /opt/nvidia unconditionally would still pass.

Add an assertion that buildDirectGpuPolicyYaml omits /opt/nvidia when jetsonGpuDevicePaths is empty or absent.

💚 Proposed negative-case coverage
+  it("omits Jetson grants when no device paths are detected (`#7610`)", () => {
+    const gpuDoc = YAML.parse(buildDirectGpuPolicyYaml(BASE_POLICY_FIXTURE, {}));
+
+    expect(gpuDoc.filesystem_policy.read_only).not.toContain("/opt/nvidia");
+    expect(gpuDoc.filesystem_policy.read_write).not.toContain("/opt/nvidia");
+  });
🤖 Prompt for 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.

In `@src/lib/onboard/initial-policy.test.ts` around lines 362 - 383, Add a
negative test for buildDirectGpuPolicyYaml with jetsonGpuDevicePaths empty or
omitted, and assert the generated filesystem_policy.read_only does not contain
/opt/nvidia. Keep the existing positive Jetson-device grant test unchanged.
🤖 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 `@src/lib/onboard/initial-policy.test.ts`:
- Around line 403-409: Strengthen the Hermes filesystem exclusion assertion by
checking each entry in devicePaths individually with a per-path negative
containment assertion, ensuring no device path is leaked. Move the
defaultOpenclaw and hermes cleanup calls into an unconditional teardown hook so
temporary policy files are removed even when earlier assertions fail.

In `@src/lib/onboard/sandbox-gpu-create-run-attempt.ts`:
- Line 150: Thread input.preserveJetsonDeviceGroupMembership through the managed
replacement boundary into createLifecycle, ensuring native Jetson recreation
receives the preservation intent and includes the required Tegra groups in
startup-command. Preserve existing compatibility-route behavior and add a native
Jetson test covering the propagated option and resulting groups.

In `@test/e2e/live/jetson-nvmap-gpu.test.ts`:
- Around line 179-181: Update the host prerequisite assertion in the test around
hostNvmap to run `test -c /dev/nvmap` instead of relying on `ls -l`, while
preserving the existing exit-code and diagnostic assertion so the check only
passes for a character device.

In `@test/jetson-device-group-bootstrap.test.ts`:
- Around line 276-286: Update the WSL Vitest lane configuration to provision
Docker and pull the exact FIXTURE_BASE_IMAGE digest before running the suite,
ensuring the Docker build in the test around dockerSpawnSync succeeds;
alternatively, explicitly exclude test/jetson-device-group-bootstrap.test.ts
from that lane.

---

Nitpick comments:
In `@src/lib/onboard/initial-policy.test.ts`:
- Around line 362-383: Add a negative test for buildDirectGpuPolicyYaml with
jetsonGpuDevicePaths empty or omitted, and assert the generated
filesystem_policy.read_only does not contain /opt/nvidia. Keep the existing
positive Jetson-device grant test unchanged.
🪄 Autofix

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: d35f1127-e268-4f26-b75c-9b199b7b1e64

📥 Commits

Reviewing files that changed from the base of the PR and between ba0fbfc and 5db705b.

📒 Files selected for processing (31)
  • Dockerfile
  • docs/reference/troubleshooting.mdx
  • scripts/jetson-device-group-bootstrap.sh
  • src/lib/onboard/docker-gpu-jetson-groups.test.ts
  • src/lib/onboard/docker-gpu-jetson-groups.ts
  • src/lib/onboard/docker-gpu-patch-clone.ts
  • src/lib/onboard/docker-gpu-patch-jetson.test.ts
  • src/lib/onboard/docker-gpu-patch-recreate.ts
  • src/lib/onboard/docker-gpu-patch-types.ts
  • src/lib/onboard/docker-gpu-patch.ts
  • src/lib/onboard/docker-gpu-sandbox-create.ts
  • src/lib/onboard/docker-startup-command-agent.test.ts
  • src/lib/onboard/docker-startup-command-agent.ts
  • src/lib/onboard/docker-startup-command-patch.test.ts
  • src/lib/onboard/docker-startup-command-patch.ts
  • src/lib/onboard/docker-startup-command-sandbox-create.ts
  • src/lib/onboard/initial-policy.test.ts
  • src/lib/onboard/initial-policy.ts
  • src/lib/onboard/sandbox-create-step.ts
  • src/lib/onboard/sandbox-gpu-create-flow.test.ts
  • src/lib/onboard/sandbox-gpu-create-flow.ts
  • src/lib/onboard/sandbox-gpu-create-run-attempt.ts
  • src/lib/sandbox/build-context.ts
  • test/e2e/docs/jetson-colossus-dispatch.md
  • test/e2e/live/jetson-nvmap-gpu.test.ts
  • test/helpers/vitest-watch-triggers.ts
  • test/jetson-device-group-bootstrap.test.ts
  • test/openclaw-final-image-layout.test.ts
  • test/sandbox-build-context.test.ts
  • test/sandbox-provisioning-helper-permissions.test.ts
  • test/vitest-watch-triggers.test.ts

Comment thread src/lib/onboard/initial-policy.test.ts Outdated
Comment thread src/lib/onboard/sandbox-gpu-create-run-attempt.ts Outdated
Comment thread test/e2e/live/jetson-nvmap-gpu.test.ts Outdated
Comment thread test/jetson-device-group-bootstrap.test.ts Outdated

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/lib/onboard/sandbox-gpu-create-run-attempt.ts:150 forwards preserveJetsonDeviceGroupMembership only to the non-managed patch factory. When input.managedBootstrap exists, runtimePatch instead uses managedLifecycle.patch, but the lifecycle input and src/lib/onboard/managed-bootstrap/docker-runtime.ts do not receive or apply this option. Managed OpenClaw Jetson recreation can therefore omit the bootstrap entrypoint and detected device groups, reproducing the access failure this PR intends to fix. Thread the preservation intent through the managed lifecycle contract and managed Docker replacement, then add a regression test that creates the managed lifecycle for native Jetson OpenClaw and asserts the bootstrap entrypoint and detected groups. The test at src/lib/onboard/sandbox-gpu-create-flow.test.ts:565 mocks the non-managed factory, so it passes without exercising this route; the CPU-only Jetson E2E also cannot detect the regression.

@copy-pr-bot

copy-pr-bot Bot commented Aug 12, 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.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
sandl99 and others added 2 commits August 12, 2026 17:40
@cjagwani cjagwani self-assigned this Aug 12, 2026
@cjagwani
cjagwani requested a review from cv August 12, 2026 14:16
@wscurran wscurran added area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression platform: jetson Affects Jetson AGX Thor or Orin labels Aug 12, 2026
Remove the Jetson GPU implementation from this PR while #7610 remains open.

Keep only the CPU-only live target and its documented acceptance boundary.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani cjagwani changed the title fix(onboard): preserve Jetson device groups test(e2e): qualify Jetson CPU fallback Aug 12, 2026
@cjagwani

Copy link
Copy Markdown
Collaborator

@cv, your requested managed Jetson recreation change is now addressed by scope: #8875 no longer contains the GPU implementation or any managed-recreation changes. Its net diff is only the CPU-only Jetson live target and runbook. The GPU work is being moved to a separate draft PR blocked on #7610, where your managed native-recreation finding remains a requirement.

Exact head c40d488c9e4e67d3c45eec6679909bc9d5039905 passed the trusted Jetson run 31610078886: sandbox GPU was disabled, /dev/nvmap was absent inside the sandbox, and cleanup succeeded. The current-head CI and automated review are also green.

Would you please take a fresh independent review of this CPU-only scope?

@cv

cv commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

@cjagwani your agent's use of the expression "exact-head" indicates it hasn't read or decided not to follow writing, comms and docs guidelines, which further indicates it's not following other instructions and guidelines as well. Please have it re-evaluate this entire PR and consider rewriting.

Replace workflow shorthand with repository terms.

Apply the terms to the Jetson test and its controller documentation.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Describe the remote workspace used by the Jetson controller.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani cjagwani changed the title test(e2e): qualify Jetson CPU fallback test(e2e): verify disabled Jetson sandbox GPU access Aug 12, 2026
@cjagwani

Copy link
Copy Markdown
Collaborator

@cv, I re-evaluated the complete PR against WRITING.md, the controlled word list, docs/CONTRIBUTING.md, CONTRIBUTING.md, and the product scope gate.

I made these corrections:

  • Replaced internal workflow shorthand with repository terms, including commit under review and latest PR commit.
  • Renamed the test and phases to state the observed behavior.
  • Rewrote the controller documentation and PR description to separate verification from product support.
  • Corrected “GitHub Actions job workspace” to “Jetson job workspace.”
  • Confirmed that the complete PR diff contains only the CPU-only live E2E test and its controller documentation.

All applicable GitHub checks pass for the latest PR commit, a2624a3547d60c8817b6134ce166edaacf7b13dd. Jetson run 31614984721 tested that commit on an NVIDIA Jetson AGX Thor Developer Kit. All seven phases passed, /dev/nvmap was absent from the sandbox, and cleanup completed without failures.

The GPU implementation remains outside this PR. Issue #7610 remains unresolved. Would you review the CPU-only scope again?

@cv
cv merged commit 035261c into main Aug 12, 2026
80 checks passed
@cv
cv deleted the codex/fix-e2e-jetson-run-31571534932 branch August 12, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression platform: jetson Affects Jetson AGX Thor or Orin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants