Skip to content

feat(cli): add resource profiles to nemoclaw onboard and nemoclaw resources command#3348

Open
nvshridhar wants to merge 10 commits into
NVIDIA:mainfrom
nvshridhar:feat/resources-v2
Open

feat(cli): add resource profiles to nemoclaw onboard and nemoclaw resources command#3348
nvshridhar wants to merge 10 commits into
NVIDIA:mainfrom
nvshridhar:feat/resources-v2

Conversation

@nvshridhar
Copy link
Copy Markdown

@nvshridhar nvshridhar commented May 11, 2026

Summary

Add nemoclaw resources [--json] global command for hardware inventory and integrate percentage-based resource profile selection into the nemoclaw onboard flow. Resource limits (CPU/memory requests and limits) are applied to sandbox pods via OpenShell's resource flags when available, with graceful degradation when they are not.

Related Issue

Closes #3336

Changes

  • src/lib/resources-cmd.ts (new): Hardware inventory (getHardwareResources), percentage resolution (resolveResourceValue), profile loading from blueprint.yaml, and appendResourceFlags with OpenShell CLI capability detection
  • src/lib/commands/resources.ts (new): Oclif command for nemoclaw resources [--json] with display metadata
  • src/lib/cli/oclif-dispatch.ts: Added resources to GLOBAL_ROUTES
  • src/lib/cli/command-display.ts: Added "Resources" to CommandGroup type
  • src/lib/cli/command-registry.ts: Added "Resources" to GROUP_ORDER
  • src/lib/cli/command-registry.test.ts: Updated GROUP_ORDER snapshot
  • src/lib/onboard.ts: Profile picker (interactive + env var paths), appendResourceFlags in createSandbox
  • nemoclaw-blueprint/blueprint.yaml: Added resource_profiles with 4 percentage-based profiles
  • schemas/blueprint.schema.json: Added resource_profiles schema with percentage/K8s quantity pattern validation

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
  • 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)

Testing

Verified end-to-end on cgroup v2 (Docker Desktop + WSL2):

  • Pod spec: resources.requests.cpu=6, resources.limits.cpu=8, resources.requests.memory=9Gi, resources.limits.memory=12Gi
  • cgroup enforcement: cpu.max=800000/100000 (8 cores), memory.max=12884901888 (12Gi)
  • CPU burn test (22 threads, 10s): 101 throttle events — PASS
  • Memory OOM test (13GB > 12Gi): exit 137 — PASS

Dependencies

  • Merge gate: Do not merge until NemoClaw's supported OpenShell range is bumped and validated to >= v0.0.41. Current PR head still pins OpenShell 0.0.39 as both min and max (scripts/install-openshell.sh, nemoclaw-blueprint/blueprint.yaml), so resource profiles gracefully fall back and will not apply CPU/RAM limits through the shipped installer path.
  • OpenShell support shipped in OpenShell PR #1376 / v0.0.41, which adds openshell sandbox create --cpu and --memory.

Signed-off-by: Shridhar Damale sdamale@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added a nemo "resources" command to show host hardware and configured sandbox resource profiles (table or --json).
    • Onboarding can select/apply sandbox resource profiles and accept CPU/RAM overrides; build-time host warnings improved.
  • Configuration

    • Introduced named resource profiles: creator, gamer, game-developer, developer with validated CPU/memory request/limit formats.
  • Documentation

    • Docs updated with the new command and environment-variable guidance for profile selection and overrides.

Review Change Stack

…ources command

Add `nemoclaw resources [--json]` global command for hardware inventory
and integrate resource profile selection into the onboard flow.

Hardware inventory:
- CPU cores, model, k8s node allocatable
- RAM total, swap, k8s node allocatable
- NVIDIA GPU name, count, VRAM
- Available resource profiles from blueprint.yaml (with resolved values)

Onboard integration:
- Profile picker after messaging channels, before sandbox creation
- Profiles use percentage values (e.g. "25%") resolved against detected
  hardware at runtime — same profile works on any machine
- appendResourceFlags passes resolved --cpu-limit/--memory-limit to
  openshell sandbox create
- Graceful degradation: silently skips if OpenShell lacks resource flags
- Non-interactive: NEMOCLAW_RESOURCE_PROFILE env var selects profile,
  NEMOCLAW_CPU_LIMIT/NEMOCLAW_RAM_LIMIT override individual fields
  (supports both "25%" and absolute "4" / "8Gi" formats)

