Skip to content

fix(uninstall): preserve user data by default#4229

Merged
cv merged 22 commits into
mainfrom
fix-4226-uninstall-confirm-backups
May 30, 2026
Merged

fix(uninstall): preserve user data by default#4229
cv merged 22 commits into
mainfrom
fix-4226-uninstall-confirm-backups

Conversation

@laitingsheng

@laitingsheng laitingsheng commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

nemoclaw uninstall used to rm -rf ~/.nemoclaw/, deleting every host-side snapshot and workspace backup. Switch to a selective wipe that keeps rebuild-backups/, backups/, and sandboxes.json by default. Full purge still available via interactive y prompt or NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1.

Related Issue

Fixes #4226.

Changes

  • src/lib/actions/uninstall/run-plan.ts: new PRESERVED_USER_DATA_ENTRIES, removePathExcept (selective wipe with lstat guard against symlinked state dirs), and resolvePreserveSet (env var + interactive y/N prompt).
  • src/lib/actions/uninstall/run-plan.test.ts: new tests covering preserve-by-default, env-var purge, interactive y/N, NEMOCLAW_NON_INTERACTIVE=1 on a TTY, symlinked state dir, no-preservable-on-disk skip, and non-ENOENT lstat failure exiting non-zero.
  • docs/reference/commands.mdx: new "User-data preservation under ~/.nemoclaw/" subsection with the decision matrix.
  • docs/manage-sandboxes/lifecycle.mdx: <Note> summary above the uninstall flags table.

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

Signed-off-by: Tinson Lai tinsonl@nvidia.com

Summary by CodeRabbit

  • New Features

    • Uninstall now preserves user data in ~/.nemoclaw by default (rebuild-backups/, backups/, sandboxes.json); other entries are removed.
  • Behavior

    • Interactive runs prompt before also removing preserved items (default: keep). Non-interactive/--yes preserves by default unless NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1 forces full purge. Symlinks to the state path are not followed.
  • Tests

    • Expanded uninstall tests covering preservation, destructive purge, interactive/non-interactive prompts, symlink handling, and error paths.
  • Documentation

    • Added notes describing preserved items and prompt/flag behavior.

Review Change Stack

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: fe53943b-3446-4b37-846b-02c36b6b9ca1

📥 Commits

Reviewing files that changed from the base of the PR and between 3393b36 and 48792d1.

📒 Files selected for processing (3)
  • docs/reference/commands.mdx
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/commands.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/actions/uninstall/run-plan.ts
  • src/lib/actions/uninstall/run-plan.test.ts

📝 Walkthrough

Walkthrough

Adds an allowlist and selective-deletion logic for ~/.nemoclaw during uninstall, computes a preserve set (interactive prompt or env-var override), uses removePathExcept() in the uninstall plan, adds tests for multiple scenarios, and updates reference and lifecycle docs to describe the preservation contract.

Changes

User-data preservation during uninstall

Layer / File(s) Summary
Preservation contract and path-exclusion infrastructure
src/lib/actions/uninstall/run-plan.ts
PRESERVED_USER_DATA_ENTRIES added; removePathExcept() implemented to delete directory children while preserving allowlisted entries and handle lstat failures.
Preserve detection and decision logic
src/lib/actions/uninstall/run-plan.ts
detectPreservableEntries() and resolvePreserveSet() added to compute preserve set based on on-disk allowlist presence, TTY/non-interactive, and NEMOCLAW_UNINSTALL_DESTROY_USER_DATA; interactive prompt included.
Banner update and uninstall wiring
src/lib/actions/uninstall/run-plan.ts
Uninstall confirmation banner updated to list preserved entries; executePlan() accepts preserve set and returns { ok }; state-and-binaries step calls removePathExcept(); runUninstallPlan() returns non-zero on failure.
Test suite for preservation scenarios
src/lib/actions/uninstall/run-plan.test.ts
Adds tests for non-interactive preservation, destructive env-var purge, interactive confirm (purge) and decline (preserve), NEMOCLAW_NON_INTERACTIVE behavior, lstat failure mode, symlink handling, and no-protected-entries case; includes temp ~/.nemoclaw helpers.
Reference and lifecycle documentation
docs/reference/commands.mdx, docs/manage-sandboxes/lifecycle.mdx
Documents default preserved entries (rebuild-backups/, backups/, sandboxes.json), interactive vs non-interactive behavior, NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1 override, and note about re-onboarding before snapshot restore can use preserved files.
sequenceDiagram
  participant detectPreservableEntries
  participant resolvePreserveSet
  participant executePlan
  participant removePathExcept
  detectPreservableEntries->>resolvePreserveSet: find present allowlisted entries
  resolvePreserveSet->>executePlan: computed preserveUnderStateDir (preserve or purge)
  executePlan->>removePathExcept: removePathExcept(paths.nemoclawStateDir, preserveSet)
  removePathExcept->>removePathExcept: remove non-preserved children or remove symlink
Loading

Estimated code review effort:
🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers:

  • ericksoa
  • cv

"🐰
I tend the backups in the den,
I ask, I note, I spare the men.
If TTY says yes, I clear the shelf;
else whisper: 'Keeping user data' myself.
Flip the flag and let it go — or keep it on the shelf!"

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR bundles three independent feature areas (uninstall gate, --save-host for backup-all/snapshot create, and new sandbox download/upload commands) beyond the core issue #4226 scope of preserving user data during uninstall. Reduce the PR to focus only on the uninstall gate implementation (run-plan.ts, run-plan.test.ts, and related uninstall docs) for the v0.0.53 cut; defer --save-host and download/upload commands to follow-up PRs.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(uninstall): preserve user data by default' accurately reflects the main change in the PR, which is to prevent data loss by preserving user data in ~/.nemoclaw/ during uninstall.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #4226: it preserves rebuild-backups/, backups/, and sandboxes.json by default, requires explicit confirmation for full purge, handles non-interactive semantics, adds lstat guards, and includes comprehensive unit tests.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-4226-uninstall-confirm-backups

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: snapshot-commands-e2e, state-backup-restore-e2e
Optional E2E: docs-validation-e2e, cloud-e2e

