Skip to content

feat(policy): add sandbox policy get command for clean YAML output#6122

Open
kagura-agent wants to merge 2 commits into
NVIDIA:mainfrom
kagura-agent:fix/policy-get-clean-yaml
Open

feat(policy): add sandbox policy get command for clean YAML output#6122
kagura-agent wants to merge 2 commits into
NVIDIA:mainfrom
kagura-agent:fix/policy-get-clean-yaml

Conversation

@kagura-agent

@kagura-agent kagura-agent commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new nemoclaw sandbox policy get CLI command that retrieves the active sandbox policy and outputs clean YAML suitable for piping to policy set.

Closes #6052

Problem

openshell policy get --full includes metadata header lines (Version, Hash, Status, Active, Created, Loaded) before the actual YAML. When this output is piped to a file and fed back to openshell policy set --policy, it fails with a YAML parse error because policy set cannot recognize the metadata fields. The get/set round-trip is broken.

Solution

Added nemoclaw sandbox policy get <sandbox> which wraps openshell policy get --full and uses the existing parseCurrentPolicy() function (from src/lib/policy/index.ts) to strip the metadata header, outputting only usable YAML.

A --raw flag is available to get the unmodified openshell output with metadata when needed.

Usage

# Get clean YAML (round-trip safe)
nemoclaw sandbox policy get my-assistant > policy.yaml
nemoclaw sandbox policy set --policy policy.yaml my-assistant  # works!

# Get raw output with metadata (for debugging)
nemoclaw sandbox policy get my-assistant --raw

Changes

  • src/commands/sandbox/policy/get.ts — new oclif command (sandbox:policy:get)
  • src/commands/sandbox/policy/get.test.ts — 4 unit tests (default parse, --raw bypass, error paths)

Testing

  • 4 unit tests pass (npx vitest run src/commands/sandbox/policy/get.test.ts)
  • Biome lint clean
  • No interface changes (new files only)

Summary by CodeRabbit

  • New Features
    • Added a new sandbox:policy:get command to display the active policy for a specified sandbox.
    • Includes an optional --raw mode to show the unprocessed policy output.
  • Bug Fixes
    • Improved failure handling when the policy can’t be retrieved or when the policy content can’t be parsed.
  • Tests
    • Added tests covering normal output, --raw output, and error scenarios for both retrieval and parsing.

…VIDIA#6052)

The openshell policy get --full output includes a metadata header that
cannot be piped directly to policy set. This adds a CLI command that
strips the header via parseCurrentPolicy and outputs only usable YAML.
A --raw flag preserves the original openshell output when needed.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 1, 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 Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: b1740378-5ec4-4f98-9317-7572ce40137a

📥 Commits

Reviewing files that changed from the base of the PR and between 6956c71 and b5d9872.

📒 Files selected for processing (4)
  • src/commands/sandbox/policy/get.test.ts
  • src/commands/sandbox/policy/get.ts
  • src/lib/actions/sandbox/policy-get.test.ts
  • src/lib/actions/sandbox/policy-get.ts

📝 Walkthrough

Walkthrough

Adds a new sandbox:policy:get command and supporting policy retrieval action. The command can print either raw OpenShell output or parsed YAML, and the new tests cover success and failure paths for both the action and command.

Changes

Sandbox Policy Get Command

Layer / File(s) Summary
Policy retrieval action
src/lib/actions/sandbox/policy-get.ts
Defines PolicyGetResult and getSandboxPolicy(), which resolves OpenShell, captures openshell policy get --full, and returns raw output plus parsed YAML when available.
Command definition and run logic
src/commands/sandbox/policy/get.ts
Adds SandboxPolicyGetCommand with CLI metadata, required sandbox name input, optional --raw flag, and run logic that logs raw output or parsed YAML and errors on missing data.
Test coverage
src/commands/sandbox/policy/get.test.ts, src/lib/actions/sandbox/policy-get.test.ts
Adds Vitest coverage for command output/error behavior and for action behavior across successful capture, empty output, and parse failure cases.

Estimated code review effort: 2 (Simple) | ~12 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SandboxPolicyGetCommand
  participant getSandboxPolicy
  participant runCapture
  participant parseCurrentPolicy

  User->>SandboxPolicyGetCommand: sandbox:policy:get <name> [--raw]
  SandboxPolicyGetCommand->>getSandboxPolicy: retrieve policy data
  getSandboxPolicy->>runCapture: openshell policy get --full <name>
  runCapture-->>getSandboxPolicy: raw output
  getSandboxPolicy->>parseCurrentPolicy: parse when raw output exists
  parseCurrentPolicy-->>getSandboxPolicy: yaml
  getSandboxPolicy-->>SandboxPolicyGetCommand: { raw, yaml }
  alt --raw set
    SandboxPolicyGetCommand->>User: log raw output
  else
    SandboxPolicyGetCommand->>User: log yaml
  end
Loading