Blueprint changes:
- Added resource_profiles section with 4 profiles using percentages
- Schema validates pattern: percentage or Kubernetes quantity

Signed-off-by: Shridhar Damale <sdamale@nvidia.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 11, 2026

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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

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

Adds a nemoclaw resources command (hardware/Kubernetes capacity + blueprint profiles), schema and blueprint presets for named resource profiles, helpers to resolve percentage/quantity values, onboarding profile selection and sandbox-creation wiring, tests, and documentation updates.

Changes

Resource Profiles and Discovery

Layer / File(s) Summary
Schema & Type Definitions
schemas/blueprint.schema.json, src/lib/resources-cmd.ts
Adds components.sandbox.resource_profiles schema and exports ResourceProfile/HardwareResources and helpers.
Blueprint Resource Profiles
nemoclaw-blueprint/blueprint.yaml
Adds four predefined percentage-based profiles under components.sandbox.resource_profiles.
Hardware discovery & profile loading
src/lib/resources-cmd.ts
Discovers host CPU/RAM, optional GPU, attempts Kubernetes allocatable via gateway container, and loads blueprint profiles.
Resolution helpers
src/lib/resources-cmd.ts
Implements resolveResourceValue, parseCpuQuantity, and resolveProfile to convert percentages/quantities into absolute CPU/memory values.
Flag append & Output/Dispatch
src/lib/resources-cmd.ts
appendResourceFlags() conditionally appends OpenShell sandbox create resource flags; printHardwareResources() prints JSON/table; runResourcesCommand() dispatches.
CLI wiring, command & tests
src/lib/cli/command-display.ts, src/lib/cli/command-registry.ts, src/lib/cli/oclif-dispatch.ts, src/commands/resources.ts, src/lib/commands/resources.ts, tests
Adds "Resources" group and route, implements nemoclaw resources command, and updates/adds CLI tests and ordering.
Onboarding selection & sandbox application
src/lib/onboard.ts, src/lib/onboard/resource-profile-selection.ts
Adds selectResourceProfileForSandbox (env/interactive/overrides), extends createSandbox() to accept a profile, and attempts to apply resolved OpenShell flags when available.
Build-estimate helper
src/lib/onboard/build-estimate.ts
Extracts formatSandboxBuildEstimateNote and SandboxBuildEstimateHost type used during onboarding messaging.
resources-cmd & selection tests
src/lib/resources-cmd.test.ts, src/lib/onboard/resource-profile-selection.test.ts, src/lib/commands/resources.test.ts, src/lib/cli/command-registry.test.ts
Adds unit tests covering resolution, profile loading, hardware discovery, CLI command behavior, and onboarding selection/error paths.
Documentation updates
docs/reference/commands.md
Documents the nemoclaw resources command and adds onboarding env variables for profile selection and CPU/RAM overrides.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

OpenShell, configuration, documentation

Suggested reviewers

  • cv
  • jyaunches

Poem

🐇 I hopped through cores and RAM at night,
Blueprints lined with profiles neat and bright,
Percent to numbers, flags prepared for flight,
Sandboxes tuck in with limits set tight,
A burrow planned — each sandbox sleeps just right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.62% 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
Title check ✅ Passed The title accurately summarizes the main changes: adding resource profiles to both the onboard flow and a new resources command.
Linked Issues check ✅ Passed All primary objectives from #3336 are implemented: resources command with JSON support, interactive profile picker with env var overrides, percentage-to-absolute resolution, graceful OpenShell flag detection, and blueprint schema updates.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #3336 scope (resources command, profile selection, schema updates, onboard integration); follow-up items (resize, verify) are appropriately deferred to PR 2/2.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/lib/resources-cmd.ts (1)

111-134: ⚡ Quick win

Consider extracting duplicated profile loading logic.

Profile loading appears in both getHardwareResources() (lines 111-134) and loadResourceProfiles() (lines 302-326). Extract the common blueprint parsing logic into a private helper to maintain consistency and reduce duplication.