Dispatch hint: snapshot-commands-e2e,state-backup-restore-e2e

Auto-dispatched E2E: snapshot-commands-e2e, state-backup-restore-e2e via nightly-e2e.yaml at 48792d1029cc1a67474fbdcc0446ae182873aaf9nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: medium

Required E2E

  • snapshot-commands-e2e (medium (~30 min timeout, cloud onboarding)): Validates the snapshot create/list/restore lifecycle and the ~/.nemoclaw/rebuild-backups/ plus sandbox registry state that this uninstall change now preserves by default.
  • state-backup-restore-e2e (medium (~60 min timeout, cloud onboarding)): Validates scripts/backup-workspace.sh backup/restore and the ~/.nemoclaw/backups/ tree that uninstall now selectively preserves instead of deleting.

Optional E2E

  • docs-validation-e2e (low-medium (~15 min timeout)): Useful because the PR changes user-facing command/lifecycle docs; this checks installed CLI/docs validation, but it is adjacent rather than direct coverage for uninstall preservation.
  • cloud-e2e (medium (~45 min script runner default)): General install/onboard/inference/destroy smoke coverage for the source branch; useful confidence that lifecycle changes did not regress the common sandbox path, though it does not directly exercise nemoclaw uninstall.

New E2E recommendations

  • uninstall / user-data preservation (high): No existing E2E appears to directly run nemoclaw uninstall after creating rebuild-backups/, backups/, and sandboxes.json, then assert default non-interactive preservation versus NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1 full purge. Current unit tests cover the plan logic, but an E2E should validate the packaged CLI/uninstall path on a real host.
    • Suggested test: uninstall-user-data-preservation-e2e
  • reinstall recovery after uninstall (medium): The new contract says preserved files are inert but usable after reinstall/re-onboard. Add an E2E that creates a snapshot, uninstalls with default preservation, reinstalls, re-onboards, and restores the snapshot to prove the documented recovery path works.
    • Suggested test: uninstall-reinstall-snapshot-restore-e2e

Dispatch hint

  • Workflow: .github/workflows/nightly-e2e.yaml
  • jobs input: snapshot-commands-e2e,state-backup-restore-e2e

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor

Findings: 2 needs attention, 4 worth checking, 0 nice ideas
Since last review: 0 prior items resolved, 5 still apply, 0 new items found

Review findings

🛠️ Needs attention

  • [Ubuntu 24.04][Install] nemoclaw uninstall destroys all user data — workspace files (USER.md, SOUL.md) and snapshots not preserved #4226 byte-for-byte preservation remains unproven (src/lib/actions/uninstall/run-plan.test.ts:639): The linked issue's primary expected result requires the documented preservation paths to remain on the host with SHA256 content unchanged. The added tests prove selected paths still exist after uninstall, but they do not record pre-uninstall bytes or hashes and compare them after uninstall. The restore-shaped snapshot fixture also does not include the issue's representative USER.md and SOUL.md workspace content.
    • Recommendation: Extend the regression to create representative rebuild-backups/, backups/, and sandboxes.json payloads, including USER.md and SOUL.md where applicable. Record pre-uninstall bytes or SHA256 values, run uninstall --yes, then assert exact byte-for-byte equality afterward.
    • Evidence: Issue [Ubuntu 24.04][Install] nemoclaw uninstall destroys all user data — workspace files (USER.md, SOUL.md) and snapshots not preserved #4226 expected result: "The documented preservation paths still exist on the host after uninstall, with their SHA256 content unchanged from before uninstall." The new preservation test starts at run-plan.test.ts:639 and asserts fs.existsSync for rebuild-backups, backups, and sandboxes.json. Repository grep found no sha256/createHash/readFileSync equality checks and no SOUL.md fixture in the new preservation tests.
  • Destructive uninstall preservation policy is still embedded in the runner monolith (src/lib/actions/uninstall/run-plan.ts:121): The PR keeps the preservation allowlist, selective deletion implementation, preservable-entry detection, prompt/ack decision logic, and expanded regression coverage inside the already-large destructive uninstall runner and test file. This also leaves the selective cleanup behavior without a clear source-of-truth boundary or permanence/removal story.
    • Recommendation: Extract PRESERVED_USER_DATA_ENTRIES, preservable-entry detection, preserve-set resolution, and removePathExcept() into a focused uninstall state-preservation helper with narrow filesystem dependencies. Move the new preservation tests into a focused test file and document whether this policy is permanent or a temporary compatibility bridge.
    • Evidence: PRESERVED_USER_DATA_ENTRIES starts at run-plan.ts:121, removePathExcept() at run-plan.ts:127, detectPreservableEntries() at run-plan.ts:633, and resolvePreserveSet() at run-plan.ts:640. Trusted drift context reports run-plan.ts grew by 121 lines and run-plan.test.ts grew by 279 lines.

