Skip to content

feat(blueprint): add snapshot prune/delete commands for retention management - #5453

Merged
cv merged 16 commits into
NVIDIA:mainfrom
vasanth53:feat/snapshot-retention-management
Jul 11, 2026
Merged

cv merged 16 commits into
NVIDIA:mainfrom
vasanth53:feat/snapshot-retention-management

Conversation

@vasanth53

@vasanth53 vasanth53 commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds snapshots list, snapshots prune --keep <N>, and snapshots delete --path <path> subcommands to the blueprint runner, letting users manage disk space consumed by accumulated migration snapshots under ~/.nemoclaw/snapshots/.

Changes

File Change
nemoclaw/src/blueprint/snapshot.ts Added deleteSnapshot(), pruneSnapshots() with symlink-attack rejection
nemoclaw/src/blueprint/snapshot.test.ts 8 tests covering deletion, symlink rejection, prune with keep count, empty state
nemoclaw/src/blueprint/runner.ts Added snapshots action with list, prune, delete subcommands and usage text
nemoclaw/src/blueprint/runner.test.ts 12 tests for CLI routing, list/prune/delete flows; extended fs mock with lstatSync, readlinkSync, rmSync
ci/test-file-size-budget.json Ratcheted runner.test.ts size budget to 1622 lines

Usage

nemoclaw blueprint snapshots list
nemoclaw blueprint snapshots prune --keep 5
nemoclaw blueprint snapshots delete --path ~/.nemoclaw/snapshots/20260101T000000Z

Testing

All 503 plugin tests pass. All hooks pass (pre-commit, commitlint). New code adds 20 tests across two test files.

Checklist

  • Conventional Commit (feat(blueprint):)
  • DCO sign-off
  • Tests added/updated
  • All tests pass
  • Hooks pass (pre-commit, commitlint)
  • Feature branch from main

Closes #5452

Summary by CodeRabbit

  • New Features
    • Added a top-level snapshots CLI action with list, prune --keep <N>, and delete --path <path>.
    • list shows snapshot metadata (or “No snapshots found.”); prune validates --keep and reports kept/deleted/failed; delete safely removes snapshots and prints Deleted snapshot: (including for non-existent targets).
  • Bug Fixes
    • Tightened snapshot selection so only directories whose manifest timestamp exactly matches are considered.
    • Improved safety checks to prevent deleting outside the snapshots root and to reject symlink targets.
  • Tests
    • Expanded unit and CLI tests for retention, validation, error messaging, and failure reporting; added real-filesystem safety coverage (skipped on Windows).

Signed-off-by: Prekshi Vyas prekshiv@nvidia.com

@copy-pr-bot

copy-pr-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds strict snapshot validation, anchored symlink-safe deletion, retention pruning, and a snapshots CLI action with list, prune --keep <N>, and delete --path <path> subcommands. Tests cover filesystem safety, validation, failure reporting, retention behavior, and CLI output.

Changes

Snapshot Retention Management

Layer / File(s) Summary
Snapshot validation, deletion, and pruning
nemoclaw/src/blueprint/snapshot.ts, nemoclaw/src/blueprint/snapshot.test.ts, nemoclaw/src/blueprint/snapshot-realfs.test.ts
Validates timestamped snapshot directories and manifests, deletes snapshot subtrees through an anchored helper, prunes older snapshots, and tests safety, retention, and failure behavior.
Snapshots CLI action and integration
nemoclaw/src/blueprint/runner.ts, nemoclaw/src/blueprint/snapshot.test.ts
Adds top-level dispatch and list, prune, and delete subcommands with argument validation, path containment checks, sanitized output, failure handling, and CLI tests.

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

Suggested labels: feature

Suggested reviewers: cv, jyaunches

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.81% 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 clearly summarizes the main change: adding snapshot prune/delete retention commands in the blueprint CLI.
Linked Issues check ✅ Passed The PR implements snapshots list/prune/delete, symlink-safe deletion, and prune delegation as requested in #5452.
Out of Scope Changes check ✅ Passed The changes stay within snapshot retention management and its tests, with no obvious unrelated feature work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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 `@nemoclaw/src/blueprint/snapshot.ts`:
- Around line 329-346: The pruneSnapshots function silently excludes snapshot
paths when deleteSnapshot returns false, leaving them out of both the deleted
and kept arrays, which hides failures from users. Add a failed array to track
snapshot paths where deleteSnapshot returns false, and include it in the
returned object alongside deleted and kept. This gives users visibility into
which specific snapshots failed to delete and why the counts might not add up to
the total.
🪄 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: c471987d-87b6-4b91-bb33-a58a59186f72