♻️ Proposed refactor
+function parseResourceProfilesFromBlueprint(blueprintPath: string): Record<string, ResourceProfile> {
+  if (!fs.existsSync(blueprintPath)) return {};
+  const content = fs.readFileSync(blueprintPath, "utf-8");
+  const blueprint = YAML.parse(content);
+  const raw = blueprint?.components?.sandbox?.resource_profiles;
+  if (!raw || typeof raw !== "object") return {};
+  const profiles: Record<string, ResourceProfile> = {};
+  for (const [name, p] of Object.entries(raw)) {
+    const prof = p as Record<string, unknown>;
+    if (prof.cpu_request && prof.cpu_limit && prof.memory_request && prof.memory_limit) {
+      profiles[name] = {
+        cpu_request: String(prof.cpu_request),
+        cpu_limit: String(prof.cpu_limit),
+        memory_request: String(prof.memory_request),
+        memory_limit: String(prof.memory_limit),
+      };
+    }
+  }
+  return profiles;
+}

Then call it from both functions:

const blueprintPath = path.join(__dirname, "..", "..", "nemoclaw-blueprint", "blueprint.yaml");
profiles = parseResourceProfilesFromBlueprint(blueprintPath);
🤖 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/resources-cmd.ts` around lines 111 - 134, The resource-profile
parsing logic is duplicated in getHardwareResources and loadResourceProfiles;
extract the shared YAML/blueprint reading and parsing into a single private
helper (e.g., parseResourceProfilesFromBlueprint) that accepts the blueprintPath
(or derives it) and returns Record<string, ResourceProfile> | null, then replace
the duplicated blocks in getHardwareResources and loadResourceProfiles to call
that helper and handle its null/return value; ensure the helper preserves the
existing behavior (fs.existsSync, YAML.parse, safe casting and string defaults)
and keep exception handling consistent.
nemoclaw-blueprint/blueprint.yaml (1)

39-58: ⚡ Quick win

Consider consolidating or differentiating the creator and game-developer profiles.

Both profiles define identical resource allocations (25% request / 50% limit for CPU and memory). If these personas have the same resource needs, consider using a single profile; otherwise, adjust the values to reflect their distinct workload characteristics.

🤖 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 `@nemoclaw-blueprint/blueprint.yaml` around lines 39 - 58, The blueprint
defines identical resource allocations for the "creator" and "game-developer"
profiles so either consolidate them into a single profile or give them distinct
values to reflect different workloads; update the blueprint.yaml by either
removing one profile and referencing the remaining profile where used (merge
"creator" and "game-developer" into one named profile) or change the
cpu_request/cpu_limit/memory_request/memory_limit values for "creator" and/or
"game-developer" to reflect their actual resource needs (e.g., lower for
authoring vs. higher for build-heavy developer tasks), and ensure any references
to the removed/renamed profile are updated accordingly.
🤖 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/commands/resources.ts`:
- Around line 37-43: The run() method currently captures the return of
printHardwareResources(this.jsonEnabled()) into result but
printHardwareResources returns void; update the code flow so that when
this.jsonEnabled() is true the command returns the actual HardwareResources
object: change or overload printHardwareResources (in resources-cmd.ts) to
return a HardwareResources value when called with jsonEnabled=true (or add a new
function that returns the object), then in ResourcesCommand.run() use that
returned object (result) to return JSON mode output; ensure
printHardwareResources still prints to stdout in non-JSON mode and that
ResourcesCommand.run() calls this.jsonEnabled() to decide which form to return.

In `@src/lib/onboard.ts`:
- Around line 10262-10280: The code only resolves/validates cpu_limit and
memory_limit; also resolve and validate cpu_request and memory_request using
resolveResourceValue so invalid request values are caught early: after computing
cpuTotal = hw.cpu.cores and memTotal = hw.memory.totalMB call
resolveResourceValue(cpuReq, cpuTotal, "cpu") and resolveResourceValue(ramReq,
memTotal, "memory"), then log the resolved request and limit values (or compare
requests <= limits if desired) before continuing; update the block that builds
selectedProfile (cpu_request, cpu_limit, memory_request, memory_limit) to
perform these extra resolves and handle errors the same way as for limits.
- Around line 10253-10257: The selection parsing for profiles (where idx =
parseInt(choice.trim(), 10) - 1 and selectedProfile is set from
availableProfiles/profileNames) currently lets non-numeric or out-of-range
inputs fall through to using default resources; change this to fail-fast or
re-prompt: validate that choice is a numeric index within
1..profileNames.length-1 (or equal to profileNames.length for the explicit
option) and when parseInt yields NaN or idx is outside the permitted range,
throw an error or loop back to prompt the user (do not silently continue),
ensuring you reference the same variables (choice, idx, profileNames,
availableProfiles, selectedProfile) and update the control flow that currently
reaches the default-resources branch.