🔎 Worth checking

  • Source-of-truth review needed: src/lib/actions/uninstall/run-plan.ts removePathExcept() selective cleanup under ~/.nemoclaw/: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: removePathExcept() starts at run-plan.ts:127 and implements selective deletion inline in the runner. It catches lstat errors at run-plan.ts:143-152 but leaves readdirSync and child rmSync unwrapped at run-plan.ts:160-163.
  • Selective state-dir cleanup still lacks a controlled filesystem error policy (src/lib/actions/uninstall/run-plan.ts:160): The lstat branch now fails closed and returns a non-zero uninstall outcome, but directory enumeration and per-child deletion do not use the same policy. On unreadable, concurrently modified, or partially failing ~/.nemoclaw layouts, fs.readdirSync() or rmSync() can still throw outside the intended ok=false path, potentially skipping later cleanup of security-relevant local state/config and leaving users without a consistent warning and exit-code contract.
    • Recommendation: Wrap lstat, readdir, and each child deletion in one explicit policy: either fail closed with a clear warning and non-zero outcome, or preserve data with a clear warning. Add negative tests for readdir failure and child rmSync failure/race in addition to the existing lstat test.
    • Evidence: removePathExcept() catches fs.lstatSync(target) at run-plan.ts:143-152, but then calls const children = fs.readdirSync(target) at run-plan.ts:160 and deps.rmSync(path.join(target, entry), ...) at run-plan.ts:163 without local error handling. Tests cover lstat EACCES and symlinked ~/.nemoclaw, but not readdirSync or child rmSync failures.
  • Preserve-by-default changes privacy cleanup semantics of uninstall --yes (docs/reference/commands.mdx:1201): The new default intentionally keeps host-side snapshots, workspace backups, and the sandbox registry after uninstall. That prevents accidental data loss, but it also means security-sensitive scripted users no longer get a full local-data purge from uninstall --yes unless they set NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1. The docs and runtime notice describe what is retained, but do not explicitly warn that retained backups, snapshots, or registry files may contain private workspace data, PII, message history, or secret-adjacent user content.
    • Recommendation: Keep the explicit purge path, but make the non-interactive runtime notice and uninstall docs explicit that retained backups/snapshots/registry may contain private workspace data, PII, message history, or secrets. Keep NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1 prominent for users who need a full purge.
    • Evidence: PRESERVED_USER_DATA_ENTRIES includes rebuild-backups, backups, and sandboxes.json. resolvePreserveSet() preserves them by default for --yes, non-TTY, and NEMOCLAW_NON_INTERACTIVE=1. docs/reference/commands.mdx:1201-1220 says the entries survive as inert files on disk; docs/manage-sandboxes/lifecycle.mdx:261-264 names the preserved entries and purge env var but does not warn about private content.
  • NEMOCLAW_NON_INTERACTIVE wording can imply it replaces the initial uninstall confirmation (docs/manage-sandboxes/lifecycle.mdx:264): The docs group --yes, NEMOCLAW_NON_INTERACTIVE=1, and non-TTY shells as non-interactive preservation contexts. In code, NEMOCLAW_NON_INTERACTIVE=1 only skips the second preservation prompt after the initial Proceed? confirmation has already been accepted; confirm() still skips only when options.assumeYes is true. The new test for NEMOCLAW_NON_INTERACTIVE also supplies a readLine answer of yes for the initial prompt, so it does not prove env-var-only uninstall proceeds without --yes.
    • Recommendation: Clarify that NEMOCLAW_NON_INTERACTIVE=1 controls the preservation prompt but does not by itself acknowledge the initial destructive uninstall confirmation; scripted runs should still pass --yes when they intend to proceed.
    • Evidence: confirm() returns early only for options.assumeYes at run-plan.ts:260, then reads the Proceed? prompt. resolvePreserveSet() treats runtime.env.NEMOCLAW_NON_INTERACTIVE === "1" as non-interactive at run-plan.ts:657-658. The test at run-plan.test.ts:756 uses readLine = vi.fn(() => "yes") and expects it to be called once for the earlier generic confirm prompt.

🌱 Nice ideas

  • None.
Since last review details