Suggested labels: area: cli, area: policy, feature

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: a new sandbox policy get command that outputs clean YAML.
Linked Issues check ✅ Passed [#6052] The command strips metadata for clean YAML and preserves --raw output, matching the requested round-trip fix.
Out of Scope Changes check ✅ Passed The changes stay focused on the policy-get command, its action, and tests, with no unrelated functionality added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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

🧹 Nitpick comments (1)
src/commands/sandbox/policy/get.test.ts (1)

29-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Tests assert mock calls instead of observable output.

Both the default-parsing test and the --raw test verify only that internal helpers were invoked with certain args, never that the command actually logs the expected YAML/raw content. This locks tests to implementation details rather than the command's public behavior (what a user sees on stdout), and would mask a behavioral regression while still passing.

As per path instructions, tests should "Prefer observable outcomes through the public boundary over source-text, private-shape, or mock-call assertions."

✅ Suggested addition: assert on logged output
+  it("invokes openshell and parses policy by default", async () => {
     const rawOutput =
       "Version: 1\nHash: abc\nStatus: active\n---\nversion: 1\nnetwork_policies: []";
     mocks.runCapture.mockReturnValue(rawOutput);
     mocks.parseCurrentPolicy.mockReturnValue("version: 1\nnetwork_policies: []");

+    const logSpy = vi.spyOn(SandboxPolicyGetCommand.prototype, "log");
     await SandboxPolicyGetCommand.run(["alpha"], rootDir);

     expect(mocks.assertOpenshellResolvable).toHaveBeenCalled();
     expect(mocks.buildPolicyGetCommand).toHaveBeenCalledWith("alpha");
     expect(mocks.runCapture).toHaveBeenCalledWith([...]);
     expect(mocks.parseCurrentPolicy).toHaveBeenCalledWith(rawOutput);
+    expect(logSpy).toHaveBeenCalledWith("version: 1\nnetwork_policies: []");
   });
🤖 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/commands/sandbox/policy/get.test.ts` around lines 29 - 58, The
SandboxPolicyGetCommand tests are only checking internal helper calls instead of
the command’s observable output. Update the tests around
SandboxPolicyGetCommand.run to assert the stdout/logged result for both the
default parsed YAML path and the --raw path, using the mocked runCapture output
as the public boundary. Keep the helper setup assertions only if needed for
setup, but make the primary expectation the actual emitted content so the tests
validate user-visible behavior rather than implementation details.

Source: Path instructions

🤖 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/commands/sandbox/policy/get.ts`:
- Around line 36-58: Move the orchestration out of SandboxPolicyGetCommand.run()
and into a sandbox action under src/lib/actions/sandbox, since run() is
currently doing precondition checks, executing OpenShell, and handling parse
branches. Extract the policy retrieval and parsing flow
(assertOpenshellResolvable, buildPolicyGetCommand, runCapture,
parseCurrentPolicy) into a typed action such as getSandboxPolicy, then keep the
command as thin argv/flag parsing plus translating the action result into
this.log/this.error. Preserve the raw/raw-flag and YAML parsing behavior in the
action’s returned result so the command no longer owns product logic.

---

Nitpick comments:
In `@src/commands/sandbox/policy/get.test.ts`:
- Around line 29-58: The SandboxPolicyGetCommand tests are only checking
internal helper calls instead of the command’s observable output. Update the
tests around SandboxPolicyGetCommand.run to assert the stdout/logged result for
both the default parsed YAML path and the --raw path, using the mocked
runCapture output as the public boundary. Keep the helper setup assertions only
if needed for setup, but make the primary expectation the actual emitted content
so the tests validate user-visible behavior rather than implementation details.
🪄 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: ece117d6-bea0-4744-adfe-63a0598ad246

📥 Commits

Reviewing files that changed from the base of the PR and between 9df364c and 6956c71.

📒 Files selected for processing (2)
  • src/commands/sandbox/policy/get.test.ts
  • src/commands/sandbox/policy/get.ts

Comment thread src/commands/sandbox/policy/get.ts
Address CodeRabbit review:
- Extract orchestration into src/lib/actions/sandbox/policy-get.ts
  per single-path oclif architecture (command = argv glue, action = logic)
- Tests now assert on logged output (observable behavior)
- Add dedicated unit tests for the action layer
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: policy Network policy, egress rules, presets, or sandbox policy area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery feature PR adds or expands user-visible functionality labels Jul 1, 2026
@wscurran

wscurran commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

✨ Thanks for the fix. Adding a new nemoclaw sandbox policy get command for clean YAML output solves the get/set round-trip issue cleanly.


Related open issues:

@kagura-agent

Copy link
Copy Markdown
Contributor Author

Thanks @wscurran! Happy to hear the approach works well. Let me know if you'd like any changes — happy to iterate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: policy Network policy, egress rules, presets, or sandbox policy area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS][Policy&Network] openshell policy get --full output cannot be used directly with policy set — metadata header causes YAML parse failure

2 participants