In `@src/lib/resources-cmd.ts`:
- Around line 148-187: printHardwareResources currently writes JSON to stdout
but returns void, while ResourcesCommand.run() expects the hardware data when
the json flag is set; update printHardwareResources(json: boolean) so that when
json === true it returns the hw object (the variable holding
getHardwareResources()) after writing JSON to stdout, keeping the existing
behavior for non-json paths and the function signature unchanged so callers like
ResourcesCommand.run() can receive the data.
- Around line 265-296: appendResourceFlags claims to "gracefully degrade" but
resolveProfile -> resolveResourceValue can throw on invalid percentage input;
wrap the resolveProfile(profile, hw) call (and the subsequent uses of resolved)
in a try-catch so any thrown error is caught and the function returns false
(i.e., skip adding resource flags) instead of crashing; reference
resolveProfile, resolveResourceValue and appendResourceFlags when making this
change so the behavior is clear and safe.

---

Nitpick comments:
In `@nemoclaw-blueprint/blueprint.yaml`:
- Around line 39-58: The blueprint defines identical resource allocations for
the "creator" and "game-developer" profiles so either consolidate them into a
single profile or give them distinct values to reflect different workloads;
update the blueprint.yaml by either removing one profile and referencing the
remaining profile where used (merge "creator" and "game-developer" into one
named profile) or change the cpu_request/cpu_limit/memory_request/memory_limit
values for "creator" and/or "game-developer" to reflect their actual resource
needs (e.g., lower for authoring vs. higher for build-heavy developer tasks),
and ensure any references to the removed/renamed profile are updated
accordingly.

In `@src/lib/resources-cmd.ts`:
- Around line 111-134: The resource-profile parsing logic is duplicated in
getHardwareResources and loadResourceProfiles; extract the shared YAML/blueprint
reading and parsing into a single private helper (e.g.,
parseResourceProfilesFromBlueprint) that accepts the blueprintPath (or derives
it) and returns Record<string, ResourceProfile> | null, then replace the
duplicated blocks in getHardwareResources and loadResourceProfiles to call that
helper and handle its null/return value; ensure the helper preserves the
existing behavior (fs.existsSync, YAML.parse, safe casting and string defaults)
and keep exception handling consistent.
🪄 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: 0d5a1f3e-6867-40a9-9a41-2e09c8126647

📥 Commits

Reviewing files that changed from the base of the PR and between 74a09bb and 302f917.

📒 Files selected for processing (9)
  • nemoclaw-blueprint/blueprint.yaml
  • schemas/blueprint.schema.json
  • src/lib/cli/command-display.ts
  • src/lib/cli/command-registry.test.ts
  • src/lib/cli/command-registry.ts
  • src/lib/cli/oclif-dispatch.ts
  • src/lib/commands/resources.ts
  • src/lib/onboard.ts
  • src/lib/resources-cmd.ts

Comment thread src/lib/commands/resources.ts
Comment thread src/lib/onboard.ts Outdated
Comment thread src/lib/onboard.ts Outdated
Comment thread src/lib/resources-cmd.ts Outdated
Comment thread src/lib/resources-cmd.ts
@wscurran wscurran added NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI). enhancement: feature Use this label to identify requests for new capabilities in NemoClaw. fix labels May 11, 2026
@wscurran
Copy link
Copy Markdown
Contributor

@cv cv closed this May 12, 2026
@cv cv reopened this May 12, 2026
@cv cv added the v0.0.42 Release target label May 14, 2026
@cv cv self-assigned this May 14, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/lib/onboard.ts (1)

10853-10869: Run the full onboarding E2E matrix for this path change.

This touches core sandbox creation flow in onboarding; please run the recommended E2E jobs (cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e, messaging-compatible-endpoint-e2e, hermes-discord-e2e, hermes-slack-e2e, openshell-gateway-upgrade-e2e) before merge.