Current findings:

  • Source-of-truth review needed: src/lib/actions/uninstall/run-plan.ts removePathExcept() selective cleanup under ~/.nemoclaw/: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: removePathExcept() starts at run-plan.ts:127 and implements selective deletion inline in the runner. It catches lstat errors at run-plan.ts:143-152 but leaves readdirSync and child rmSync unwrapped at run-plan.ts:160-163.
  • [Ubuntu 24.04][Install] nemoclaw uninstall destroys all user data — workspace files (USER.md, SOUL.md) and snapshots not preserved #4226 byte-for-byte preservation remains unproven (src/lib/actions/uninstall/run-plan.test.ts:639): The linked issue's primary expected result requires the documented preservation paths to remain on the host with SHA256 content unchanged. The added tests prove selected paths still exist after uninstall, but they do not record pre-uninstall bytes or hashes and compare them after uninstall. The restore-shaped snapshot fixture also does not include the issue's representative USER.md and SOUL.md workspace content.
    • Recommendation: Extend the regression to create representative rebuild-backups/, backups/, and sandboxes.json payloads, including USER.md and SOUL.md where applicable. Record pre-uninstall bytes or SHA256 values, run uninstall --yes, then assert exact byte-for-byte equality afterward.
    • Evidence: Issue [Ubuntu 24.04][Install] nemoclaw uninstall destroys all user data — workspace files (USER.md, SOUL.md) and snapshots not preserved #4226 expected result: "The documented preservation paths still exist on the host after uninstall, with their SHA256 content unchanged from before uninstall." The new preservation test starts at run-plan.test.ts:639 and asserts fs.existsSync for rebuild-backups, backups, and sandboxes.json. Repository grep found no sha256/createHash/readFileSync equality checks and no SOUL.md fixture in the new preservation tests.
  • Destructive uninstall preservation policy is still embedded in the runner monolith (src/lib/actions/uninstall/run-plan.ts:121): The PR keeps the preservation allowlist, selective deletion implementation, preservable-entry detection, prompt/ack decision logic, and expanded regression coverage inside the already-large destructive uninstall runner and test file. This also leaves the selective cleanup behavior without a clear source-of-truth boundary or permanence/removal story.
    • Recommendation: Extract PRESERVED_USER_DATA_ENTRIES, preservable-entry detection, preserve-set resolution, and removePathExcept() into a focused uninstall state-preservation helper with narrow filesystem dependencies. Move the new preservation tests into a focused test file and document whether this policy is permanent or a temporary compatibility bridge.
    • Evidence: PRESERVED_USER_DATA_ENTRIES starts at run-plan.ts:121, removePathExcept() at run-plan.ts:127, detectPreservableEntries() at run-plan.ts:633, and resolvePreserveSet() at run-plan.ts:640. Trusted drift context reports run-plan.ts grew by 121 lines and run-plan.test.ts grew by 279 lines.
  • Selective state-dir cleanup still lacks a controlled filesystem error policy (src/lib/actions/uninstall/run-plan.ts:160): The lstat branch now fails closed and returns a non-zero uninstall outcome, but directory enumeration and per-child deletion do not use the same policy. On unreadable, concurrently modified, or partially failing ~/.nemoclaw layouts, fs.readdirSync() or rmSync() can still throw outside the intended ok=false path, potentially skipping later cleanup of security-relevant local state/config and leaving users without a consistent warning and exit-code contract.
    • Recommendation: Wrap lstat, readdir, and each child deletion in one explicit policy: either fail closed with a clear warning and non-zero outcome, or preserve data with a clear warning. Add negative tests for readdir failure and child rmSync failure/race in addition to the existing lstat test.
    • Evidence: removePathExcept() catches fs.lstatSync(target) at run-plan.ts:143-152, but then calls const children = fs.readdirSync(target) at run-plan.ts:160 and deps.rmSync(path.join(target, entry), ...) at run-plan.ts:163 without local error handling. Tests cover lstat EACCES and symlinked ~/.nemoclaw, but not readdirSync or child rmSync failures.
  • Preserve-by-default changes privacy cleanup semantics of uninstall --yes (docs/reference/commands.mdx:1201): The new default intentionally keeps host-side snapshots, workspace backups, and the sandbox registry after uninstall. That prevents accidental data loss, but it also means security-sensitive scripted users no longer get a full local-data purge from uninstall --yes unless they set NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1. The docs and runtime notice describe what is retained, but do not explicitly warn that retained backups, snapshots, or registry files may contain private workspace data, PII, message history, or secret-adjacent user content.
    • Recommendation: Keep the explicit purge path, but make the non-interactive runtime notice and uninstall docs explicit that retained backups/snapshots/registry may contain private workspace data, PII, message history, or secrets. Keep NEMOCLAW_UNINSTALL_DESTROY_USER_DATA=1 prominent for users who need a full purge.
    • Evidence: PRESERVED_USER_DATA_ENTRIES includes rebuild-backups, backups, and sandboxes.json. resolvePreserveSet() preserves them by default for --yes, non-TTY, and NEMOCLAW_NON_INTERACTIVE=1. docs/reference/commands.mdx:1201-1220 says the entries survive as inert files on disk; docs/manage-sandboxes/lifecycle.mdx:261-264 names the preserved entries and purge env var but does not warn about private content.
  • NEMOCLAW_NON_INTERACTIVE wording can imply it replaces the initial uninstall confirmation (docs/manage-sandboxes/lifecycle.mdx:264): The docs group --yes, NEMOCLAW_NON_INTERACTIVE=1, and non-TTY shells as non-interactive preservation contexts. In code, NEMOCLAW_NON_INTERACTIVE=1 only skips the second preservation prompt after the initial Proceed? confirmation has already been accepted; confirm() still skips only when options.assumeYes is true. The new test for NEMOCLAW_NON_INTERACTIVE also supplies a readLine answer of yes for the initial prompt, so it does not prove env-var-only uninstall proceeds without --yes.
    • Recommendation: Clarify that NEMOCLAW_NON_INTERACTIVE=1 controls the preservation prompt but does not by itself acknowledge the initial destructive uninstall confirmation; scripted runs should still pass --yes when they intend to proceed.
    • Evidence: confirm() returns early only for options.assumeYes at run-plan.ts:260, then reads the Proceed? prompt. resolvePreserveSet() treats runtime.env.NEMOCLAW_NON_INTERACTIVE === "1" as non-interactive at run-plan.ts:657-658. The test at run-plan.test.ts:756 uses readLine = vi.fn(() => "yes") and expects it to be called once for the earlier generic confirm prompt.

Workflow run details

This is an automated advisory review. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

E2E Scenario Advisor Recommendation

Required scenario E2E: None
Optional scenario E2E: None

Workflow run

Full scenario advisor summary

E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required scenario E2E

  • None. No scenario workflow, scenario metadata, scenario runtime, or validation-suite files changed.

Optional scenario E2E

  • None.

Relevant changed files

  • None.

…oad wrappers

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@laitingsheng laitingsheng changed the title fix(uninstall): gate destruction of host snapshots behind explicit ack feat(uninstall): bundle host snapshot gate, --save-host, download/upload wrappers May 26, 2026

@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 `@docs/reference/commands.mdx`:
- Around line 1221-1240: Docs/CLI parity: the uninstall docs incorrectly surface
non-uninstall flags like --save-host/--mount/--volume; update the text so it
doesn’t present those tokens as uninstall options. Edit the paragraph that
currently shows the example command and the mount/volume sentence: replace the
example block with a single sentence pointing readers to the existing "nemoclaw
backup-all" and "nemoclaw <name> snapshot create" sections for host-preservation
commands, and change the OpenShell note to say “host mount/volume options” (not
specific flags) and refer to the host-preservation flow described above; keep
references to PROTECTED_USER_DATA_DIRS and NEMOCLAW_UNINSTALL_DESTROY_USER_DATA
unchanged so readers can still find implementation details in
src/lib/actions/uninstall/run-plan.ts.

