Skip to content

fix(onboard): pin openshell fetch to blueprint max_openshell_version (#3404)#3446

Merged
jyaunches merged 9 commits into
NVIDIA:mainfrom
Dongni-Yang:fix/installer-pin-openshell-max-3404
May 13, 2026
Merged

fix(onboard): pin openshell fetch to blueprint max_openshell_version (#3404)#3446
jyaunches merged 9 commits into
NVIDIA:mainfrom
Dongni-Yang:fix/installer-pin-openshell-max-3404

Conversation

@Dongni-Yang

@Dongni-Yang Dongni-Yang commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #3404. The reactive bump of max_openshell_version in nemoclaw-blueprint/blueprint.yaml keeps QA installs working today, but the same bug recurs on every subsequent OpenShell release because both the blueprint pin and the shell installer's hardcoded version constants would need to be bumped in lockstep.

This PR makes nemoclaw-blueprint/blueprint.yaml the single source of truth for the OpenShell version envelope:

  • Pure resolver in src/lib/onboard/openshell-install.ts:
    • parseOpenshellReleaseTag(tag) — boundary-safe parse (strips leading v, rejects empty / leading-- / non-X.Y.Z).
    • resolveOpenshellInstallVersion(available, { max }, { versionGte }) — pure picker returning one of pin / no-max / incompatible.
  • Orchestrator in src/lib/onboard/openshell-pin.ts:
    • listOpenshellReleaseTags() — paginated GitHub release fetch (gh release list --limit 1000, falling back to a paginated curl https://api.github.com/repos/NVIDIA/OpenShell/releases?per_page=100&page=N). Pagination addresses CodeRabbit's "once the repo exceeds 100 releases" concern. Any per-page failure returns null (not a partial list), so a page-2+ outage cannot hide an older compatible release and falsely produce incompatible.
    • resolveOpenshellInstallPin(deps) — wires the fetch into the resolver. On any fetch failure (offline, gh missing, rate-limited) it returns no-max so the shell installer falls back to its hardcoded pin — no regression vs. main.
    • computeOpenshellInstallEnv(baseEnv, deps) — overlays NEMOCLAW_OPENSHELL_MIN_VERSION / NEMOCLAW_OPENSHELL_MAX_VERSION / NEMOCLAW_OPENSHELL_PIN_VERSION onto the spawn env from the blueprint.
    • runOpenshellInstall(deps) — the body of the former in-line installOpenshell lives here so src/lib/onboard.ts shrinks rather than grows.
  • Shell installer scripts/install-openshell.sh:
    • Honours the three env overrides (MIN_VERSION, MAX_VERSION, PIN_VERSION) only on the stable channel — dev installs use RELEASE_TAG=dev and DEV_MIN_VERSION, so a malformed override no longer aborts a dev install (CodeRabbit minor).
    • Validates each override against ^[0-9]+\.[0-9]+\.[0-9]+$ and fails fast with a clear error naming the offending env var.
    • PIN and MAX are intentionally independent: a NEMOCLAW_OPENSHELL_MAX_VERSION override does not silently update PIN_VERSION. The TS resolver sets PIN_VERSION only when it confidently picked an existing published release; if the fetch failed, the script's hardcoded PIN_VERSION stays as the known-good fallback (CodeRabbit major).
  • Blueprint pin unchangedmax_openshell_version: "0.0.39" in main is the source of truth.

Verification matrix

Scenario Pre-PR behaviour Post-PR behaviour
Fresh install, online, blueprint max=0.0.39, latest=0.0.38 fetch 0.0.39 (hardcoded PIN) resolver pins to 0.0.38 (latest ≤ max), shell honours env
Fresh install, online, blueprint max=0.0.39, latest=0.0.42 (current real world) fetch 0.0.39 (hardcoded PIN) resolver pins to 0.0.39 (highest ≤ max), logs latest 0.0.42 exceeds blueprint max 0.0.39
Fresh install, online, blueprint bumped to e.g. 0.0.42 would still fetch 0.0.39 unless shell PIN/MAX also bumped — bug resolver pins to 0.0.42 + shell MIN/MAX env-overridden to 0.0.42 — single bump suffices
QA repro: latest=0.0.38, max=0.0.36 fetch 0.0.38, post-install gate fails resolver pins to highest ≤ 0.0.36, installs cleanly
No published release ≤ max fetch latest, gate fails late fails early with latest=…, max=… in the message
Blueprint missing/malformed max n/a resolver returns no-max → shell uses hardcoded — same as main
GitHub unreachable / gh missing / rate-limited n/a listing returns null → resolver returns no-max → shell uses hardcoded — same as main
Dev channel install (NEMOCLAW_OPENSHELL_CHANNEL=dev) ignore PIN_VERSION, RELEASE_TAG=dev shell now skips all three env overrides on dev — same observable behaviour

Unit tests cover the four required cases plus the widened MIN/MAX overlay and the runOpenshellInstall orchestrator (test/onboard.test.tsresolveOpenshellInstallVersion (#3404), resolveOpenshellInstallPin (#3404 orchestrator), computeOpenshellInstallEnv overlays MIN/MAX/PIN (#3404 widening)).

Entrypoint budget

src/lib/onboard.ts shrinks by 19 net lines (the bulk of installOpenshell moves into src/lib/onboard/openshell-pin.ts). The onboard-entrypoint-budget check is satisfied.

Test plan

  • npm run build:cli
  • npm run typecheck + npm run typecheck:cli
  • npx vitest run test/onboard.test.ts — 235 passed (17 new)
  • shellcheck scripts/install-openshell.sh
  • shfmt -i 2 -ci -bn -d scripts/install-openshell.sh
  • src/lib/onboard.ts net delta -19 lines (entrypoint budget passes)
  • Reproduced issue [DGX Spark][Install] openshell 0.0.38 above NemoClaw max-supported 0.0.36 — install fails #3404 locally against the real OpenShell release timeline (v0.0.36 shipped 2026-04-23, v0.0.38 shipped 2026-05-11). With max=0.0.36, the resolver returns { kind: "pin", version: "0.0.36", reason: "max-cap" } and install-openshell.sh (gh/curl stubbed to abort the download) prints Installing OpenShell from release 'v0.0.36' — the version the old hardcoded path could not select. Pre-PR, that same install would have fetched v0.0.38 and tripped the post-install gate.
  • End-to-end against scripts/install-openshell.sh:
    • A. resolver picked 0.0.36 → script downloads v0.0.36
    • B. resolver picked 0.0.39 (today) → script downloads v0.0.39
    • C. offline (TS set MIN/MAX only, no PIN) → script keeps its hardcoded v0.0.39 (no regression)
    • D. dev channel + malformed overrides → script downloads dev tag, overrides ignored
    • E. malformed NEMOCLAW_OPENSHELL_PIN_VERSION on stable → fails loudly with the env-var name in the error (regression caught and fixed mid-PR: the original apply_blueprint_override helper swallowed fail's message into the $(...) capture; commit 18fe705 inlines the regex check so the error reaches stderr).
  • Future-bump walkthrough: with v0.0.40 / v0.0.42 published on GitHub but blueprint still at 0.0.39, resolver auto-caps to 0.0.39 (same observable install as today). When the maintainer is ready to accept the newer version, a one-line blueprint bump is enough — no install-openshell.sh edit required.
  • CI green
  • CodeRabbit feedback addressed
  • Peer review

Signed-off-by: Dongni Yang dongniy@nvidia.com

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Installer can derive/enforce blueprint min/max constraints, auto-pin the highest compatible OpenShell release, document an offline fallback pin, augment PATH, and cache the resolved OpenShell binary after install.
  • Behavior Changes

    • On non-dev channels, MIN/MAX/PIN overrides are validated (malformed values abort install); PIN is only applied when explicitly provided and is not derived from MAX. Dev channel skips blueprint overrides.
  • Tests

    • Added comprehensive tests for release parsing, resolution, pinning, env overlays, and incompatible scenarios.

Review Change Stack

…VIDIA#3404)

The reactive blueprint bump in main only kicks the can down the road —
the installer would re-trip the compatibility gate on the next OpenShell
release bump. This makes the installer self-correct by querying published
OpenShell releases and pinning the fetch to the highest release ≤ the
blueprint's max_openshell_version. If no compatible release exists, the
install fails with a clear error naming both the published latest and the
configured max.

- Adds a pure resolver (resolveOpenshellInstallVersion) plus boundary-safe
  tag parser (parseOpenshellReleaseTag) to onboard/openshell-install.ts.
- installOpenshell() in onboard.ts lists release tags via gh/curl and
  passes the resolved version through NEMOCLAW_OPENSHELL_PIN_VERSION.
- install-openshell.sh honours that env (validated against ^X.Y.Z$) and
  falls back to the hardcoded pin only when the resolver was unable to
  reach GitHub.
- Unit tests cover the four required cases: latest > max → highest ≤ max;
  latest ≤ max → latest unchanged; no release ≤ max → clear error; max
  missing → no-max fallback. Plus malformed-input boundary cases and the
  QA repro (latest=0.0.38, max=0.0.36 → 0.0.36).

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

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
📝 Walkthrough

Walkthrough

This PR implements OpenShell version resolution during installation: it parses GitHub release tags, resolves a compatible version per blueprint min/max constraints, composes MIN/MAX/PIN env overlays, validates blueprint overrides in the installer script, and runs the installer with the computed environment while updating host PATH and cached bin path.

Changes

OpenShell Install Version Resolution

Layer / File(s) Summary
Version Resolution Types & Helpers
src/lib/onboard/openshell-install.ts
Introduces OpenshellInstallVersionResolution discriminated union (no-max, pin, incompatible) and exports parseOpenshellReleaseTag (sanitizes raw tags to X.Y.Z semver or null) and resolveOpenshellInstallVersion (selects highest compatible release or returns incompatibility/no-max outcomes).
Release discovery (gh + curl fallback)
src/lib/onboard/openshell-pin.ts
Lists OpenShell release tags via gh release list with a timed failure-return and a paginated curl fallback that accumulates tag_name values.
Pin orchestrator & env composition
src/lib/onboard/openshell-pin.ts
Module types/constants and orchestration that read blueprint max, fetch tags, call the pure resolver, map outcomes to pin/no-max/incompatible, and compose installer env overlays (sets MIN/MAX/PIN or returns env=null).
Installer script: blueprint override validation
scripts/install-openshell.sh
Updates inline PIN docs and adds channel-gated NEMOCLAW_OPENSHELL_* override parsing: on non-dev, validates X.Y.Z overrides and applies MIN/MAX and explicit PIN only (does not derive PIN from overridden MAX); skips overrides on dev.
Run installer and host env updates
src/lib/onboard/openshell-pin.ts
Runs scripts/install-openshell.sh with the computed env (or aborts), handles non-zero exit status by printing output and returning failure, discovers openshell bin paths, augments PATH when appropriate, wires resolveOpenshell/setOpenshellBin, and updates NEMOCLAW_OPENSHELL_BIN.
Onboard module wiring
src/lib/onboard.ts
Imports openshellPinFlow, rewires installOpenshell() to call openshellPinFlow.runOpenshellInstall(...), and updates the return type to OpenShellInstallResult.
Version resolution test suite
test/onboard.test.ts
Adds tests for resolveOpenshellInstallVersion, resolveOpenshellInstallPin, and computeOpenshellInstallEnv: highest ≤ max pinning, latest-when-within-cap, incompatible reporting (message contents), legacy fallback for missing/malformed max, malformed-entry dropping, parseOpenshellReleaseTag validation, and env overlay semantics (MIN/MAX/PIN).

Sequence Diagram(s)

sequenceDiagram
  participant Onboard as Onboard.installOpenshell
  participant PinFlow as openshellPinFlow
  participant TagFetcher as listOpenshellReleaseTags
  participant GitHub as GitHub (gh / curl)
  participant Resolver as resolveOpenshellInstallVersion
  participant Installer as scripts/install-openshell.sh

  Onboard->>PinFlow: runOpenshellInstall(deps)
  PinFlow->>TagFetcher: fetch tags
  TagFetcher->>GitHub: gh release list / curl pages
  GitHub-->>TagFetcher: tag list or failure
  PinFlow->>Resolver: available tags + blueprint max
  Resolver-->>PinFlow: pin / no-max / incompatible
  PinFlow->>Installer: execute with computed env (MIN/MAX/PIN or base)
  Installer-->>PinFlow: exit code + output
  PinFlow-->>Onboard: OpenShellInstallResult (installed, env, messages)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested labels

OpenShell, fix

Suggested reviewers

  • cv

Poem

🐰 A rabbit hops through version trees,
Pinning releases with constraint glee,
From GitHub tags to blueprint cue,
It picks the shell that's best for you. 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: pinning OpenShell fetch to blueprint max_openshell_version, which is the core objective of the PR across resolver, orchestrator, and shell installer components.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 2

🤖 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 `@scripts/install-openshell.sh`:
- Around line 47-53: The script currently validates
NEMOCLAW_OPENSHELL_PIN_VERSION and fails early even for a dev install; update
the logic so validation of NEMOCLAW_OPENSHELL_PIN_VERSION (and assignment to
PIN_VERSION) is skipped when the dev channel/RELEASE_TAG is selected (i.e., when
RELEASE_TAG == "dev" or equivalent channel flag), by moving the validation block
to after RELEASE_TAG/channel resolution or by adding a guard like if [
"$RELEASE_TAG" != "dev" ]; then ... fi; reference the
NEMOCLAW_OPENSHELL_PIN_VERSION variable, PIN_VERSION assignment, and RELEASE_TAG
check to locate and modify the conditional so malformed pin values do not abort
dev installs.

In `@src/lib/onboard.ts`:
- Around line 2777-2838: The current listOpenshellReleaseTags implementation
only fetches up to 100 releases via a single gh (--limit 100) or curl
(per_page=100) call; update listOpenshellReleaseTags to paginate both gh and
curl calls (use page numbers or gh's paging flags and curl's
?per_page=100&page=N) and accumulate tagName/tag_name results until an empty
page is returned or no more results, then return the full array so
resolveOpenshellInstallVersion gets the complete release list; ensure you keep
the same JSON parsing/filtering logic (tagName for gh, tag_name for curl) and
preserve timeouts/env 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: c57c3db3-031a-4de2-90e1-4d3d024bdd0a

📥 Commits

Reviewing files that changed from the base of the PR and between c517d62 and a3074d9.

📒 Files selected for processing (4)
  • scripts/install-openshell.sh
  • src/lib/onboard.ts
  • src/lib/onboard/openshell-install.ts
  • test/onboard.test.ts

Comment thread scripts/install-openshell.sh Outdated
Comment thread src/lib/onboard.ts Outdated
)

Addresses CodeRabbit review feedback and the onboard-entrypoint-budget
check on NVIDIA#3446, and widens scope so the shell installer's MIN/MAX
constants are no longer a second source of truth:

- Move installOpenshell() body to src/lib/onboard/openshell-pin.ts so
  src/lib/onboard.ts shrinks by 19 net lines (entrypoint budget passes).
- Paginate published OpenShell release lookups: gh release list uses
  --limit 1000; the curl fallback walks per_page=100&page=N until the
  page is short. Older compatible versions are reachable once
  NVIDIA/OpenShell exceeds one page.
- Skip NEMOCLAW_OPENSHELL_PIN_VERSION (and now MIN/MAX) validation on
  the dev channel — that path installs from RELEASE_TAG=dev and never
  consults PIN_VERSION, so a malformed override should not abort a dev
  install.
- TS pin module overlays NEMOCLAW_OPENSHELL_MIN_VERSION and
  NEMOCLAW_OPENSHELL_MAX_VERSION from the blueprint onto spawn env;
  install-openshell.sh validates each against ^X.Y.Z$ and overrides its
  hardcoded MIN_VERSION / MAX_VERSION when the env is present and the
  channel is stable.
- Unit tests cover the new MIN/MAX/PIN overlay and the orchestrator
  fallback paths (offline, no max, no release ≤ max).

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@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: 2

🤖 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 `@scripts/install-openshell.sh`:
- Around line 78-84: The current block overwrites PIN_VERSION with MAX_VERSION
even when the resolver returned the sentinel "no-max", losing the hardcoded
legacy pin; change the assignment so PIN_VERSION is only set from MAX_VERSION
when MAX_VERSION is a real version (e.g. non-empty and not "no-max"). In the
block that computes MAX_VERSION (using apply_blueprint_override and the
NEMOCLAW_OPENSHELL_MAX_VERSION variable), wrap the PIN_VERSION="$MAX_VERSION"
assignment in a conditional that checks MAX_VERSION != "no-max" (and non-empty)
so legacy PIN_VERSION remains when resolver signals no-max.

In `@src/lib/onboard/openshell-pin.ts`:
- Around line 100-107: The current logic in openshell-pin.ts returns accumulated
tags on non-first pages when a paginated fetch (result from the shell command
parsed in the block handling `result.status` and `JSON.parse(result.stdout)`)
fails, which yields incomplete release lists; change both failure branches so
they return null instead of `page === 1 ? null : tags`, ensuring
`resolveOpenshellInstallPin()` receives `null` on any page-level failure and
avoids treating partial `tags` as authoritative.
🪄 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: bfe1494e-120e-4879-ba99-c5c39c9d4f70

📥 Commits

Reviewing files that changed from the base of the PR and between a3074d9 and bf35102.

📒 Files selected for processing (4)
  • scripts/install-openshell.sh
  • src/lib/onboard.ts
  • src/lib/onboard/openshell-pin.ts
  • test/onboard.test.ts

Comment thread scripts/install-openshell.sh
Comment thread src/lib/onboard/openshell-pin.ts Outdated
…NVIDIA#3404)

Address two CodeRabbit major findings on NVIDIA#3446:

- scripts/install-openshell.sh no longer defaults PIN_VERSION to a
  blueprint MAX env override. When the TS resolver couldn't reach
  GitHub it only sets MIN/MAX (never PIN), and the script's hardcoded
  PIN_VERSION is the known-good safe fallback. Letting the blueprint
  MAX silently drive the pin meant a bumped blueprint + rate-limited
  install would probe an unreleased tag.
- src/lib/onboard/openshell-pin.ts paginated curl fetch returns null
  on any per-page failure rather than the partial accumulated list. A
  page-2+ failure can hide older compatible releases, which would
  cause the resolver to falsely return "incompatible" and abort the
  install — null preserves the legacy fallback.

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NVIDIA#3404)

While running the issue NVIDIA#3404 repro locally with NEMOCLAW_OPENSHELL_PIN_VERSION
set to a malformed value, the script exited 1 with no visible error: the
`apply_blueprint_override` helper called `fail` inside a `$(...)` substitution,
which captured the stderr-less error message into the variable assignment
instead of letting it reach the user.

Inline the regex check at each call site so `fail`'s message reaches stderr
when an override is malformed. Behaviour for valid overrides is unchanged.

Verified end-to-end against the real install-openshell.sh:
- A. issue NVIDIA#3404 repro (resolver picked 0.0.36) → "Installing OpenShell from release 'v0.0.36'..."
- B. today (resolver picked 0.0.39) → "Installing OpenShell from release 'v0.0.39'..."
- C. offline (TS only set MIN/MAX, no PIN) → script keeps hardcoded 'v0.0.39'
- D. dev channel with garbage overrides → "Installing OpenShell from release 'dev'..."
- E. malformed PIN on stable → fails loudly with the env-name in the message

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@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 `@scripts/install-openshell.sh`:
- Around line 61-69: The fail() helper currently uses echo which writes to
stdout, contradicting the block comment claiming errors reach stderr; update the
fail() implementation to send its message(s) to stderr (e.g., use echo ... >&2
or printf ... >&2) and preserve the existing exit behavior so all callers
(including the validation block around MIN/MAX/PIN) emit errors on stderr as
intended.
🪄 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: 6305b173-6b02-4a15-9bee-6e3396ece353

📥 Commits

Reviewing files that changed from the base of the PR and between cde2d70 and 18fe705.

📒 Files selected for processing (1)
  • scripts/install-openshell.sh

Comment thread scripts/install-openshell.sh Outdated
Dongni-Yang and others added 2 commits May 13, 2026 17:24
…VIDIA#3404)

CodeRabbit minor on NVIDIA#3446: the comment introduced in 18fe705 claimed
fail()'s output reaches stderr, but fail() (Line 14-17) still echoed to
stdout. Today the inlined validation avoids $(...) capture, so the user
does see the message, but the stderr claim itself was false.

Redirect fail()'s echo to stderr (>&2) so it matches both the comment
and conventional shell error reporting. The non-error path (info/warn)
is untouched. The validation continues to live outside $(...) so a
future caller cannot accidentally capture it.

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ect (NVIDIA#3404)

CI fixup. The three pre-existing version-check tests asserted that
fail()'s error string appeared on stdout. Commit 6c4187c redirected
fail() to stderr (per CodeRabbit minor on NVIDIA#3446), so the assertions
have to move with it. Behaviour is unchanged — only the stream the
error lands on.

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wscurran

Copy link
Copy Markdown
Contributor

@jyaunches

Copy link
Copy Markdown
Contributor

The #3478 regression guard is now on main and I merged main into this branch (maintainer edits are enabled) so the PR branch can exercise it.

Targeted dispatch against the updated PR-A preview branch is still red:

Installer hard-failed on sticky OpenShell 0.0.40 instead of reinstalling pinned 0.0.39 (#3474)
[install] openshell 0.0.40 is above the maximum (0.0.39) supported by this NemoClaw release. Upgrade NemoClaw first.

So #3446 looks good for the fresh-install resolver path, but it does not satisfy Margaret's sticky/previously-installed OpenShell path from #3474 yet. The remaining fix is in scripts/install-openshell.sh: when stable-channel INSTALLED_VERSION > MAX_VERSION, it should reinstall the pinned compatible PIN_VERSION instead of failing before the download/replacement path.

If a host already has an OpenShell release newer than this NemoClaw release supports, reinstall the pinned compatible release instead of hard-failing before the download path.

This lets the NVIDIA#3474 regression guard pass while preserving the post-install blueprint max gate.

Related: NVIDIA#3474
@jyaunches

Copy link
Copy Markdown
Contributor

✅ Coverage guard verified

openshell-version-pin-e2e (added in #3478) is now:

This verifies the sticky OpenShell path from #3474: an already-installed openshell 0.0.40 no longer hard-fails against NemoClaw max 0.0.39; the installer proceeds to reinstall the pinned compatible OpenShell release.

Local validation also passed:

npm run build:cli
npx vitest run test/install-openshell-version-check.test.ts
bash test/e2e/test-openshell-version-pin.sh

@jyaunches jyaunches merged commit 81320ea into NVIDIA:main May 13, 2026
35 checks passed
cv pushed a commit that referenced this pull request May 14, 2026
## Summary
- Bump the docs metadata and version switcher to `0.0.41`.
- Add v0.0.41 release notes plus operator guidance for OpenShell
pinning, Docker bridge reachability, Local Ollama proxy reachability,
and Docker GPU onboarding diagnostics.
- Refresh generated `nemoclaw-user-*` skills from the updated docs.

## Source summary
- #3434 -> `docs/reference/commands.md`,
`docs/reference/troubleshooting.md`, `docs/about/release-notes.md`:
Document Linux Docker-driver GPU onboarding behavior, diagnostics,
cleanup guidance, and the `NEMOCLAW_DOCKER_GPU_PATCH` troubleshooting
escape hatch.
- #3483 -> `docs/about/release-notes.md`: Note that `nemoclaw uninstall`
removes all installer-managed OpenShell helper binaries unless
`--keep-openshell` is passed.
- #3446 -> `docs/reference/commands.md`,
`docs/reference/troubleshooting.md`, `docs/about/release-notes.md`:
Document blueprint-driven OpenShell install pin resolution and fallback
behavior.
- #3472 -> `docs/inference/use-local-inference.md`,
`docs/reference/troubleshooting.md`, `docs/about/release-notes.md`:
Document sandbox-side Local Ollama auth proxy reachability checks and
firewall remediation.
- #3459 -> `docs/reference/commands.md`,
`docs/reference/troubleshooting.md`, `docs/about/release-notes.md`:
Document Docker-driver sandbox-to-gateway reachability checks and
firewall remediation.

## Test plan
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user`
- `make docs`
- `git diff --check`
- `npm run build:cli`
- `npm run typecheck:cli`
- pre-commit hooks during `git commit`

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

## Summary by CodeRabbit

* **New Features**
* Added `nemoclaw inference get` command to check current inference
settings
* Improved gateway health validation with Linux firewall remediation
guidance

* **Bug Fixes**
  * Enhanced proxy readiness validation with sandbox network path probes
  * Improved local Ollama route onboarding with rerun-safe fixes
  * Better sandbox-to-gateway connectivity detection

* **Documentation**
* Expanded troubleshooting guidance for firewall and connectivity issues
* Updated CLI reference with new command and environment variable
documentation
  * Added gateway binding and Docker-driver GPU compatibility guidance

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3531)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression and removed priority: high labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DGX Spark][Install] openshell 0.0.38 above NemoClaw max-supported 0.0.36 — install fails

4 participants