As per coding guidelines src/lib/onboard.ts: "This file contains core onboarding logic. Changes here affect the full sandbox creation and configuration flow." and the listed "E2E test recommendation" jobs.

🤖 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.ts` around lines 10853 - 10869, This change touches the core
sandbox creation flow around selectResourceProfileForSandbox,
stopStaleDashboardListenersForSandbox (which uses registry.listSandboxes), and
createSandbox; before merging, run the full onboarding E2E matrix (cloud-e2e,
sandbox-operations-e2e, rebuild-openclaw-e2e, messaging-compatible-endpoint-e2e,
hermes-discord-e2e, hermes-slack-e2e, openshell-gateway-upgrade-e2e) to validate
the new path and ensure no regressions in sandbox creation, dashboard listener
cleanup, and profile selection logic.
🤖 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.ts`:
- Around line 5014-5122: The new resource-profile selection helpers
(hasResourceEnvOverrides, applyResourceEnvOverrides,
exitWithResourceProfileError, printResolvedResourceProfile,
selectResourceProfileForSandbox and any helper callers like
loadResourceProfiles/getHardwareResources/promptOrDefault) are too large for
src/lib/onboard.ts and must be extracted into a new focused module (e.g.,
src/lib/resources-cmd.ts); move those functions into the new file, export
selectResourceProfileForSandbox (and any helpers used elsewhere), update
onboard.ts to import the exported symbol(s) and keep onboard.ts only
orchestrating calls to selectResourceProfileForSandbox, ensuring all references
(note, prompt, promptOrDefault, loadResourceProfiles, getHardwareResources,
resolveResourceValue) are imported or passed in as needed so compilation and
behavior remain unchanged.
- Around line 5061-5068: The code trusts availableProfiles[envProfile] which can
hit inherited properties; change the existence check to an own-key check using
Object.prototype.hasOwnProperty.call(availableProfiles, envProfile) (or
equivalent) in the conditional that sets selectedProfile (the block using
NEMOCLAW_RESOURCE_PROFILE, envProfile, availableProfiles, profileNames and
selectedProfile), so only true defined profile keys allow selection and fallback
to the unknown-profile error branch otherwise.

---

Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 10853-10869: This change touches the core sandbox creation flow
around selectResourceProfileForSandbox, stopStaleDashboardListenersForSandbox
(which uses registry.listSandboxes), and createSandbox; before merging, run the
full onboarding E2E matrix (cloud-e2e, sandbox-operations-e2e,
rebuild-openclaw-e2e, messaging-compatible-endpoint-e2e, hermes-discord-e2e,
hermes-slack-e2e, openshell-gateway-upgrade-e2e) to validate the new path and
ensure no regressions in sandbox creation, dashboard listener cleanup, and
profile selection logic.
🪄 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: bf106993-c19a-41bc-b59e-e8799bd7825a

📥 Commits

Reviewing files that changed from the base of the PR and between 302f917 and 91fd43e.

📒 Files selected for processing (5)
  • docs/reference/commands.md
  • nemoclaw-blueprint/blueprint.yaml
  • src/lib/cli/command-registry.test.ts
  • src/lib/cli/oclif-dispatch.ts
  • src/lib/onboard.ts
✅ Files skipped from review due to trivial changes (3)
  • src/lib/cli/oclif-dispatch.ts
  • docs/reference/commands.md
  • src/lib/cli/command-registry.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • nemoclaw-blueprint/blueprint.yaml

Comment thread src/lib/onboard.ts Outdated
Comment thread src/lib/onboard.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/lib/onboard/resource-profile-selection.ts (2)

38-47: ⚡ Quick win

Mutation risk: spread before modifying to avoid side effects.

