Skip to content

fix(onboard): honor NEMOCLAW_POLICY_PRESETS on recreate - #2682

Merged
cv merged 14 commits into
NVIDIA:mainfrom
rluo8:fix/2675-policy-presets-recreate-override
May 15, 2026
Merged

fix(onboard): honor NEMOCLAW_POLICY_PRESETS on recreate#2682
cv merged 14 commits into
NVIDIA:mainfrom
rluo8:fix/2675-policy-presets-recreate-override

Conversation

@rluo8

@rluo8 rluo8 commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

nemoclaw onboard --recreate-sandbox --non-interactive silently ignored the NEMOCLAW_POLICY_PRESETS env var when an existing sandbox had previous policies recorded in the registry.
The fix gates the registry-→-session carry-over on the env-var override: when running non-interactively with NEMOCLAW_POLICY_PRESETS explicitly set, the previous policies are not carried forward, and the policy step reads the env var like a fresh onboard. A [non-interactive] note prints the overridden list so the takeover is visible.

Related Issue

Fixes #2675

Changes

src/lib/onboard.ts: Added shouldCarryPreviousPolicies predicate; the createSandbox recreate branch now uses it to gate the previous-policies-→-session write, and prints a one-line note when an env-var override displaces a recorded list. Helper exported for testing.
test/onboard.test.ts: Added two unit tests under describe("shouldCarryPreviousPolicies (#2675)") covering the non-interactive override case and the interactive-mode boundary.

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)

AI Disclosure

  • AI-assisted — tool: Claude

Signed-off-by: rluo8 ruluo@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Sandbox recreation now correctly decides whether to carry prior policy presets: environment-configured presets take effect in non-interactive mode, while interactive mode preserves previously stored presets. A clear note is shown when an environment preset overrides prior presets during recreation.
  • Tests

    • Added unit tests covering policy preset inheritance across interactive and non-interactive scenarios.

@rluo8 rluo8 closed this Apr 29, 2026
@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Sandbox recreation now conditionally carries prior policy presets using a new exported helper shouldCarryPreviousPolicies(...). In non-interactive recreate flows the helper prevents inheriting presets when env vars indicate explicit presets/modes; a [non-interactive] note is logged when inheritance is blocked. (44 words)

Changes

Cohort / File(s) Summary
Policy Preset Inheritance Gate
src/lib/onboard.ts
Added and exported shouldCarryPreviousPolicies(previousPolicies: string[] | null | undefined, options?: { nonInteractive?: boolean; envPolicyPresetsRaw?: string; envPolicyModeRaw?: string }): boolean. Recreation now uses this helper to decide whether to carry prior policyPresets; when false, session policyPresets are cleared (null) and a [non-interactive] note is emitted if env vars override previous presets.
Test Coverage
test/onboard.test.ts
Exposed the helper via OnboardTestInternals and added unit tests covering five cases: interactive vs non-interactive, envPolicyPresetsRaw override, and envPolicyModeRaw values (skip, custom, suggested) to assert expected boolean outcomes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through sessions, tidy and spry,
Old presets peeked from a sandbox sky,
When silence flags insist "do not resume," I sigh,
I tuck them away, no echo to ply.
"[non-interactive]" — a gentle hop, goodbye.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 'fix(onboard): honor NEMOCLAW_POLICY_PRESETS on recreate' directly and clearly summarizes the main change: fixing the recreate behavior to respect environment variable policy presets, which is the core bug fix addressed in the PR.
Linked Issues check ✅ Passed The PR fully addresses the core requirement from issue #2675: it implements option (a) by honoring NEMOCLAW_POLICY_PRESETS on recreate and adds a helper predicate with comprehensive unit tests covering both non-interactive override and interactive-mode boundary conditions.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the policy preset override fix: a new shouldCarryPreviousPolicies predicate with explicit mode handling, updated sandbox recreation logic, and corresponding unit tests. No unrelated changes detected.

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

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

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

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

@rluo8 rluo8 reopened this Apr 29, 2026
@rluo8
rluo8 requested a review from ericksoa April 29, 2026 15:03

@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

🧹 Nitpick comments (1)
test/onboard.test.ts (1)

289-307: Add a trim/empty-env boundary test for NEMOCLAW_POLICY_PRESETS.

Current coverage validates non-empty override and interactive behavior, but it doesn’t lock the " " / "" case where previous policies should still carry. Adding that case would prevent regressions around env normalization.