In `@src/lib/actions/maintenance.ts`:
- Around line 88-90: The current code calls
saveBackupToHost(result.manifest.backupPath, options.saveHost) which writes only
the leaf folder name to the shared host root and can cause collisions when
different sandboxes produce identical leaf names; change the host destination to
include a sandbox-unique prefix (for example sandbox id or full relative path)
so each sandbox writes to its own subfolder (e.g. build a hostPath by joining
options.saveHost with a sandbox identifier from the backup context instead of
using only the leaf folder), and use that hostPath when calling
saveBackupToHost(result.manifest.backupPath, hostPath).
🪄 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: 58df9b5d-9fdc-42e0-9262-529fded96e00

📥 Commits

Reviewing files that changed from the base of the PR and between 412ebf0 and 2fd61ae.

📒 Files selected for processing (15)
  • docs/reference/commands.mdx
  • src/commands/backup-all.ts
  • src/commands/sandbox/download.ts
  • src/commands/sandbox/snapshot/create.ts
  • src/commands/sandbox/upload.ts
  • src/lib/actions/global.ts
  • src/lib/actions/maintenance.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/actions/sandbox/transfer.test.ts
  • src/lib/actions/sandbox/transfer.ts
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts
  • src/lib/cli/public-display-defaults.ts
  • src/lib/state/save-host.test.ts
  • src/lib/state/save-host.ts
✅ Files skipped from review due to trivial changes (2)
  • src/lib/actions/sandbox/transfer.test.ts
  • src/commands/sandbox/upload.ts

Comment thread docs/reference/commands.mdx Outdated
Comment thread src/lib/actions/maintenance.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26444236185
Target ref: 2fd61ae8a74b11816ce469d4bd05ebb1ee6eec62
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e,sandbox-operations-e2e,openshell-gateway-upgrade-e2e
Summary: 4 passed, 0 failed, 0 skipped

Job Result
openshell-gateway-upgrade-e2e ✅ success
sandbox-operations-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

Signed-off-by: Tinson Lai <tinsonl@nvidia.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 `@src/lib/actions/uninstall/run-plan.ts`:
- Around line 169-183: The current fallback for listRegisteredSandboxes (the
anonymous default used when deps.listRegisteredSandboxes is undefined) swallows
any parsing or IO errors and returns [], which can incorrectly allow uninstall
to proceed; change the catch block to surface failures instead of returning an
empty list by rethrowing (or throwing a new Error with context) when JSON.parse
or fs.readFileSync fails so the uninstall flow can fail closed; keep the rest of
the logic (reading env.HOME, checking exists, parsing sandboxes) but replace the
silent catch with a thrown error that includes the registryFile path and the
original error message so callers of listRegisteredSandboxes see the failure.
🪄 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: 4d38e858-7515-4834-a17f-68aeca7b24cd

📥 Commits

Reviewing files that changed from the base of the PR and between 2fd61ae and cec34c1.

📒 Files selected for processing (8)
  • docs/reference/commands.mdx
  • src/commands/global-oclif-command-adapters.test.ts
  • src/lib/actions/global.test.ts
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts
  • src/lib/cli/command-registry.test.ts
  • src/lib/state/save-host.test.ts
  • src/lib/state/save-host.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/actions/global.test.ts

Comment thread src/lib/actions/uninstall/run-plan.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26446362377
Target ref: cec34c18a1ee9b0f699bb1e5fa3a416b752aec28
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e,sandbox-operations-e2e
Summary: 3 passed, 0 failed, 0 skipped

Job Result
sandbox-operations-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

Signed-off-by: Tinson Lai <tinsonl@nvidia.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 `@src/lib/actions/uninstall/run-plan.ts`:
- Around line 761-774: The catch block handling failures from detectUserData()
currently always logs a remediation about the sandbox registry which is
misleading if readdirSync failed on a protected directory; update the catch
handler in run-plan.ts (the catch around detectUserData and any readdirSync
usage) to produce generalized recovery messaging: log the error and a generic
hint such as "check directory permissions or file access for the target path"
and only append the sandbox-registry-specific advice when you can detect the
error path or context (e.g., examine the path variable or error.stack/message
for the sandbox registry string or check error.code like EACCES); ensure you
reference detectUserData and the readdirSync call so the conditional/specific
hint is applied only when the failing path clearly matches the sandbox registry.
- Around line 185-194: In listRegisteredSandboxes, validate the result of
JSON.parse(raw) is a non-null object before accessing data.sandboxes (treat
null/primitive/array as invalid and throw the same parse/invalid registry error)
so JSON.parse("null") cannot cause a TypeError; in runUninstallPlan, broaden the
error messages that currently reference only “registry” when catching failures
from detectUserData to a more general “user-data detection” (or vary text based
on whether the failure originated from listRegisteredSandboxes vs
detectUserData) so messages correctly cover both registry parsing and protected
user-data scan failures.
🪄 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: 070aaf1f-ebe1-4b2f-bd90-23c027b47fbf

📥 Commits

Reviewing files that changed from the base of the PR and between cec34c1 and 06fce3c.

📒 Files selected for processing (2)
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts

Comment thread src/lib/actions/uninstall/run-plan.ts Outdated
Comment thread src/lib/actions/uninstall/run-plan.ts Outdated
Signed-off-by: Tinson Lai <tinsonl@nvidia.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

🧹 Nitpick comments (1)
src/lib/actions/uninstall/run-plan.test.ts (1)

485-486: ⚡ Quick win

Prefix or remove the unused logs fixtures.

These locals are never read in either test, so they should be removed or renamed to _logs if they are intentionally unused.

