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
Contributor

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
@wscurran wscurran added bug Something fails against expected or documented behavior NemoClaw CLI labels Apr 30, 2026
@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 bug Something fails against expected or documented behavior feature PR adds or expands user-visible functionality labels Jun 3, 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

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