Suggested test addition
   describe("shouldCarryPreviousPolicies (`#2675`)", () => {
@@
     it("ignores env var in interactive mode (previous list still wins)", () => {
       expect(
         shouldCarryPreviousPolicies(["npm"], {
           nonInteractive: false,
           envPolicyPresetsRaw: "pypi",
         }),
       ).toBe(true);
     });
+
+    it("treats empty/whitespace env var as not overriding previous policies", () => {
+      expect(
+        shouldCarryPreviousPolicies(["npm"], {
+          nonInteractive: true,
+          envPolicyPresetsRaw: "   ",
+        }),
+      ).toBe(true);
+      expect(
+        shouldCarryPreviousPolicies(["npm"], {
+          nonInteractive: true,
+          envPolicyPresetsRaw: "",
+        }),
+      ).toBe(true);
+    });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/onboard.test.ts` around lines 289 - 307, Add a test that verifies
shouldCarryPreviousPolicies treats empty or whitespace-only
NEMOCLAW_POLICY_PRESETS as "no override" so previous policies are carried;
update the test suite around describe("shouldCarryPreviousPolicies (`#2675`)") to
include a case (using shouldCarryPreviousPolicies([...], { nonInteractive: true,
envPolicyPresetsRaw: "   " }) and/or envPolicyPresetsRaw: "") that expects true,
referencing the shouldCarryPreviousPolicies function to locate where to add the
assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 3688-3701: When shouldCarryPreviousPolicies(previousPolicies) is
false, explicitly clear any stale session.policyPresets so old presets don't
persist on resume and interfere with setupPoliciesWithSelection or the
NEMOCLAW_POLICY_PRESETS override; inside the same branch that currently skips
assigning previousPolicies, call onboardSession.updateSession to set
current.policyPresets = [] (or null/undefined per session shape) so subsequent
logic in setupPoliciesWithSelection sees no explicit selection; ensure this is
done before the non-interactive/env-var check that logs the override and
reference isNonInteractive(), shouldCarryPreviousPolicies(),
onboardSession.updateSession, and setupPoliciesWithSelection to locate the
relevant code.
- Around line 5755-5765: The predicate shouldCarryPreviousPolicies currently
only checks NEMOCLAW_POLICY_PRESETS; adjust it to also read the effective
NEMOCLAW_POLICY_MODE (from options if provided, else
process.env.NEMOCLAW_POLICY_MODE) and treat any explicit mode as forcing a fresh
decision: if mode is one of ["skip","none","no","custom","list"]
(case-insensitive) return false so cached presets are not carried; preserve the
existing logic for when no explicit mode is set and still respect
options.envPolicyPresetsRaw and nonInteractive behavior.

---

Nitpick comments:
In `@test/onboard.test.ts`:
- Around line 289-307: Add a test that verifies shouldCarryPreviousPolicies
treats empty or whitespace-only NEMOCLAW_POLICY_PRESETS as "no override" so
previous policies are carried; update the test suite around
describe("shouldCarryPreviousPolicies (`#2675`)") to include a case (using
shouldCarryPreviousPolicies([...], { nonInteractive: true, envPolicyPresetsRaw:
"   " }) and/or envPolicyPresetsRaw: "") that expects true, referencing the
shouldCarryPreviousPolicies function to locate where to add the assertion.
🪄 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: 3b76e527-43a6-456d-830e-3d9fcc5b78ff

📥 Commits

Reviewing files that changed from the base of the PR and between d2f6272 and acfd1b2.

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

Comment thread src/lib/onboard.ts Outdated
Comment thread src/lib/onboard.ts Outdated

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

♻️ Duplicate comments (1)
src/lib/onboard.ts (1)

5761-5770: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Honor explicit NEMOCLAW_POLICY_MODE here too.

The carry-forward decision still only looks at NEMOCLAW_POLICY_PRESETS. On non-interactive recreate, explicit modes like skip|none|no can still reuse cached presets via the resume path, and custom|list can bypass the required env-var validation.

💡 Suggested fix
 function shouldCarryPreviousPolicies(
   previousPolicies: string[] | null | undefined,
-  options: { nonInteractive?: boolean; envPolicyPresetsRaw?: string } = {},
+  options: {
+    nonInteractive?: boolean;
+    envPolicyPresetsRaw?: string;
+    policyModeRaw?: string;
+  } = {},
 ): boolean {
   if (!Array.isArray(previousPolicies) || previousPolicies.length === 0) return false;
   const nonInteractive = options.nonInteractive ?? isNonInteractive();
+  const policyMode = (options.policyModeRaw ?? process.env.NEMOCLAW_POLICY_MODE ?? "suggested")
+    .trim()
+    .toLowerCase();
   const envRaw = (
     options.envPolicyPresetsRaw ?? process.env.NEMOCLAW_POLICY_PRESETS ?? ""
   ).trim();
+  if (nonInteractive && ["skip", "none", "no", "custom", "list"].includes(policyMode)) {
+    return false;
+  }
   return !(nonInteractive && envRaw.length > 0);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 5761 - 5770, The function
shouldCarryPreviousPolicies currently only checks NEMOCLAW_POLICY_PRESETS;
update shouldCarryPreviousPolicies to also read and consider
NEMOCLAW_POLICY_MODE (e.g., process.env.NEMOCLAW_POLICY_MODE or options if you
add support) when deciding to carry previous policies: if nonInteractive and
either envPolicyPresetsRaw is present OR NEMOCLAW_POLICY_MODE is set to an
explicit mode that implies using presets (or conversely set to skip/none/no to
prevent reuse), return false accordingly; adjust the return logic in
shouldCarryPreviousPolicies to include this additional mode-based guard so
resume paths cannot bypass env-var validation for modes like skip|none|no and
custom|list are handled correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 5761-5770: The function shouldCarryPreviousPolicies currently only
checks NEMOCLAW_POLICY_PRESETS; update shouldCarryPreviousPolicies to also read
and consider NEMOCLAW_POLICY_MODE (e.g., process.env.NEMOCLAW_POLICY_MODE or
options if you add support) when deciding to carry previous policies: if
nonInteractive and either envPolicyPresetsRaw is present OR NEMOCLAW_POLICY_MODE
is set to an explicit mode that implies using presets (or conversely set to
skip/none/no to prevent reuse), return false accordingly; adjust the return
logic in shouldCarryPreviousPolicies to include this additional mode-based guard
so resume paths cannot bypass env-var validation for modes like skip|none|no and
custom|list are handled correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7071023f-06f1-4e37-beaf-29d8d180927a

📥 Commits

Reviewing files that changed from the base of the PR and between acfd1b2 and ce7bfec.

📒 Files selected for processing (1)
  • src/lib/onboard.ts

@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 the current code and only fix it if needed.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 5765-5785: shouldCarryPreviousPolicies currently only treats
certain values in env policy mode as explicit; instead treat any provided
NEMOCLAW_POLICY_MODE (or options.envPolicyModeRaw) as an explicit decision.
Change the logic in shouldCarryPreviousPolicies so after computing envRaw for
presets you also compute envModeRaw = (options.envPolicyModeRaw ??
process.env.NEMOCLAW_POLICY_MODE ?? "").trim() and if envModeRaw.length > 0
return false (remove/replace the EXPLICIT_POLICY_MODES.includes check); keep the
rest of the nonInteractive and envRaw checks intact. This ensures any explicit
policy mode string prevents carrying previous policies.
🪄 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: bdc6e3a9-a2f8-46df-a1e2-1e19af1030ee

📥 Commits

Reviewing files that changed from the base of the PR and between ce7bfec and a206deb.

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

Comment thread src/lib/onboard.ts Outdated
@cv cv closed this May 12, 2026
@cv cv reopened this May 12, 2026
@rluo8 rluo8 added the v0.0.39 label May 13, 2026
@cv cv added v0.0.41 and removed v0.0.39 labels May 13, 2026
@cv cv added v0.0.42 and removed v0.0.41 labels May 14, 2026
@cv cv added v0.0.43 and removed v0.0.42 labels May 14, 2026
…ts-recreate-override

# Conflicts:
#	src/lib/onboard.ts
@cv
cv enabled auto-merge (squash) May 15, 2026 13:55
@cv
cv merged commit 2534db4 into NVIDIA:main May 15, 2026
20 checks passed
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: policy Network policy, egress rules, presets, or sandbox policy bug-fix PR fixes a bug or regression feature PR adds or expands user-visible functionality and removed NemoClaw CLI feature PR adds or expands user-visible functionality labels Jun 3, 2026
@wscurran wscurran added the NV QA Bugs found by the NVIDIA QA Team label Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: policy Network policy, egress rules, presets, or sandbox policy bug-fix PR fixes a bug or regression NV QA Bugs found by the NVIDIA QA Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS][Onboard] nemoclaw onboard --recreate-sandbox silently ignores NEMOCLAW_POLICY_PRESETS env var, resumes previous presets from cached state

4 participants