📥 Commits

Reviewing files that changed from the base of the PR and between f4f3c58 and 66dc1d2.

📒 Files selected for processing (5)
  • ci/test-file-size-budget.json
  • nemoclaw/src/blueprint/runner.test.ts
  • nemoclaw/src/blueprint/runner.ts
  • nemoclaw/src/blueprint/snapshot.test.ts
  • nemoclaw/src/blueprint/snapshot.ts

Comment thread nemoclaw/src/blueprint/snapshot.ts Outdated
@vasanth53
vasanth53 force-pushed the feat/snapshot-retention-management branch from 66dc1d2 to 337c93b Compare June 15, 2026 06:31

@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)
nemoclaw/src/blueprint/snapshot.ts (1)

319-327: ⚡ Quick win

Consider validating that snapshotPath is within SNAPSHOTS_DIR.

rejectSymlinksOnPath guards against symlink attacks under HOME but doesn't restrict deletion to the snapshots directory. A user could inadvertently (or maliciously via a compromised script) run snapshots delete --path ~/.ssh and delete unrelated directories.

Adding a prefix check provides defense-in-depth:

🛡️ Suggested validation
 export function deleteSnapshot(snapshotPath: string): boolean {
   try {
+    const resolved = resolve(snapshotPath);
+    if (!resolved.startsWith(SNAPSHOTS_DIR + '/') && resolved !== SNAPSHOTS_DIR) {
+      return false;
+    }
     rejectSymlinksOnPath(snapshotPath);
     rmSync(snapshotPath, { recursive: true, force: true });
     return true;
   } catch {
     return false;
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nemoclaw/src/blueprint/snapshot.ts` around lines 319 - 327, The
deleteSnapshot function currently only guards against symlinks but doesn't
restrict path deletion to the SNAPSHOTS_DIR directory, allowing arbitrary
directory deletion. Add a validation check in deleteSnapshot that ensures
snapshotPath is within SNAPSHOTS_DIR before proceeding with rejectSymlinksOnPath
and rmSync calls. If the path is outside SNAPSHOTS_DIR, return false to prevent
the deletion.
🤖 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 `@nemoclaw/src/blueprint/snapshot.ts`:
- Around line 329-333: The pruneSnapshots function does not validate the keep
parameter for negative values, and when keep is negative, the slice(keep)
operation will behave unexpectedly by returning elements from the end of the
array. Add a defensive guard at the beginning of the pruneSnapshots function to
either throw an error for invalid negative values or clamp the keep value to a
minimum of 0 to ensure predictable behavior.

---

Nitpick comments:
In `@nemoclaw/src/blueprint/snapshot.ts`:
- Around line 319-327: The deleteSnapshot function currently only guards against
symlinks but doesn't restrict path deletion to the SNAPSHOTS_DIR directory,
allowing arbitrary directory deletion. Add a validation check in deleteSnapshot
that ensures snapshotPath is within SNAPSHOTS_DIR before proceeding with
rejectSymlinksOnPath and rmSync calls. If the path is outside SNAPSHOTS_DIR,
return false to prevent the deletion.
🪄 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: 4406e8b8-b940-40ca-bc6a-54f757bce558

📥 Commits

Reviewing files that changed from the base of the PR and between 66dc1d2 and 337c93b.

📒 Files selected for processing (5)
  • ci/test-file-size-budget.json
  • nemoclaw/src/blueprint/runner.test.ts
  • nemoclaw/src/blueprint/runner.ts
  • nemoclaw/src/blueprint/snapshot.test.ts
  • nemoclaw/src/blueprint/snapshot.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • ci/test-file-size-budget.json
  • nemoclaw/src/blueprint/snapshot.test.ts
  • nemoclaw/src/blueprint/runner.test.ts
  • nemoclaw/src/blueprint/runner.ts

Comment thread nemoclaw/src/blueprint/snapshot.ts Outdated
@vasanth53
vasanth53 force-pushed the feat/snapshot-retention-management branch from 337c93b to 5e76755 Compare June 15, 2026 06:37

@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 `@nemoclaw/src/blueprint/runner.ts`:
- Around line 1092-1104: The delete command accepts a user-provided --path
argument that is passed directly to deleteSnapshot without validation, allowing
deletion of arbitrary directories outside the snapshots directory. After
extracting snapshotPath from argv (around line 1095), add validation to ensure
the path is constrained to the snapshots directory by resolving it to an
absolute path and verifying it starts with the expected snapshots directory path
(typically ~/.nemoclaw/snapshots). Reject the command with an appropriate error
message if the resolved path attempts to escape the snapshots directory. This
validation must occur before the deleteSnapshot function is called to prevent
unauthorized recursive deletion of directories outside the snapshots location.
- Around line 1065-1067: The `Number.parseInt` function at the keep variable
assignment performs lenient parsing and will accept malformed inputs like "3abc"
or "1.5" by silently truncating them to 3 and 1 respectively. To enforce the
"non-negative integer" requirement strictly, validate that the entire input
string represents a pure integer with no trailing characters or decimal points.
You can do this by checking that the parsed keep value, when converted back to a
string, matches the original trimmed input value, or by validating the input
format using a regex pattern that matches only optional whitespace and
non-negative integer digits before attempting to parse.
🪄 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: bd9bfb48-d9d7-47f7-8974-9fc2e082f74f

📥 Commits

Reviewing files that changed from the base of the PR and between 337c93b and 5e76755.

📒 Files selected for processing (3)
  • nemoclaw/src/blueprint/runner.ts
  • nemoclaw/src/blueprint/snapshot.test.ts
  • nemoclaw/src/blueprint/snapshot.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • nemoclaw/src/blueprint/snapshot.ts
  • nemoclaw/src/blueprint/snapshot.test.ts

Comment thread nemoclaw/src/blueprint/runner.ts Outdated
Comment thread nemoclaw/src/blueprint/runner.ts Outdated
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output feature PR adds or expands user-visible functionality labels Jun 23, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for adding the snapshots list, snapshots prune --keep <N>, and snapshots delete --path <path> subcommands to the blueprint runner. This proposes a way to manage disk space consumed by accumulated migration snapshots under ~/.nemoclaw/snapshots/ through new CLI commands.


Related open issues:

1 similar comment
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for adding the snapshots list, snapshots prune --keep <N>, and snapshots delete --path <path> subcommands to the blueprint runner. This proposes a way to manage disk space consumed by accumulated migration snapshots under ~/.nemoclaw/snapshots/ through new CLI commands.


Related open issues:

@cv cv added the v0.0.80 label Jul 9, 2026
@prekshivyas prekshivyas self-assigned this Jul 9, 2026
@cv cv added the needs: info Waiting on author for missing details label Jul 9, 2026
@cv

cv commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Contributor compliance is still blocking review: the PR body lacks a valid Signed-off-by: declaration and three commits are not GitHub Verified. Please publish a clean Verified history and add the DCO declaration; if this branch cannot be rewritten safely, open a fresh PR.

Add snapshot list, prune, and delete commands for blueprint-managed OpenClaw migration snapshots.

Report failed prune deletions explicitly and strictly validate prune counts.

Constrain delete paths to child entries under the snapshots directory before recursive removal.

Co-authored-by: vasanth53 <vasanth@peak42.in>

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas
prekshivyas force-pushed the feat/snapshot-retention-management branch from 2beb2fb to be3b7be Compare July 10, 2026 15:45
@prekshivyas prekshivyas removed the needs: info Waiting on author for missing details label Jul 10, 2026
@prekshivyas

Copy link
Copy Markdown
Collaborator

Exact-head rewrite at be3b7be2: rebuilt the PR as a single GitHub-Verified signed commit with DCO in the commit and PR body. Also fixed the still-valid review items: prune now reports failed deletions, --keep parsing is strict, delete paths are constrained under the snapshots directory, and the CLI rejects escaped/root snapshot paths before recursive deletion. Local validation passed: focused Vitest snapshot/runner suites, Biome lint/format, typecheck, source-shape, pre-commit, and pre-push. Exact-head snapshot-commands E2E is dispatched in run 29104926968.

@prekshivyas

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 29104926968
Workflow ref: tmp/e2e/pr-5453-snapshot-be3b7be2e
Requested targets: snapshot-commands
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
snapshot-commands ✅ success

@prekshivyas

Copy link
Copy Markdown
Collaborator

Follow-up validation is now green at exact head be3b7be2: snapshot-commands E2E passed in run 29104926968, E2E Advisor passed in run 29105508088, and PR Review Advisor passed in run 29105792203 for both GPT-5.5 and Nemotron Ultra. CodeRabbit re-review command also completed with no new action requested after the clean rewrite.

@cjagwani cjagwani left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Exact-head security review at be3b7be2e19c7c79e79e03483696b0be1231481d: changes required before approval.

  1. nemoclaw/src/blueprint/snapshot.ts:319-325 validates the snapshot path and its symlink components, then calls path-based recursive rmSync. A concurrent replacement of the snapshots ancestor after validation can redirect deletion outside the snapshot tree. Please close this ancestor-swap TOCTOU boundary with a no-follow/beneath deletion design, or narrow the feature to a deletion primitive whose containment can be guaranteed.
  2. snapshot.ts:345-351,379-394 trusts mutable manifest timestamps for prune ordering. Require identity/timestamp agreement with a strictly validated direct-child snapshot directory name and sort from that trusted identity.
  3. nemoclaw/src/blueprint/runner.ts:1048-1051 prints mutable manifest/path fields without stripping control characters or bounding them.

The current shard-4 timeout is unrelated to this diff (the failing MCP test blob is unchanged from the parent), but it has repeated and remains a separate red required check.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Exact-head maintainer sweep at be3b7be2e1: the current shard-4 red is the unrelated known 5-second timeout in mcp-bridge-status-resolution.test.ts, so that check can be rerun after the source fix below.

One command-contract blocker remains in this PR. pruneSnapshots() correctly returns a failed list, and the snapshots prune handler prints each failed path, but then falls through successfully. The runner protocol explicitly defines exit code 0 as success, so a partial or total prune failure is currently reported to callers and automation as success even though requested retention was not achieved.

Please preserve the per-path summary but make any non-empty failed result exit nonzero, and add a command-level regression that injects a deletion failure, asserts the failed path is reported, and asserts the command rejects or exits nonzero. After that, rerun ordinary CI, obtain trusted fork-context advisor review, and run the snapshot-focused live target recommended for the exact head.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: state-backup-restore, upgrade-stale-sandbox
Optional E2E: None

Dispatch hint: state-backup-restore,upgrade-stale-sandbox

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: target/main
Head: HEAD
Confidence: high

Required E2E

  • state-backup-restore (medium): Required by the deterministic risk plan for upgrade/rebuild snapshot and restore changes. It validates that state backup and restore paths preserve user workspace and runtime state across real lifecycle operations.
  • upgrade-stale-sandbox (medium): Required by the deterministic risk plan for upgrade/rebuild snapshot changes. It exercises replacing stale runtime state while preserving credentials, policy, registry, and workspace state in a live sandbox upgrade/rebuild path.

Optional E2E

  • None.

New E2E recommendations

  • blueprint snapshot retention CLI (high): This PR introduces user-facing snapshots list, snapshots prune, and snapshots delete behavior plus destructive host filesystem deletion safeguards. Existing required E2E jobs cover broader backup/restore and upgrade invariants but do not appear to exercise the new snapshot-retention CLI end-to-end against a real packaged runner and host snapshot directory.
    • Suggested test: Add an E2E test that creates timestamped ~/.nemoclaw/snapshots entries, runs the packaged blueprint runner snapshots list/prune/delete commands, verifies retained/deleted entries, and confirms symlink/out-of-root paths are rejected without deleting outside files.

Dispatch hint

  • Workflow: e2e.yaml
  • jobs input: state-backup-restore,upgrade-stale-sandbox

@github-actions

github-actions Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: state-backup-restore, upgrade-stale-sandbox
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=state-backup-restore
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: target/main
Head: HEAD
Confidence: high

Required E2E targets

  • state-backup-restore: Upgrade, rebuild, snapshot, and restore operations must preserve user state while replacing stale runtime state.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=state-backup-restore
  • upgrade-stale-sandbox: Upgrade, rebuild, snapshot, and restore operations must preserve user state while replacing stale runtime state.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox

Optional E2E targets

  • None.

Relevant changed files

  • nemoclaw/src/blueprint/runner.ts
  • nemoclaw/src/blueprint/snapshot-command.ts
  • nemoclaw/src/blueprint/snapshot-delete-helper.ts
  • nemoclaw/src/blueprint/snapshot-management.ts
  • nemoclaw/src/blueprint/snapshot.ts

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29125993228
Workflow ref: tmp/e2e/pr-5453-snapshot-977dabde
Requested targets: (default — all supported)
Requested jobs: snapshot-commands,state-backup-restore,upgrade-stale-sandbox
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
snapshot-commands ✅ success
state-backup-restore ✅ success
upgrade-stale-sandbox ✅ success

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Exact-head re-review of 977dabde0cc24f595ee3c4a19c26ef7a3a08b74f: the prior Python startup vulnerability is fixed. python3 -I, buildSubprocessEnv(), the hostile real-process sitecustomize regression, fd-relative no-follow deletion, all ordinary CI, and all three required live jobs now pass.

One merge-gate item remains: both trusted exact-head advisors independently return merge_after_fixes for the same architecture concern. This PR adds 225 production lines to security-sensitive snapshot.ts, 128 to the already-central runner.ts, and 465 to snapshot.test.ts (977 changed lines total). The new retention/deletion boundary and the snapshots CLI parser are cohesive surfaces and should not remain embedded in those existing modules.

Please perform a behavior-neutral extraction of the new retention/delete helper into a focused snapshot-retention module and the new CLI parsing/dispatch into a focused command module, with the corresponding new tests split alongside those surfaces. Preserve the now-verified subprocess and fd-relative security contracts unchanged. I am not treating the advisors' native-Windows, manifest-order, real-FS prune, or negative-keep notes as blockers; those are already handled, outside supported native-Windows scope, or explicitly tested.

After the mechanical split, rerun the focused snapshot suites, package checks, exact-head ordinary CI, the three live jobs, and trusted advisors. That should leave this otherwise-correct PR ready for approval.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>

@cjagwani cjagwani left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

follow-up at f159b21aaf81b23889a7117a73d8792ee7a6ac8e: the requested extraction is structurally good. runner.ts and snapshot.ts are substantially smaller, and the command, retention, and fd-relative deletion boundaries now live in focused modules. Two current-head issues remain before approval.

  1. The split made the snapshot tests materially nondeterministic. Repeating the exact focused plugin command below produced 6 passes and 4 failures in the latest 10-run sample (with 10/17 passes in an earlier sample):

npm test -- --run src/blueprint/snapshot.test.ts src/blueprint/snapshot-management.test.ts src/blueprint/snapshot-command.test.ts src/blueprint/snapshot-realfs.test.ts src/blueprint/runner.test.ts --silent

Failures vary between snapshot-command.test.ts:102 (the expected partial-failure throw disappears), snapshot-management.test.ts:76 (the trusted snapshot list is empty), snapshot-realfs.test.ts:82 (nothing is deleted), snapshot-command.test.ts:91 (No snapshots found), and snapshot-realfs.test.ts:193 (deleteSnapshot returns false). The prior 977dabde suites showed one related home-mock failure in 24 observed runs, but f159 adds two more files that repeatedly reset modules and dynamically mock node:os, alongside process-global PATH/platform stubs, and makes the race dramatically reproducible. Please give the extracted modules/tests a stable snapshot-root/platform/helper seam or otherwise scope the mocks deterministically, then demonstrate repeated normal-run stability. A one-off 553/553 pass is not sufficient for a 40% focused failure rate.

  1. The exact GPT advisor correctly found that the new destructive user-facing commands are undocumented. Please document ~/.nemoclaw/snapshots/, snapshots list, snapshots prune --keep <N>, and snapshots delete --path <path>, including retention/data-loss guidance and the native-Windows/WSL limitation, then run the docs build.

The direct pruneSnapshots(-1) and native-Windows command-level behavior changed during the nominally behavior-neutral split. Those are not independent blockers because the CLI validates keep values and Windows deletion was already unsupported, but please either preserve the old behavior or make the intentional change explicit in tests/docs.

After the deterministic test repair and docs update, refresh ordinary CI, both advisors, and the three required snapshot/state live jobs. The stronger fd-relative deletion boundary itself remains accepted.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@cjagwani

cjagwani commented Jul 10, 2026 •

Copy link
Copy Markdown
Collaborator

follow-up at 5be7602c3b18c05cf3ae41e21ae0eb917e51276b: the new host-state documentation addresses the GPT warning, and npm run docs passes with 0 errors and the same 2 pre-existing warnings. Thank you; that item is resolved.

The deterministic-test blocker from review #4675321850 remains because this commit does not change the dynamic HOME/PATH/platform seams. The exact five-file focused command passed 9/10 in the first current-head sample, then failed again on a later attempt at snapshot-management.test.ts:109 (deleteSnapshot() for a missing timestamp child returned false instead of true). Please replace or reliably scope the dynamic node:os module resets/process-global stubs and demonstrate repeated normal-run stability. The branch is also one commit behind current main fcc121d58 after #6629 merged; sync after the test repair, then refresh CI/advisors/live evidence.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29126852665
Workflow ref: tmp/e2e/pr-5453-snapshot-f159b21a
Requested targets: (default — all supported)
Requested jobs: snapshot-commands,state-backup-restore,upgrade-stale-sandbox
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
snapshot-commands ✅ success
state-backup-restore ✅ success
upgrade-stale-sandbox ✅ success

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ⚠️ Run cancelled — no signal

Run: 29127491454
Workflow ref: tmp/e2e/pr-5453-snapshot-5be7602c
Requested targets: (default — all supported)
Requested jobs: snapshot-commands,state-backup-restore,upgrade-stale-sandbox
Summary: 0 passed, 0 failed, 3 cancelled, 0 skipped

Job Result
snapshot-commands ⚠️ cancelled
state-backup-restore ⚠️ cancelled
upgrade-stale-sandbox ⚠️ cancelled

@cv cv added v0.0.81 and removed v0.0.80 labels Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29127831946
Workflow ref: tmp/e2e/pr-5453-snapshot-fade9414
Requested targets: (default — all supported)
Requested jobs: snapshot-commands,state-backup-restore,upgrade-stale-sandbox
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
snapshot-commands ✅ success
state-backup-restore ✅ success
upgrade-stale-sandbox ✅ success

@prekshivyas
prekshivyas requested review from cjagwani and cv July 10, 2026 22:46

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Current-head re-review passed at fade941. The extracted snapshot modules now use deterministic injected seams instead of process-global/module-reset mocks, the destructive snapshot commands and retention/data-loss/platform limits are documented, all current CI and commits are green/Verified, both exact-head trusted advisors returned merge_as_is, and snapshot-commands/state-backup-restore/upgrade-stale-sandbox all passed live. No unresolved review threads remain.

@cv
cv dismissed cjagwani’s stale review July 11, 2026 23:22

Dismissed after current-commit re-review: the requested module extraction, deterministic injected seams, and host-state documentation are present. The focused suites passed repeated stress runs, the full plugin suite and build passed, current CI is green, both trusted advisors reported merge_as_is, all three required live jobs passed, and all review threads are resolved. Earlier security and correctness requests remain covered by fd-relative no-follow deletion and isolated Python/environment regression tests.

@cv
cv merged commit 4064501 into NVIDIA:main Jul 11, 2026
38 checks passed
@cv cv mentioned this pull request Jul 12, 2026
9 of 21 tasks
cv added a commit that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Release-prep documentation for v0.0.81 now summarizes user-facing
changes merged since v0.0.80.
It also closes the Hermes dashboard-profile backup gap and distinguishes
direct blueprint-runner actions from public host CLI commands.

## Changes

- Add the `v0.0.81` section to `docs/about/release-notes.mdx` with links
to the detailed user guides.
- Document that Hermes rebuilds preserve `.hermes/dashboard-home/`,
including Dashboard `MEMORY.md` and `USER.md`.
- Update Hermes manual backup and restore examples to transfer those two
profile files without copying generated configuration or the
secret-bearing dashboard `.env`.
- Explain the new per-item backup failure causes.
- Clarify that migration snapshot retention fragments are direct-runner
arguments and are not exposed by the host `nemoclaw` CLI.

### Source summary

- #6445 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Summarize manifest-owned
key-level restore and current-config authority.
- #6617 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Record the fail-closed
`/proc` fallback used to verify an idle Deep Agents runtime before
snapshot creation.
- #6685 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Document Hermes Web
Dashboard profile persistence and safe manual transfer.
- #6649 -> `docs/about/release-notes.mdx`: Summarize host-validated
loopback compatible-endpoint routing through the sandbox gateway.
- #6643 -> `docs/about/release-notes.mdx`: Summarize automatic
`max_completion_tokens` handling for GPT-5 and o-series models.
- #6661 -> `docs/about/release-notes.mdx`: Summarize bounded connection
reuse for eligible provider-validation probes.
- #6704 -> `docs/about/release-notes.mdx`: Record that direct blueprint
apply stops instead of persisting incomplete state after provider or
inference setup fails.
- #6677 -> `docs/about/release-notes.mdx`: Summarize transactional
recovery for legacy Docker containers whose managed supervisor
disappeared after restart.
- #6625 -> `docs/about/release-notes.mdx`: Record Hermes managed-startup
persistence across direct Docker restarts.
- #6597 -> `docs/about/release-notes.mdx`: Record final-sandbox gateway
cleanup on macOS.
- #6680 -> `docs/about/release-notes.mdx`: Summarize managed Deep Agents
first-run and process-tree cleanup improvements.
- #6647 -> `docs/about/release-notes.mdx`: Record fail-closed validation
for the managed Deep Agents fetch CA bundle.
- #6645 -> `docs/about/release-notes.mdx`: Summarize WhatsApp loopback
pairing and trusted npm plugin provenance.
- #6673 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document stopped-sandbox
backup remediation.
- #6631 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document per-item backup
failure causes.
- #6620 -> `docs/about/release-notes.mdx`: Record the
created-but-not-ready sandbox lifecycle receipt.
- #6664 -> `docs/about/release-notes.mdx`: Record prompt-aware
onboarding progress output.
- #6598 -> `docs/about/release-notes.mdx`: Summarize stale replay-result
invalidation during resumed onboarding.
- #6593 -> `docs/about/release-notes.mdx`: Summarize contextual OpenClaw
audit findings for managed dashboard compatibility settings.
- #6650 -> `docs/about/release-notes.mdx`: Record redaction of
token-shaped URL query values.
- #6638 -> `docs/about/release-notes.mdx`: Record the exact-path MCP
`DELETE` policy recipe for session termination.
- #5453 -> `docs/reference/host-files-and-state.mdx`: Clarify that
snapshot retention actions belong to direct runner integrations and are
not standalone host CLI commands.

### Skipped from docs-skip

- #6633 matched the `openclaw-sandbox-permissive.yaml` path in
`docs/.docs-skip` and produced no documentation in this update.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: This is a documentation-only
release-prep update; behavior is protected by the merged source PRs, and
the documentation build validates the changed examples and routes.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — tests are not applicable for this
documentation-only change; `npm run docs` completed successfully.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not run for this
documentation-only change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — 0
errors; two existing Fern warnings remain.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new pages.

---
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


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

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.81 covering state preservation, inference
setup, sandbox recovery, session setup, pairing, diagnostics, and
security policy updates.
- Expanded backup and restore guidance to include dashboard profile
files and clarify files that must not be copied.
- Added dashboard profile persistence details to workspace and rebuild
documentation.
- Clarified snapshot retention guidance and the distinction between host
CLI capabilities and direct runner actions.
  - Added more detailed backup failure reporting information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…agement (NVIDIA#5453)

## Summary

Adds `snapshots list`, `snapshots prune --keep <N>`, and `snapshots
delete --path <path>` subcommands to the blueprint runner, letting users
manage disk space consumed by accumulated migration snapshots under
`~/.nemoclaw/snapshots/`.

## Changes

| File | Change |
|------|--------|
| `nemoclaw/src/blueprint/snapshot.ts` | Added `deleteSnapshot()`,
`pruneSnapshots()` with symlink-attack rejection |
| `nemoclaw/src/blueprint/snapshot.test.ts` | 8 tests covering deletion,
symlink rejection, prune with keep count, empty state |
| `nemoclaw/src/blueprint/runner.ts` | Added `snapshots` action with
`list`, `prune`, `delete` subcommands and usage text |
| `nemoclaw/src/blueprint/runner.test.ts` | 12 tests for CLI routing,
list/prune/delete flows; extended fs mock with `lstatSync`,
`readlinkSync`, `rmSync` |
| `ci/test-file-size-budget.json` | Ratcheted runner.test.ts size budget
to 1622 lines |

## Usage

```bash
nemoclaw blueprint snapshots list
nemoclaw blueprint snapshots prune --keep 5
nemoclaw blueprint snapshots delete --path ~/.nemoclaw/snapshots/20260101T000000Z
```

## Testing

All 503 plugin tests pass. All hooks pass (pre-commit, commitlint). New
code adds 20 tests across two test files.

## Checklist

- [x] Conventional Commit (`feat(blueprint):`)
- [x] DCO sign-off
- [x] Tests added/updated
- [x] All tests pass
- [x] Hooks pass (pre-commit, commitlint)
- [x] Feature branch from `main`

Closes NVIDIA#5452

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

* **New Features**
* Added a top-level `snapshots` CLI action with `list`, `prune --keep
<N>`, and `delete --path <path>`.
* `list` shows snapshot metadata (or “No snapshots found.”); `prune`
validates `--keep` and reports kept/deleted/failed; `delete` safely
removes snapshots and prints `Deleted snapshot:` (including for
non-existent targets).
* **Bug Fixes**
* Tightened snapshot selection so only directories whose manifest
timestamp exactly matches are considered.
* Improved safety checks to prevent deleting outside the snapshots root
and to reject symlink targets.
* **Tests**
* Expanded unit and CLI tests for retention, validation, error
messaging, and failure reporting; added real-filesystem safety coverage
(skipped on Windows).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>

---------

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Release-prep documentation for v0.0.81 now summarizes user-facing
changes merged since v0.0.80.
It also closes the Hermes dashboard-profile backup gap and distinguishes
direct blueprint-runner actions from public host CLI commands.

## Changes

- Add the `v0.0.81` section to `docs/about/release-notes.mdx` with links
to the detailed user guides.
- Document that Hermes rebuilds preserve `.hermes/dashboard-home/`,
including Dashboard `MEMORY.md` and `USER.md`.
- Update Hermes manual backup and restore examples to transfer those two
profile files without copying generated configuration or the
secret-bearing dashboard `.env`.
- Explain the new per-item backup failure causes.
- Clarify that migration snapshot retention fragments are direct-runner
arguments and are not exposed by the host `nemoclaw` CLI.

### Source summary

- NVIDIA#6445 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Summarize manifest-owned
key-level restore and current-config authority.
- NVIDIA#6617 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Record the fail-closed
`/proc` fallback used to verify an idle Deep Agents runtime before
snapshot creation.
- NVIDIA#6685 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Document Hermes Web
Dashboard profile persistence and safe manual transfer.
- NVIDIA#6649 -> `docs/about/release-notes.mdx`: Summarize host-validated
loopback compatible-endpoint routing through the sandbox gateway.
- NVIDIA#6643 -> `docs/about/release-notes.mdx`: Summarize automatic
`max_completion_tokens` handling for GPT-5 and o-series models.
- NVIDIA#6661 -> `docs/about/release-notes.mdx`: Summarize bounded connection
reuse for eligible provider-validation probes.
- NVIDIA#6704 -> `docs/about/release-notes.mdx`: Record that direct blueprint
apply stops instead of persisting incomplete state after provider or
inference setup fails.
- NVIDIA#6677 -> `docs/about/release-notes.mdx`: Summarize transactional
recovery for legacy Docker containers whose managed supervisor
disappeared after restart.
- NVIDIA#6625 -> `docs/about/release-notes.mdx`: Record Hermes managed-startup
persistence across direct Docker restarts.
- NVIDIA#6597 -> `docs/about/release-notes.mdx`: Record final-sandbox gateway
cleanup on macOS.
- NVIDIA#6680 -> `docs/about/release-notes.mdx`: Summarize managed Deep Agents
first-run and process-tree cleanup improvements.
- NVIDIA#6647 -> `docs/about/release-notes.mdx`: Record fail-closed validation
for the managed Deep Agents fetch CA bundle.
- NVIDIA#6645 -> `docs/about/release-notes.mdx`: Summarize WhatsApp loopback
pairing and trusted npm plugin provenance.
- NVIDIA#6673 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document stopped-sandbox
backup remediation.
- NVIDIA#6631 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document per-item backup
failure causes.
- NVIDIA#6620 -> `docs/about/release-notes.mdx`: Record the
created-but-not-ready sandbox lifecycle receipt.
- NVIDIA#6664 -> `docs/about/release-notes.mdx`: Record prompt-aware
onboarding progress output.
- NVIDIA#6598 -> `docs/about/release-notes.mdx`: Summarize stale replay-result
invalidation during resumed onboarding.
- NVIDIA#6593 -> `docs/about/release-notes.mdx`: Summarize contextual OpenClaw
audit findings for managed dashboard compatibility settings.
- NVIDIA#6650 -> `docs/about/release-notes.mdx`: Record redaction of
token-shaped URL query values.
- NVIDIA#6638 -> `docs/about/release-notes.mdx`: Record the exact-path MCP
`DELETE` policy recipe for session termination.
- NVIDIA#5453 -> `docs/reference/host-files-and-state.mdx`: Clarify that
snapshot retention actions belong to direct runner integrations and are
not standalone host CLI commands.

### Skipped from docs-skip

- NVIDIA#6633 matched the `openclaw-sandbox-permissive.yaml` path in
`docs/.docs-skip` and produced no documentation in this update.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: This is a documentation-only
release-prep update; behavior is protected by the merged source PRs, and
the documentation build validates the changed examples and routes.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — tests are not applicable for this
documentation-only change; `npm run docs` completed successfully.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not run for this
documentation-only change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — 0
errors; two existing Fern warnings remain.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new pages.

---
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


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

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.81 covering state preservation, inference
setup, sandbox recovery, session setup, pairing, diagnostics, and
security policy updates.
- Expanded backup and restore guidance to include dashboard profile
files and clarify files that must not be copied.
- Added dashboard profile persistence details to workspace and rebuild
documentation.
- Clarified snapshot retention guidance and the distinction between host
CLI capabilities and direct runner actions.
  - Added more detailed backup failure reporting information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
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 feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(blueprint): add snapshot prune/delete commands for retention management

5 participants