Skip to content

fix(onboard): catch SandboxBaseImageResolutionError in build context staging (#8102) - #8193

Merged
prekshivyas merged 4 commits into
mainfrom
fix/hermes-base-image-override-clean-error-8102
Aug 4, 2026
Merged

fix(onboard): catch SandboxBaseImageResolutionError in build context staging (#8102)#8193
prekshivyas merged 4 commits into
mainfrom
fix/hermes-base-image-override-clean-error-8102

Conversation

@yanyunl1991

@yanyunl1991 yanyunl1991 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

When NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF is set to a non-tracked or unresolvable digest, resolveSandboxBaseImage throws a typed SandboxBaseImageResolutionError. In the fresh-onboard path this error propagated uncaught through ensureAgentBaseImagecreateAgentSandboxstageCreateSandboxBuildContextresolveSandboxBuildContext with no surrounding handler, causing Node.js to crash with a raw stack trace instead of a clean, single-line error.

Closes #8102.

Reproduction

Environment

  • Test machine: DGX Spark aarch64 test host (GB10 GPU)
  • NemoClaw main HEAD a5562015, Node v22.22.2

Observed on main (before fix)

export NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF=ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef0000...
nemoclaw onboard --agent hermes --non-interactive --yes --name qa-ovr --no-sandbox-gpu

  throw new SandboxBaseImageResolutionError(...)
        ^
SandboxBaseImageResolutionError: Hermes Agent sandbox base image override '...' could not be resolved
    at resolveSandboxBaseImage (.../dist/lib/sandbox-base-image.js:...)
    at resolveExactImage (.../dist/lib/agent/base-image.js:...)
    at ensureAgentBaseImage (.../dist/lib/agent/base-image.js:...)
Node.js v22.22.2

Observed on fix/... (after fix)

  Hermes Agent sandbox base image override 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef0000...' could not be resolved to an immutable trusted digest or failed required compatibility checks.
EXIT=1

Analysis

stageCreateSandboxBuildContext in src/lib/onboard/build-context-stage.ts calls input.createAgentSandbox(input.agent) at two points — the else if (input.agent) branch and the isSameFile(fromResolved, agentDockerfile) branch — with no try/catch. The rebuild preflight callers (rebuild-custom-image-preflight.ts, rebuild-managed-image-preflight.ts) already wrap stageCreateSandboxBuildContext in a broad catch (err) that returns { ok: false, detail: err.message }, so they are unaffected. The gap is exclusively in the fresh-onboard path, where prepared-dcode-rebuild.ts:resolveSandboxBuildContext calls stageCreateSandboxBuildContext and onboard.ts calls resolveSandboxBuildContext — neither has a surrounding handler for SandboxBaseImageResolutionError.

Because the throw originates inside ensureAgentBaseImage, before createAgentSandbox ever calls fs.mkdtempSync, no temporary build-context directory is created, so there is no cleanup gap on the failure path.

Fix

Import SandboxBaseImageResolutionError in build-context-stage.ts and wrap both input.createAgentSandbox(input.agent) call sites with a try/catch. On a SandboxBaseImageResolutionError, call the existing error() callback (the message already names the override ref and the specific rejection reason) and exit(1). Non-SandboxBaseImageResolutionError exceptions are re-thrown unchanged.

Three tests are added to the existing build-context-stage.test.ts:

  • Resolution error in the else if (input.agent) path → clean exit (the reporter's exact scenario).
  • Resolution error in the --from=<agent Dockerfile> path → clean exit.
  • Non-resolution error → re-thrown (regression lock).

Changes

  • src/lib/onboard/build-context-stage.ts: import SandboxBaseImageResolutionError; wrap both createAgentSandbox call sites
  • src/lib/onboard/build-context-stage.test.ts: add 3 tests for #8102

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)

Verification

  • npx prek run --all-files passes
  • npm test passes (touched files at minimum)
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

AI Disclosure

  • AI-assisted — tool: Claude Code

Signed-off-by: Yanyun Liao yanyunl@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved sandbox setup error handling by displaying a clear message when the base image cannot be resolved.
    • Sandbox creation now exits cleanly with status 1 for this specific issue, while unrelated errors continue to be handled normally.
    • Applies consistently to both generated and agent-provided Dockerfile configurations.
  • Tests
    • Added coverage for base image resolution failures and unrelated error handling across supported sandbox creation scenarios.

…staging (#8102)

When NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF is set to a non-tracked or
unresolvable digest, resolveSandboxBaseImage throws a typed
SandboxBaseImageResolutionError. In the fresh-onboard path, this error
propagated uncaught through ensureAgentBaseImage -> createAgentSandbox ->
stageCreateSandboxBuildContext -> resolveSandboxBuildContext with no
surrounding handler, causing Node.js to crash with a raw stack trace
instead of a clean, single-line error.

The rebuild preflight callers (rebuild-custom-image-preflight.ts and
rebuild-managed-image-preflight.ts) already wrap stageCreateSandboxBuildContext
in a broad catch, so they are unaffected. The gap is exclusively in the
fresh-onboard path via prepared-dcode-rebuild.ts.

Catch SandboxBaseImageResolutionError at both createAgentSandbox call sites
in stageCreateSandboxBuildContext, print the error message via the existing
error() callback (already human-readable: names the override ref and the
reason it was rejected), and call exit(1). Non-SandboxBaseImageResolutionError
exceptions are re-thrown unchanged. No buildCtx temp dir is created before
the throw, so there is no cleanup gap.

Fixes #8102

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: 6f491e07-67c0-4d3d-a1dd-b2b0b026ddcd

📥 Commits

Reviewing files that changed from the base of the PR and between aa6aeec and 3cc6be6.

📒 Files selected for processing (1)
  • src/lib/onboard/build-context-stage.test.ts

📝 Walkthrough

Walkthrough

Onboarding reports SandboxBaseImageResolutionError and exits with code 1 for both managed sandbox creation paths. Other errors continue to propagate unchanged. Tests cover both paths and temporary directory cleanup.

Changes

Sandbox resolution error handling

Layer / File(s) Summary
Handle sandbox resolution errors
src/lib/onboard/build-context-stage.ts
Both agent sandbox creation paths report SandboxBaseImageResolutionError and exit with code 1. Other errors are rethrown.
Validate error handling
src/lib/onboard/build-context-stage.test.ts
Tests cover generated sandboxes, --from Dockerfiles, temporary-directory cleanup, and propagation of unrelated errors.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Suggested labels: bug-fix, area: onboarding

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements clean error reporting and exit status 1, but it does not show that partial sandbox registration is removed. Add or verify cleanup that prevents a partial sandbox registration when base-image resolution fails.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the error-handling change in build-context staging.
Out of Scope Changes check ✅ Passed The implementation and tests support the linked issue, and temporary-directory changes address the related CodeQL finding.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/hermes-base-image-override-clean-error-8102

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

@github-code-quality

github-code-quality Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit c55ef87 in the fix/hermes-base-imag... branch remains at 96%, unchanged from commit 2fa1d22 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit c55ef87 in the fix/hermes-base-imag... branch remains at 81%, unchanged from commit 2fa1d22 in the main branch.

Show a code coverage summary of the most impacted files.
File main 2fa1d22 fix/hermes-base-imag... c55ef87 +/-
src/lib/shields/index.ts 69% 68% -1%
src/lib/onboard...ontext-stage.ts 94% 94% 0%
src/lib/sandbox...rce-identity.ts 88% 88% 0%

Updated August 04, 2026 11:05 UTC

@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: 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 `@src/lib/onboard/build-context-stage.test.ts`:
- Around line 373-400: Update the test around stageCreateSandboxBuildContext to
create a unique temporary directory with fs.mkdtempSync(), place
agent.Dockerfile inside it, and wrap the assertion and error checks in a
try/finally block. Remove the temporary directory recursively in finally so
cleanup is guaranteed even when an assertion fails, while preserving the
existing test behavior.
🪄 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: f90a211b-005c-40a3-8c20-b3e27dee612a

📥 Commits

Reviewing files that changed from the base of the PR and between a556201 and aa6aeec.

📒 Files selected for processing (2)
  • src/lib/onboard/build-context-stage.test.ts
  • src/lib/onboard/build-context-stage.ts

Comment on lines +373 to +400
const agentDockerfilePath = path.join(os.tmpdir(), "agent.Dockerfile");
fs.writeFileSync(agentDockerfilePath, "FROM scratch\n");
const errors: string[] = [];
const resolutionError = new SandboxBaseImageResolutionError(
"Hermes Agent sandbox base image override 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef' is outside the trusted repository 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base'.",
);

expect(() =>
stageCreateSandboxBuildContext({
root: "/repo",
fromDockerfile: agentDockerfilePath,
agent: {
name: "hermes",
displayName: "Hermes Agent",
dockerfilePath: agentDockerfilePath,
} as any,
createAgentSandbox: () => {
throw resolutionError;
},
log: vi.fn(),
error: (msg) => errors.push(msg),
exit: throwingExit,
}),
).toThrow("exit 1");

expect(errors).toEqual([` ${resolutionError.message}`]);
fs.rmSync(agentDockerfilePath, { force: true });
});

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use an isolated temporary directory and guaranteed cleanup.

Line 373 writes to a shared fixed path. Line 399 deletes that same path. Parallel tests or another process can have its file overwritten or removed. If an assertion fails, cleanup does not run.

Create a unique directory with fs.mkdtempSync() and remove it in finally.

Proposed fix
-    const agentDockerfilePath = path.join(os.tmpdir(), "agent.Dockerfile");
-    fs.writeFileSync(agentDockerfilePath, "FROM scratch\n");
-    const errors: string[] = [];
-    const resolutionError = new SandboxBaseImageResolutionError(
-      "Hermes Agent sandbox base image override 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef' is outside the trusted repository 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base'.",
-    );
+    const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "build-context-stage-"));
+    try {
+      const agentDockerfilePath = path.join(tempDir, "agent.Dockerfile");
+      fs.writeFileSync(agentDockerfilePath, "FROM scratch\n");
+      const errors: string[] = [];
+      const resolutionError = new SandboxBaseImageResolutionError(
+        "Hermes Agent sandbox base image override 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef' is outside the trusted repository 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base'.",
+      );
 
-    expect(() => /* existing assertion */).toThrow("exit 1");
-    expect(errors).toEqual([`  ${resolutionError.message}`]);
-    fs.rmSync(agentDockerfilePath, { force: true });
+      expect(() => /* existing assertion */).toThrow("exit 1");
+      expect(errors).toEqual([`  ${resolutionError.message}`]);
+    } finally {
+      fs.rmSync(tempDir, { recursive: true, force: true });
+    }

