fix(onboard): select IPv4 sandbox fallback DNS and probe the same resolver - #7185
Conversation
…olver On a systemd-resolved host whose upstream resolver list is IPv6-first, detectSandboxFallbackDns() selected the IPv6 resolver (first-match) and Hermes Docker-driver recreation injected it via `docker run --dns <ipv6>`. Docker frequently cannot reach an IPv6 upstream from the container network path, so all sandbox DNS failed — while the container-DNS preflight probed with Docker defaults (no --dns) and falsely reported success. Two coupled fixes: - Restrict the compatibility DNS override to usable unicast IPv4 (ignore IPv6); return null when no IPv4 upstream exists so Docker defaults are preserved. Existing link-local (169.254.169.253) and private-resolver acceptance and loopback/unspecified/multicast rejection are unchanged. A capability-probed IPv6 path can be added separately. - Thread the selected resolver into probeContainerDns() via a validated `dnsServer` option so the preflight tests the exact `docker run --dns <ip>` path the recreated sandbox will use, and report it in diagnostics. The resolver is validated as an IP before shell interpolation. Adds regression coverage: IPv4-preferred-over-IPv6 selection, null for an IPv6-only upstream list, --dns injection into the probe, and the non-IP injection guard. Closes #7172 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Jason Ma <jama@nvidia.com>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe change narrows sandbox DNS fallback selection to usable IPv4 resolvers, adds resolver overrides to container DNS probes, and validates the exact fallback during sandbox recreation before stopping the original container. ChangesDNS fallback alignment
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Recreation
participant getDockerGpuCloneFallbackDns
participant probeContainerDns
participant Docker
Recreation->>getDockerGpuCloneFallbackDns: derive fallback resolver
getDockerGpuCloneFallbackDns-->>Recreation: IPv4 resolver or null
Recreation->>probeContainerDns: probe exact resolver
probeContainerDns->>Docker: docker run with optional --dns
Docker-->>probeContainerDns: DNS probe result
probeContainerDns-->>Recreation: success, warning, or fatal result
Recreation->>Docker: stop original container after non-fatal probe
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit 7bcbef2 in the TypeScript / code-coverage/cliThe overall coverage in commit 7bcbef2 in the Show a code coverage summary of the most impacted files.
Updated |
There was a problem hiding this comment.
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/bridge-dns-preflight.ts`:
- Around line 200-203: Update the fatal DNS failure output in the bridge DNS
preflight flow to append the existing testedResolverSuffix to its headline.
Reuse the suffix created alongside dnsIsFatal, while preserving the current
success and inconclusive message 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: 74c6c8e7-7314-47b2-802d-983a56bef3b8
📒 Files selected for processing (5)
src/lib/onboard/bridge-dns-preflight.tssrc/lib/onboard/docker-gpu-dns-fallback.test.tssrc/lib/onboard/docker-gpu-dns-fallback.tssrc/lib/onboard/preflight.test.tssrc/lib/onboard/preflight.ts
PR Review Advisor — InformationalAdvisor assessment: Informational / medium confidence Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
There was a problem hiding this comment.
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/preflight-dns-resolver-override.test.ts`:
- Around line 37-40: Strengthen the test for probeContainerDns by making
runCaptureImpl record whether it was invoked, then assert it was not called
after the invalid dnsServer input throws. Keep the existing IP-validation error
assertion and ensure the malicious resolver is rejected before reaching the
execution seam.
🪄 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: 1814ccb8-98e4-4495-b196-3fe452b78366
📒 Files selected for processing (6)
src/lib/onboard/bridge-dns-preflight.tssrc/lib/onboard/docker-gpu-patch-clone.tssrc/lib/onboard/docker-gpu-patch-recreate-dns.test.tssrc/lib/onboard/docker-gpu-patch-recreate.tssrc/lib/onboard/docker-gpu-patch-types.tssrc/lib/onboard/preflight-dns-resolver-override.test.ts
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
🌿 Preview your docs: https://nvidia-preview-pr-7185.docs.buildwithfern.com/nemoclaw |
|
CI diagnosis for exact head |
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
laitingsheng
left a comment
There was a problem hiding this comment.
Review summary
Verified the full change set at head 6f4b48c in a detached worktree. The fix narrows the compatibility DNS override to usable unicast IPv4, shares one selection function between preflight and clone construction, and probes the exact resolver before any destructive recreation.
Verified
- Solves #7172 —
isUsableUpstreamResolverrejects non-IPv4; IPv6-only upstream lists returnnulland preserve Docker defaults; link-local169.254.169.253retention intact. Covers the stated acceptance criteria. - Selection parity —
getDockerGpuCloneFallbackDns()is the single source of truth; clone construction and the recreation probe call it with the same options, so the probed resolver equals the injected--dns. ExplicitHostConfig.Dnsand host networking returnnullin both paths, with no duplicate or conflicting--dns. - Fatal-before-mutation — the recreation probe throws before
dockerStop; regression coverage asserts the original container is never stopped on a fatal result. - Injection guard —
dnsServeris validated withnet.isIPbefore shell-command construction and before the execution seam; the hardened test proves a malicious value never reachesrunCapture. - Behavioural tests — selection, parity, exact-command, non-IP rejection, and fatal ordering all assert on outputs, args, throws, and call state. The startup-command suite is isolated via a fallback-disabling helper and a deterministic clock.
- Docs —
troubleshooting.mdxdocuments IPv4 selection, the pre-mutation probe, IPv6-only default preservation, and explicit-DNS/host-network behaviour. - Discussion — both CodeRabbit inline findings addressed (fatal-suffix reworked to the clone-aware recreation point; resolver-rejection test hardened). No still-valid bot findings outstanding.
- CI — no red required checks; CLI shards, CodeQL, ShellCheck, sandbox image builds, commit-lint, and DCO all pass.
Design note: the global bridge preflight intentionally keeps probing Docker defaults, while the fallback-specific probe lives at the clone-aware recreation point where explicit-DNS and host-network suppression apply — documented in-line and consistent with the direction on the thread.
Approving.
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Refreshed this PR append-only onto current
Fresh exact-head/current-base CI, advisors, and E2E are running. |
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
|
Addressed the exact-head advisor coverage gap in Verified commit
Jason Ma remains credited as co-author. Fresh exact-head CI and automated review are running. |
Co-authored-by: Jason Ma <jama@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary This PR adds the canonical dated release entry for NemoClaw v0.0.94 before the tag is cut. The entry reconciles all 26 commits since v0.0.93 and links each user-visible change to its owning documentation. ## Changes - Add `docs/changelog/2026-07-24.mdx` with the exact `## v0.0.94` heading, parser-safe SPDX comment, release summary, and detailed bullets. - Record sandbox restore and update behavior, onboarding and inference changes, network policy behavior, security evidence, Hermes build performance, DGX Station guidance, and E2E validation changes. - Preserve `docs/` as the source of truth without changing the AI-agent documentation routing skill. - Use [E2E run 30075443016](https://github.com/NVIDIA/NemoClaw/actions/runs/30075443016) for release QA evidence at exact tested SHA `04e6dfa883071dda9df429c66e73168e1a995cba`. ### Source summary - [#7461](#7461) -> `docs/changelog/2026-07-24.mdx`: Record the ownership-preserving Hermes image layer reduction and hosted timing comparison. - [#7460](#7460) -> `docs/changelog/2026-07-24.mdx`: Record removal of candidate Hermes swap setup from E2E validation. - [#7458](#7458) -> `docs/security/fern-5.80.1-dependency-review.md`, `docs/changelog/2026-07-24.mdx`: Record the reviewed Fern CLI update. - [#7457](#7457) -> `docs/changelog/2026-07-24.mdx`: Record periodic runner-pressure telemetry. - [#7455](#7455) -> `docs/changelog/2026-07-24.mdx`: Record non-blocking absent Fern previews. - [#7450](#7450) -> `docs/changelog/2026-07-24.mdx`: Record stable cancellation handling for live-test child processes. - [#7449](#7449) -> `docs/changelog/2026-07-24.mdx`: Record parallel plugin EXDEV coverage. - [#7448](#7448) -> `docs/changelog/2026-07-24.mdx`: Record isolated long-running E2E lanes. - [#7444](#7444) -> `docs/changelog/2026-07-24.mdx`: Record exact-head Hermes swap validation. - [#7437](#7437) -> `docs/manage-sandboxes/backup-restore.mdx`, `docs/changelog/2026-07-24.mdx`: Record gateway pairing and authenticated verification after cross-sandbox restore. - [#7436](#7436) -> `docs/manage-sandboxes/backup-restore.mdx`, `docs/reference/commands.mdx`, `docs/changelog/2026-07-24.mdx`: Record selected stale-state cleanup and Hermes virtual-environment access repair. - [#7385](#7385) -> `docs/network-policy/customize-network-policy.mdx`, `docs/changelog/2026-07-24.mdx`: Record the read-only agent-variant route check. - [#7371](#7371) -> `docs/changelog/2026-07-24.mdx`: Record host-artifact verification for session exports. - [#7359](#7359) -> `docs/changelog/2026-07-24.mdx`: Record platform validation for managed vLLM model overrides. - [#7356](#7356) -> `docs/changelog/2026-07-24.mdx`: Record token-shaped value redaction for `sandbox doctor --json`. - [#7354](#7354) -> `docs/security/advisory-early-warning.md`, `docs/changelog/2026-07-24.mdx`: Record advisory correlation and retained audit provenance. - [#7352](#7352) -> `docs/network-policy/customize-network-policy.mdx`, `docs/network-policy/integration-policy-examples.mdx`, `docs/reference/commands.mdx`, `docs/changelog/2026-07-24.mdx`: Record preset reapplication and bounded `tls: skip` guidance. - [#7345](#7345) -> `docs/security/openclaw-2026.6.10-dependency-review.md`, `docs/security/openclaw-2026.7.1-dependency-review.md`, `docs/changelog/2026-07-24.mdx`: Record reviewed npm audit exception enforcement. - [#7340](#7340) -> `docs/network-policy/customize-network-policy.mdx`, `docs/changelog/2026-07-24.mdx`: Record the repaired CLI-reference route. - [#7334](#7334) -> `docs/get-started/dgx-station-preparation.mdx`, `docs/changelog/2026-07-24.mdx`: Record the qualified OTA metadata fallback and narrowed override wording. - [#7322](#7322) -> `docs/changelog/2026-07-24.mdx`: Reconcile the gateway source tag added to plugin registration banners. - [#7284](#7284) -> `docs/manage-sandboxes/update-sandboxes.mdx`, `docs/changelog/2026-07-24.mdx`: Record read-only `upgrade-sandboxes --check` behavior and recorded-gateway selection. - [#7277](#7277) -> `docs/changelog/2026-07-24.mdx`: Reconcile deterministic gateway TCP refusal coverage. - [#7234](#7234) -> `docs/reference/troubleshooting.mdx`, `docs/changelog/2026-07-24.mdx`: Record preserved DGX Spark managed vLLM Express intent on resume. - [#7185](#7185) -> `docs/reference/troubleshooting.mdx`, `docs/changelog/2026-07-24.mdx`: Record IPv4 fallback DNS selection and exact resolver probing. - [#6820](#6820) -> `docs/reference/commands.mdx`, `docs/changelog/2026-07-24.mdx`: Record the versioned, redacted `--events=jsonl` onboarding stream. ## 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 - [x] Existing tests cover changed behavior — justification: `npx vitest run test/changelog-docs.test.ts` passed 6/6 tests. - [ ] Tests not applicable — justification: - [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: `docs/changelog/2026-07-24.mdx`; the writing rules, documentation style, exact release range, skip terms, published routes, and product scope were reviewed; the changelog test passed 6/6; `npm run docs` passed with route checking OK, zero errors, and two existing warnings. - Agent: Codex Desktop <!-- docs-review-head-sha: 65368f9 --> <!-- docs-review-agents-blob-sha: 9c9b36d --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: Not applicable - Station profile/scenario: Not applicable - Result: Not applicable - Supporting evidence: Not applicable. This PR does not change `scripts/prepare-dgx-station-host.sh`. ## 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 check:diff` passed 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 test/changelog-docs.test.ts` passed 6/6 tests. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: Not applicable to the dated changelog entry. - [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). The build passed with zero errors and two existing Fern warnings. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only). Native dated changelog entries use the required parser-safe MDX SPDX comment and no frontmatter. --- Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added the v0.0.94 release changelog. * Documented improvements to sandbox snapshot and restore behavior. * Added updates for gateway selection, policy comparisons, onboarding event output, and DGX recovery workflows. * Documented enhanced diagnostics redaction, npm audit provenance, image assembly performance, and validation stability improvements. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Summary
On a systemd-resolved host whose upstream resolver list is IPv6-first, sandbox recreation could select an unreachable IPv6 fallback resolver and inject it into the recreated Docker sandbox. This change selects a usable unicast IPv4 fallback and validates that exact resolver immediately before destructive recreation, but only when the clone will actually inject the fallback. Explicit DNS and host-network sandboxes retain their existing behavior.
Related Issue
Closes #7172
Changes
--dnsargument cannot drift.docs/reference/troubleshooting.mdxwith the exact fallback selection, pre-mutation probe, IPv6-only default-preservation, and explicit-DNS/host-network behavior.Deliberate behavior change: IPv6 is no longer selected as a fallback candidate for this compatibility override. A future IPv6 path should be capability-probed separately.
Type of Change
Quality Gates
Documentation Writer Review
docs-updateddocs/reference/troubleshooting.mdxdocuments IPv4 fallback DNS selection, probing the exact--dnspath before recreation, preserving the original container on confirmed failure, IPv6-only behavior, and explicit-DNS/host-network exclusions.npm run docspassed with 0 errors and the 2 existing Fern warnings.Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docscompleted successfully (doc changes only) — 0 errors; 2 existing Fern warningsVerification detail
Signed-off-by: Jason Ma jama@nvidia.com
Summary by CodeRabbit