If selectedProfile is passed as a direct reference (e.g., from line 112 which doesn't spread), this function mutates the original object. While the current control flow prevents this scenario, the code is fragile. Making a defensive copy here ensures safety regardless of how callers evolve.

♻️ Proposed fix
-  const nextProfile = selectedProfile || {
+  const nextProfile = selectedProfile ? { ...selectedProfile } : {
     cpu_request: "",
     cpu_limit: "",
     memory_request: "",
     memory_limit: "",
   };
🤖 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/resource-profile-selection.ts` around lines 38 - 47, The code
mutates selectedProfile via nextProfile; make a defensive shallow copy before
modifying by creating nextProfile from a spread of selectedProfile (or the
default object) so changes to nextProfile do not affect the original
selectedProfile; then apply the env overrides (env.NEMOCLAW_CPU_REQUEST,
env.NEMOCLAW_CPU_LIMIT, env.NEMOCLAW_RAM_REQUEST, env.NEMOCLAW_RAM_LIMIT) to
that copied nextProfile.

112-112: ⚡ Quick win

Add spread for consistency with line 80.

Line 80 creates a copy with { ...availableProfiles[envProfile] }, but this line assigns the reference directly. For consistency and to prevent potential future mutation issues (as noted above in applyResourceEnvOverrides), spread here as well.

♻️ Proposed fix
-      selectedProfile = availableProfiles[profileNames[idx]];
+      selectedProfile = { ...availableProfiles[profileNames[idx]] };
🤖 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/resource-profile-selection.ts` at line 112, selectedProfile
is assigned a direct reference from availableProfiles[profileNames[idx]] which
differs from the earlier copy at line 80 and can allow mutations; change the
assignment in resource-profile-selection.ts to create a shallow copy using
object spread (e.g., selectedProfile = { ...availableProfiles[profileNames[idx]]
}) so it matches the pattern used for envProfile and avoids accidental mutation
(consistent with applyResourceEnvOverrides behavior).
🤖 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.

Nitpick comments:
In `@src/lib/onboard/resource-profile-selection.ts`:
- Around line 38-47: The code mutates selectedProfile via nextProfile; make a
defensive shallow copy before modifying by creating nextProfile from a spread of
selectedProfile (or the default object) so changes to nextProfile do not affect
the original selectedProfile; then apply the env overrides
(env.NEMOCLAW_CPU_REQUEST, env.NEMOCLAW_CPU_LIMIT, env.NEMOCLAW_RAM_REQUEST,
env.NEMOCLAW_RAM_LIMIT) to that copied nextProfile.
- Line 112: selectedProfile is assigned a direct reference from
availableProfiles[profileNames[idx]] which differs from the earlier copy at line
80 and can allow mutations; change the assignment in
resource-profile-selection.ts to create a shallow copy using object spread
(e.g., selectedProfile = { ...availableProfiles[profileNames[idx]] }) so it
matches the pattern used for envProfile and avoids accidental mutation
(consistent with applyResourceEnvOverrides behavior).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e4fa60a1-4415-4460-b8ae-c479535550d0

📥 Commits

Reviewing files that changed from the base of the PR and between 91fd43e and 61d610f.

📒 Files selected for processing (5)
  • nemoclaw-blueprint/blueprint.yaml
  • src/lib/onboard.ts
  • src/lib/onboard/build-estimate.ts
  • src/lib/onboard/resource-profile-selection.ts
  • src/lib/resources-cmd.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/onboard/build-estimate.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • nemoclaw-blueprint/blueprint.yaml
  • src/lib/resources-cmd.ts
  • src/lib/onboard.ts

Copy link
Copy Markdown
Collaborator

@cv cv left a comment

Choose a reason for hiding this comment

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

Waiting for an OpenShell that gives us these flags, as their design might change slightly.

@cv
Copy link
Copy Markdown
Collaborator

cv commented May 14, 2026

Changes merged into OpenShell and should be in the next release tag: NVIDIA/OpenShell#1376

This PR is ready to go once we upgrade to it.

@nvshridhar
Copy link
Copy Markdown
Author

Rebased, Updated as per NVIDIA/OpenShell#1376, tested NemoClaw.

@cv cv added v0.0.43 Release target v0.0.44 Release target v0.0.45 Release target and removed v0.0.42 Release target v0.0.43 Release target labels May 14, 2026
@cv cv removed the v0.0.44 Release target label May 15, 2026
ericksoa added 2 commits May 17, 2026 22:09
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

# Conflicts:
#	src/lib/onboard.ts
#	test/onboard.test.ts
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@wscurran wscurran added v0.0.46 Release target and removed v0.0.45 Release target labels May 18, 2026
@ericksoa ericksoa added v0.0.47 Release target and removed v0.0.46 Release target labels May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement: feature Use this label to identify requests for new capabilities in NemoClaw. fix NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI). v0.0.47 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add resource profiles to nemoclaw onboard and nemoclaw resources command

4 participants