Based on learnings, temporary directories and files are resources that Vitest does not manage and must be cleaned up explicitly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const agentDockerfilePath = path.join(os.tmpdir(), "agent.Dockerfile");
fs.writeFileSync(agentDockerfilePath, "FROM scratch\n");
const errors: string[] = [];
const resolutionError = new SandboxBaseImageResolutionError(
"Hermes Agent sandbox base image override 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef' is outside the trusted repository 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base'.",
);
expect(() =>
stageCreateSandboxBuildContext({
root: "/repo",
fromDockerfile: agentDockerfilePath,
agent: {
name: "hermes",
displayName: "Hermes Agent",
dockerfilePath: agentDockerfilePath,
} as any,
createAgentSandbox: () => {
throw resolutionError;
},
log: vi.fn(),
error: (msg) => errors.push(msg),
exit: throwingExit,
}),
).toThrow("exit 1");
expect(errors).toEqual([` ${resolutionError.message}`]);
fs.rmSync(agentDockerfilePath, { force: true });
});
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "build-context-stage-"));
try {
const agentDockerfilePath = path.join(tempDir, "agent.Dockerfile");
fs.writeFileSync(agentDockerfilePath, "FROM scratch\n");
const errors: string[] = [];
const resolutionError = new SandboxBaseImageResolutionError(
"Hermes Agent sandbox base image override 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:deadbeef' is outside the trusted repository 'ghcr.io/nvidia/nemoclaw/hermes-sandbox-base'.",
);
expect(() =>
stageCreateSandboxBuildContext({
root: "/repo",
fromDockerfile: agentDockerfilePath,
agent: {
name: "hermes",
displayName: "Hermes Agent",
dockerfilePath: agentDockerfilePath,
} as any,
createAgentSandbox: () => {
throw resolutionError;
},
log: vi.fn(),
error: (msg) => errors.push(msg),
exit: throwingExit,
}),
).toThrow("exit 1");
expect(errors).toEqual([` ${resolutionError.message}`]);
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 373-373: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(agentDockerfilePath, "FROM scratch\n")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

🤖 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/build-context-stage.test.ts` around lines 373 - 400, Update
the test around stageCreateSandboxBuildContext to create a unique temporary
directory with fs.mkdtempSync(), place agent.Dockerfile inside it, and wrap the
assertion and error checks in a try/finally block. Remove the temporary
directory recursively in finally so cleanup is guaranteed even when an assertion
fails, while preserving the existing test behavior.

Source: Learnings

Comment thread src/lib/onboard/build-context-stage.test.ts Fixed
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / low confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: Same-session synthesis validation failed; the advisor result is incomplete.

Model lanes

  • GPT-5.6 Terra (primary): Completed · low confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions match; normalized E2E selections differ; severity counts match.
3 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • full-e2e: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • hermes-e2e: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • rebuild-hermes: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: onboard-repair, onboard-resume, cloud-onboard

Workflow run details

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

@apurvvkumaria apurvvkumaria self-assigned this Aug 4, 2026

@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.

lgtm on green

@cjagwani

cjagwani commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Exact-head blocker on d900cf4: CodeQL alert 1864 is still open at src/lib/onboard/build-context-stage.test.ts:374 (high severity, insecure temporary file). The test constructs a predictable path directly under the OS temp directory, and there is no author response or newer head yet. Please create a unique directory with fs.mkdtempSync, place agent.Dockerfile inside it, and guarantee recursive cleanup in a finally block as CodeRabbit also recommended. Then push a signed/verified commit and let CodeQL plus the advisor lanes rerun; the existing approval is explicitly conditional on green.

CodeQL flagged js/insecure-temporary-file (high) on the build-context
staging test: it created/referenced Dockerfiles at predictable, fixed
names directly under os.tmpdir() (`agent.Dockerfile` / `default.Dockerfile`),
which is symlink-race-prone. Route every staged-Dockerfile path through the
existing `makeTmpDir` helper (fs.mkdtempSync) so each lives in an
unpredictable, per-test directory that afterEach already cleans up. Covers
all five sites, matching the safe pattern the file already uses elsewhere.
No behavior change — these are mock fixtures and one real write in the

Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>
#8102 regression test.
@prekshivyas
prekshivyas merged commit 0abd14a into main Aug 4, 2026
60 of 62 checks passed
@prekshivyas
prekshivyas deleted the fix/hermes-base-image-override-clean-error-8102 branch August 4, 2026 11:44
apurvvkumaria added a commit that referenced this pull request Aug 4, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the canonical v0.0.102 release documentation from the current
release-labeled scope.
The change adds a dated changelog for all 38 user-facing shipping PRs
and corrects the OpenClaw agent command reference for the behavior
delivered by #8191.

## Changes

- Add `docs/changelog/2026-08-04.mdx` with the v0.0.102 release summary,
detailed behavior changes, support boundaries, security evidence links,
and links to durable documentation.
- Update `docs/reference/commands.mdx` to describe non-JSON OpenClaw
output capture, its combined limit, marker handling, stream suppression,
recovery guidance, and exit behavior.
- [#8167](#8167) ->
`docs/changelog/2026-08-04.mdx`: Records authenticated attachment of
operator-managed llama.cpp servers.
- [#8129](#8129) ->
`docs/changelog/2026-08-04.mdx`: Records the Experimental managed vLLM
profile for two DGX Spark systems.
- [#7983](#7983) ->
`docs/changelog/2026-08-04.mdx`: Records qualification of the May 2026
GB300WS factory image.
- [#8207](#8207) ->
`docs/changelog/2026-08-04.mdx`: Records the qualified DGX Station
driver transaction.
- [#8208](#8208) ->
`docs/changelog/2026-08-04.mdx`: Records mode-bound Express resume
state.
- [#8158](#8158) ->
`docs/changelog/2026-08-04.mdx`: Records recovery of host-global
dual-Station runtime ownership.
- [#8145](#8145) ->
`docs/changelog/2026-08-04.mdx`: Records Windows-host Ollama validation
from Docker Desktop's network context.
- [#8190](#8190) ->
`docs/changelog/2026-08-04.mdx`: Records HTTP model pulls when WSL has
no local Ollama executable.
- [#8195](#8195) ->
`docs/changelog/2026-08-04.mdx`: Records reuse of a healthy
installer-managed CLI.
- [#8053](#8053) ->
`docs/changelog/2026-08-04.mdx`: Records early rejection of incompatible
OpenShell gateway versions.
- [#8098](#8098) ->
`docs/changelog/2026-08-04.mdx`: Records the bounded
package-service-to-standalone gateway recovery transition.
- [#8216](#8216) ->
`docs/changelog/2026-08-04.mdx`: Records the final dashboard port
selected during multi-sandbox onboarding.
- [#8146](#8146) ->
`docs/changelog/2026-08-04.mdx`: Records managed startup-state
restoration for stopped sandboxes.
- [#8092](#8092) ->
`docs/changelog/2026-08-04.mdx`: Records gateway watchdog recovery for
classified not-serving states.
- [#8182](#8182) ->
`docs/changelog/2026-08-04.mdx`: Records consistent managed-recovery
wait configuration.
- [#8040](#8040) ->
`docs/changelog/2026-08-04.mdx`: Records Docker sandbox rollback
authority through late validation.
- [#8130](#8130) ->
`docs/changelog/2026-08-04.mdx`: Records bounded Shields deadline
recovery and durable containment.
- [#8086](#8086) ->
`docs/changelog/2026-08-04.mdx`: Records repair of narrowly validated
permission-only configuration drift.
- [#8122](#8122) ->
`docs/changelog/2026-08-04.mdx`: Records prompt failure and guidance for
corrupt transition locks.
- [#8124](#8124) ->
`docs/changelog/2026-08-04.mdx`: Records policy restoration flags,
previews, and target revalidation.
- [#7886](#7886) ->
`docs/changelog/2026-08-04.mdx`: Records explicit destruction after
pre-delete Shields hardening failures while preserving recovery
authority.
- [#7901](#7901) ->
`docs/changelog/2026-08-04.mdx`: Records multi-port uninstall behavior
and shared-resource preservation.
- [#7984](#7984) ->
`docs/changelog/2026-08-04.mdx`: Records one classified transient remote
MCP startup retry.
- [#7954](#7954) ->
`docs/changelog/2026-08-04.mdx`: Records bounded hosted-inference probe
replies.
- [#7574](#7574) ->
`docs/changelog/2026-08-04.mdx`: Records preservation of validated
reasoning capabilities through onboarding.
- [#8089](#8089) ->
`docs/changelog/2026-08-04.mdx`: Records proxy routing for Hermes
WhatsApp pairing and media traffic.
- [#7682](#7682) ->
`docs/changelog/2026-08-04.mdx`: Records native Hermes session deletion
and identifier validation.
- [#8150](#8150) ->
`docs/changelog/2026-08-04.mdx`: Records corporate CA trust for
LangChain Deep Agents Code image builds.
- [#8156](#8156) ->
`docs/changelog/2026-08-04.mdx`: Records reviewed managed runtime
dependency remediation.
- [#8180](#8180) ->
`docs/changelog/2026-08-04.mdx`: Records reviewed MCP discovery runtime
dependency updates.
- [#8196](#8196) ->
`docs/changelog/2026-08-04.mdx`: Records private npm dependency
remediation across managed images.
- [#8203](#8203) ->
`docs/changelog/2026-08-04.mdx`: Records reviewed Hermes and LangChain
Deep Agents Code Python dependency updates.
- [#8125](#8125) ->
`docs/changelog/2026-08-04.mdx`: Records bounded diagnostics for invalid
enumerated CLI values.
- [#8193](#8193) ->
`docs/changelog/2026-08-04.mdx`: Records bounded diagnostics for
unresolved sandbox base images.
- [#8118](#8118) ->
`docs/changelog/2026-08-04.mdx`: Records bounded diagnostics for changed
gateway authority.
- [#8191](#8191) ->
`docs/changelog/2026-08-04.mdx`, `docs/reference/commands.mdx`: Records
output capture, marker handling, recovery guidance, and exit behavior
for non-JSON OpenClaw agent commands.
- [#8187](#8187) ->
`docs/changelog/2026-08-04.mdx`: Records the aligned
interactive-installation start across supported agents.
- [#8153](#8153) ->
`docs/changelog/2026-08-04.mdx`: Records current product capabilities
and support boundaries.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] 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:
- [x] Tests not applicable — justification: This documentation-only
release preparation does not change executable behavior. Existing
changelog and published-route tests pass.
- [x] 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:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: Independently reviewed `docs/changelog/2026-08-04.mdx` and
`docs/reference/commands.mdx` at commit `b89913780`. All 38 user-facing
v0.0.102 PRs are represented, #8191 behavior matches the implementation,
and the writing rules, documentation style, controlled terminology,
route structure, and skip policy pass review. Targeted tests pass 36/36
and the documentation build completes with 0 errors.
- Agent: Codex Desktop independent documentation writer
<!-- docs-review-head-sha: b899137 -->
<!-- docs-review-agents-blob-sha: 3dd7c24 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable
- Station profile/scenario: Not applicable
- Result: Not applicable
- Supporting evidence: Not applicable

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run --project integration
test/changelog-docs.test.ts test/check-docs-published-routes.test.ts`
passed 36/36.
- [x] Applicable broad gate passed — not applicable to
documentation-only changes; `npm run docs` completed successfully with 0
errors.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors and 2 existing Fern warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [x] New doc pages include SPDX header and frontmatter (new pages only)
— the native dated changelog uses the required parser-safe MDX SPDX
comment and intentionally has no frontmatter.

---
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.102, covering authentication, hardware
setup, WSL, installer recovery, sandbox resilience, policy management,
inference reliability, CLI improvements, and unified quickstarts.
- Updated command documentation to explain how non-JSON agent output is
collected, replayed, and reported.

- **Bug Fixes**
- Improved command-output recovery guidance when output exceeds limits
or contains unsupported fallback markers.
- Preserved accurate command exit-status reporting after output
processing.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@wscurran wscurran added the bug-fix PR fixes a bug or regression label Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DGX Spark][Onboard] Hermes base-image override rejection throws an uncaught SandboxBaseImageResolutionError stack trace instead of a clean error

7 participants