As per coding guidelines **/*.{js,ts,tsx,jsx}: Unused variables should be prefixed with underscore (_) following Biome conventions.

Also applies to: 568-569

🤖 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/actions/uninstall/run-plan.test.ts` around lines 485 - 486, The test
file declares unused locals logs and errors in the uninstall run-plan tests;
either remove those unused variables or rename them to _logs and _errors to
follow the Biome convention for unused variables; update both occurrences of
these locals (the const declarations where logs and errors are defined in the
run-plan.test.ts tests) so linters stop flagging them.
🤖 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/actions/uninstall/run-plan.ts`:
- Around line 782-789: The code logs a refusal and remediation even when the
ack-bypass env var is set; change the control flow so that after computing
message and remediation you check
runtime.env.NEMOCLAW_UNINSTALL_DESTROY_USER_DATA === "1" first and, if true,
skip logging the "Refusing to proceed" and remediation lines and instead log
only the acknowledgment note (ackBypassNote) and return true; otherwise proceed
to runtime.error the message, refusal and remediation and return false. Target
the block that uses message, remediation, ackBypassNote and
runtime.env.NEMOCLAW_UNINSTALL_DESTROY_USER_DATA in run-plan.ts.

---

Nitpick comments:
In `@src/lib/actions/uninstall/run-plan.test.ts`:
- Around line 485-486: The test file declares unused locals logs and errors in
the uninstall run-plan tests; either remove those unused variables or rename
them to _logs and _errors to follow the Biome convention for unused variables;
update both occurrences of these locals (the const declarations where logs and
errors are defined in the run-plan.test.ts tests) so linters stop flagging them.
🪄 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: a041ac3a-c005-41f0-853d-152e552fdd0f

📥 Commits

Reviewing files that changed from the base of the PR and between 06fce3c and 4e0ec06.

📒 Files selected for processing (2)
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts

Comment thread src/lib/actions/uninstall/run-plan.ts Outdated
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
…links

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26448971616
Target ref: e4ae80a40c0c2da3c58cabcc5f35008c5cc17b6e
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e
Summary: 2 passed, 0 failed, 0 skipped

Job Result
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

…emoclaw

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26449943142
Target ref: 112bcf872848f3f93ec40b8501a588518d154c9a
Workflow ref: main
Requested jobs: state-backup-restore-e2e,snapshot-commands-e2e,sandbox-operations-e2e
Summary: 2 passed, 1 failed, 0 skipped

Job Result
sandbox-operations-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ❌ failure

Failed jobs: state-backup-restore-e2e. Check run artifacts for logs.

Signed-off-by: Tinson Lai <tinsonl@nvidia.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

🧹 Nitpick comments (1)
docs/manage-sandboxes/lifecycle.mdx (1)

261-261: ⚡ Quick win

Use one sentence per source line in the Note text.

Line 261 currently contains multiple sentences on a single line; split them into separate lines to match docs formatting rules.

As per coding guidelines, "One sentence per line in source (makes diffs readable)."

🤖 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 `@docs/manage-sandboxes/lifecycle.mdx` at line 261, The Note paragraph
containing the sentence starting "Before destroying anything, uninstall now
scans for workspace state — host snapshots under `~/.nemoclaw/rebuild-backups/`
and `~/.nemoclaw/backups/`, registered sandboxes in
`~/.nemoclaw/sandboxes.json`, and running Docker containers matching the
sandbox/gateway pattern." should be split so each sentence is on its own source
line; edit the Note block in docs/manage-sandboxes/lifecycle.mdx to break that
long line into separate lines for each sentence (separate the scan description,
the gate refusal behavior, and the `--yes`/exit status detail into individual
lines) to comply with the one-sentence-per-line rule.
🤖 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 `@docs/manage-sandboxes/lifecycle.mdx`:
- Line 261: The sentence currently says the uninstall gate checks "running
Docker containers matching the sandbox/gateway pattern" but the gate actually
inspects Docker's container listing (including stopped or unregistered
containers), so update the text in lifecycle.mdx to clarify that the gate
inventories Docker containers matching the sandbox/gateway pattern from Docker's
listing — including stopped or unregistered containers — and will refuse to
proceed if any are found, even with `--yes` set.

---

Nitpick comments:
In `@docs/manage-sandboxes/lifecycle.mdx`:
- Line 261: The Note paragraph containing the sentence starting "Before
destroying anything, uninstall now scans for workspace state — host snapshots
under `~/.nemoclaw/rebuild-backups/` and `~/.nemoclaw/backups/`, registered
sandboxes in `~/.nemoclaw/sandboxes.json`, and running Docker containers
matching the sandbox/gateway pattern." should be split so each sentence is on
its own source line; edit the Note block in docs/manage-sandboxes/lifecycle.mdx
to break that long line into separate lines for each sentence (separate the scan
description, the gate refusal behavior, and the `--yes`/exit status detail into
individual lines) to comply with the one-sentence-per-line rule.
🪄 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: 3a63d45a-72c2-4150-b449-8d40525c9252

📥 Commits

Reviewing files that changed from the base of the PR and between 112bcf8 and 032147a.

📒 Files selected for processing (3)
  • docs/manage-sandboxes/lifecycle.mdx
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts

Comment thread docs/manage-sandboxes/lifecycle.mdx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26451568604
Target ref: 032147ab8d7c2a2bffb152e125e89b49bab460d5
Workflow ref: main
Requested jobs: state-backup-restore-e2e,snapshot-commands-e2e,openshell-gateway-upgrade-e2e
Summary: 2 passed, 1 failed, 0 skipped

Job Result
openshell-gateway-upgrade-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ❌ failure

Failed jobs: state-backup-restore-e2e. Check run artifacts for logs.

Signed-off-by: Tinson Lai <tinsonl@nvidia.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.

🧹 Nitpick comments (3)
docs/reference/commands.mdx (3)

1224-1224: ⚡ Quick win

Split into one sentence per line.

This line contains two sentences joined by a semicolon.
Per the style guide, "One sentence per line in source (makes diffs readable)."

Suggested edit
-The list of protected directories lives in `PROTECTED_USER_DATA_DIRS` in `src/lib/actions/uninstall/run-plan.ts`; additions to this list automatically extend the gate.
+The list of protected directories lives in `PROTECTED_USER_DATA_DIRS` in `src/lib/actions/uninstall/run-plan.ts`.
+Additions to this list automatically extend the gate.

As per coding guidelines: "One sentence per line in source (makes diffs readable). Flag paragraphs where multiple sentences appear on the same line."

🤖 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 `@docs/reference/commands.mdx` at line 1224, The sentence contains two
sentences joined by a semicolon; split it into two lines so each sentence is on
its own line in source: make one line "The list of protected directories lives
in `PROTECTED_USER_DATA_DIRS` in `src/lib/actions/uninstall/run-plan.ts`." and
the next line "Additions to this list automatically extend the gate." and ensure
you update the docs file `docs/reference/commands.mdx` accordingly so diffs
remain clean.

1227-1227: ⚡ Quick win

Split into one sentence per line.

This line contains two sentences joined by a semicolon.

Suggested edit
-Both `nemoclaw backup-all` and `nemoclaw <name> snapshot create` expose a host-copy option that places each backup directory into a destination you supply, so the data survives the `~/.nemoclaw/` wipe; see those command sections for the exact invocation.
+Both `nemoclaw backup-all` and `nemoclaw <name> snapshot create` expose a host-copy option that places each backup directory into a destination you supply, so the data survives the `~/.nemoclaw/` wipe.
+See those command sections for the exact invocation.

As per coding guidelines: "One sentence per line in source (makes diffs readable)."

🤖 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 `@docs/reference/commands.mdx` at line 1227, The sentence contains two
sentences joined by a semicolon—split them into separate lines so each sentence
is one line in the source: put the sentence about "Both `nemoclaw backup-all`
and `nemoclaw <name> snapshot create` expose a host-copy option that places each
backup directory into a destination you supply." on its own line, and move "so
the data survives the `~/.nemoclaw/` wipe; see those command sections for the
exact invocation." onto the next line, replacing the semicolon with a period (or
reword to start with "See those command sections for the exact invocation.") so
each logical sentence is a standalone line.

1232-1232: ⚡ Quick win

Split into one sentence per line.

This line contains two sentences joined by a semicolon.

Suggested edit
-OpenShell's `sandbox create` does not currently expose host mount or volume options, so NemoClaw cannot mount workspace state on a persistent host volume; the host-copy flow referenced above is the workaround for that constraint.
+OpenShell's `sandbox create` does not currently expose host mount or volume options, so NemoClaw cannot mount workspace state on a persistent host volume.
+The host-copy flow referenced above is the workaround for that constraint.

As per coding guidelines: "One sentence per line in source (makes diffs readable)."

🤖 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 `@docs/reference/commands.mdx` at line 1232, The line containing "OpenShell's
`sandbox create` does not currently expose host mount or volume options, so
NemoClaw cannot mount workspace state on a persistent host volume; the host-copy
flow referenced above is the workaround for that constraint." should be split
into two sentences on separate lines: replace the semicolon with a period and
break after the first sentence so each sentence appears on its own line (first
line: OpenShell's `sandbox create` does not currently expose host mount or
volume options. second line: NemoClaw cannot mount workspace state on a
persistent host volume, so the host-copy flow referenced above is the workaround
for that constraint.).
🤖 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 `@docs/reference/commands.mdx`:
- Line 1224: The sentence contains two sentences joined by a semicolon; split it
into two lines so each sentence is on its own line in source: make one line "The
list of protected directories lives in `PROTECTED_USER_DATA_DIRS` in
`src/lib/actions/uninstall/run-plan.ts`." and the next line "Additions to this
list automatically extend the gate." and ensure you update the docs file
`docs/reference/commands.mdx` accordingly so diffs remain clean.
- Line 1227: The sentence contains two sentences joined by a semicolon—split
them into separate lines so each sentence is one line in the source: put the
sentence about "Both `nemoclaw backup-all` and `nemoclaw <name> snapshot create`
expose a host-copy option that places each backup directory into a destination
you supply." on its own line, and move "so the data survives the `~/.nemoclaw/`
wipe; see those command sections for the exact invocation." onto the next line,
replacing the semicolon with a period (or reword to start with "See those
command sections for the exact invocation.") so each logical sentence is a
standalone line.
- Line 1232: The line containing "OpenShell's `sandbox create` does not
currently expose host mount or volume options, so NemoClaw cannot mount
workspace state on a persistent host volume; the host-copy flow referenced above
is the workaround for that constraint." should be split into two sentences on
separate lines: replace the semicolon with a period and break after the first
sentence so each sentence appears on its own line (first line: OpenShell's
`sandbox create` does not currently expose host mount or volume options. second
line: NemoClaw cannot mount workspace state on a persistent host volume, so the
host-copy flow referenced above is the workaround for that constraint.).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 12931477-ddf0-4859-aaef-4f5e894fda1a

📥 Commits

Reviewing files that changed from the base of the PR and between 032147a and 3b947a2.

📒 Files selected for processing (5)
  • docs/reference/commands.mdx
  • src/lib/actions/uninstall/run-plan.test.ts
  • src/lib/actions/uninstall/run-plan.ts
  • src/lib/state/save-host.test.ts
  • src/lib/state/save-host.ts
💤 Files with no reviewable changes (3)
  • src/lib/state/save-host.test.ts
  • src/lib/state/save-host.ts
  • src/lib/actions/uninstall/run-plan.test.ts

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26453472576
Target ref: 3b947a281405e5cf6f07bdbbfb89b42fb000bfbc
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e,sandbox-operations-e2e
Summary: 3 passed, 0 failed, 0 skipped

Job Result
sandbox-operations-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26590962649
Target ref: 2c070fa5ffd04792b96d36d40c9a3650fccba857
Workflow ref: main
Requested jobs: docs-validation-e2e
Summary: 1 passed, 0 failed, 0 skipped

Job Result
docs-validation-e2e ✅ success

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26592087649
Target ref: 9c883db61ada91cc1a48af0111a6c2904f6920d5
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e
Summary: 2 passed, 0 failed, 0 skipped

Job Result
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

…v, active-voice docs

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26593127514
Target ref: 0418a11e99bb2364386e10ad7e7ca6726e218880
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e,docs-validation-e2e
Summary: 3 passed, 0 failed, 0 skipped

Job Result
docs-validation-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

@cv cv added the v0.0.55 label May 28, 2026
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ No requested jobs ran

Run: 26594930772
Target ref: 3393b36e12c04db71788834241af6eb7ed821d78
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e,gpu-e2e
Summary: 0 passed, 0 failed, 1 skipped

Job Result
gpu-e2e ⏭️ skipped
snapshot-commands-e2e ⚠️ cancelled
state-backup-restore-e2e ⚠️ cancelled

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26595172990
Target ref: 48792d1029cc1a67474fbdcc0446ae182873aaf9
Workflow ref: main
Requested jobs: snapshot-commands-e2e,state-backup-restore-e2e
Summary: 2 passed, 0 failed, 0 skipped

Job Result
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success

@jyaunches jyaunches added R1 v0.0.56 Release target and removed v0.0.55 labels May 29, 2026
@cv cv merged commit d1e42b4 into main May 30, 2026
35 checks passed
@cv cv deleted the fix-4226-uninstall-confirm-backups branch May 30, 2026 01:11
miyoungc added a commit that referenced this pull request Jun 1, 2026
## Summary

- Adds the v0.0.56 release notes section with links to the deeper docs
pages for installer, status, inference, messaging, policy, and lifecycle
changes.
- Updates source docs for the remaining release-prep gaps around `uv` in
the PyPI preset, compact WhatsApp pairing guidance, and `nemoclaw
inference set` command boundaries.
- Refreshes generated `nemoclaw-user-*` skills and removes skipped
experimental command terms from generated skill surfaces.

## Source summary

- #4613 -> `docs/manage-sandboxes/lifecycle.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Documents
that public installs and `nemoclaw update` follow the maintained `lkg`
tag by default.
- #4419 -> `docs/about/release-notes.mdx`: Notes that non-interactive
Linux installs can reactivate Docker group membership and continue in
one installer run when `sg docker` is available.
- #4550 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Captures live sandbox agent-version
probing for status, connect, and upgrade checks.
- #4609 -> `docs/inference/use-local-inference.mdx`,
`docs/about/release-notes.mdx`: Captures the GPU Docker-driver
host-network local-inference reachability gate.
- #4607 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Documents
compact WhatsApp QR pairing guidance and gateway/session diagnostics.
- #4582 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Reflects
Slack credential validation before enabling the channel.
- #4554 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/troubleshooting.mdx`, `docs/about/release-notes.mdx`:
Keeps Telegram allowlist alias guidance in the generated user skills and
release notes.
- #4563 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Includes the new `nemoclaw <name> skill
remove <skill>` command in command docs and release notes.
- #4566 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Documents the `nemoclaw inference set`
redirect boundary when `--provider` or `--model` is missing.
- #4323 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Captures per-sandbox status JSON
support.
- #4506 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Captures debug command sandbox-name
validation and safer tarball writing.
- #4569 -> `docs/network-policy/integration-policy-examples.mdx`,
`docs/about/release-notes.mdx`: Documents that the `pypi` preset allows
`/usr/local/bin/uv`.
- #4579 -> `docs/network-policy/integration-policy-examples.mdx`,
`docs/about/release-notes.mdx`: Captures observable Jira preset
validation guidance.
- #4229 -> `docs/manage-sandboxes/lifecycle.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Documents
user-data preservation defaults for uninstall.
- #4399 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Captures CPU-only sandbox intent
preservation across rebuilds.
- #4058 -> `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Captures safer snapshot restore behavior
around existing destinations.
- #4155 and #4460 -> skipped by `docs/.docs-skip`: Removed skipped
experimental command terms from source docs and generated skill evals
instead of documenting those features.

## Verification

- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --doc-platform fern-mdx`
- `npm run docs` (passes; Fern reports the pre-existing light-mode
accent contrast warning)
- `rg "permissive mode|shields down|shields up|shields status|config
rotate-token|rotate-token" .agents/skills` (no matches)
- `npm run build:cli` (run to refresh local CLI artifacts for the
pre-push TypeScript hook)
- Commit hooks passed, including `NEMOCLAW_* env-var documentation
gate`, `Verify docs-to-skills output`, `markdownlint-cli2`, `gitleaks`,
and `Test (skills YAML)`.

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

* **Documentation**
* Expanded Model Router setup with YAML examples, flow diagrams, and
credential handling; strengthened agent-config immutability and
integrity guidance; messaging channels updated (Telegram aliases,
WhatsApp pairing/diagnostics); CLI docs revised (GPU detection,
inference set behavior, uninstall/rebuild preservation); overview
rebranded to NemoClaw and added v0.0.56 release notes.

* **New Features**
* Added `nemoclaw <name> channels status` (messaging diagnostics, JSON);
added `nemoclaw <name> skill remove`; Hermes no longer marked
experimental; DGX Spark quickstart sandbox-name note.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression and removed NemoClaw CLI 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: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression v0.0.56 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Ubuntu 24.04][Install] nemoclaw uninstall destroys all user data — workspace files (USER.md, SOUL.md) and snapshots not preserved

5 participants