Skip to content

fix(policy): refuse to apply a preset when the live policy could not be read#4589

Open
latenighthackathon wants to merge 3 commits into
NVIDIA:mainfrom
latenighthackathon:fix/4586-policy-degraded-read-guard
Open

fix(policy): refuse to apply a preset when the live policy could not be read#4589
latenighthackathon wants to merge 3 commits into
NVIDIA:mainfrom
latenighthackathon:fix/4586-policy-degraded-read-guard

Conversation

@latenighthackathon
Copy link
Copy Markdown
Contributor

@latenighthackathon latenighthackathon commented May 31, 2026

Summary

When policy get succeeds but returns output NemoClaw cannot parse (an error or status line, or otherwise unexpected content), policy-add and the onboard preset apply rebuild the policy from only the preset being applied and write that back, silently dropping every other preset already in place along with the filesystem and process rules. A full gateway outage is safe, since the follow-up policy set also fails and nothing is written; the damage happens when the gateway is healthy enough to accept the write but returned a degraded read. The matching remove command already refuses to act on a policy it could not read; the apply paths did not.

Related Issue

Fixes #4586

Changes

  • applyPresetContent and applyPresets now stop and report when the live policy read comes back non-empty but unparseable, instead of overwriting it. A genuinely empty read, which is the normal case for a fresh sandbox with no policy yet, still applies the first preset as before. This matches the guard the remove path already had.
  • Added regression tests in test/policies.test.ts for the degraded-read abort (both functions) and the fresh-sandbox happy path.

Type of Change

  • Code change (feature, bug fix, or refactor)

Verification

  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed

Ran npm run build:cli, npm run typecheck:cli, npx @biomejs/biome lint, and the full policies suite (154/154). The new tests fail before the change and pass after.

Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com

Summary by CodeRabbit

  • Bug Fixes

    • Preset application operations now safely abort when unable to validate the current sandbox policy state, preventing accidental overwriting of existing policies during error conditions.
  • Tests

    • Added regression tests verifying preset application behavior when sandbox policy state cannot be validated.

…be read

applyPresetContent and applyPresets fetch the live policy with
runCapture(..., { ignoreError: true }) and pass it through
parseCurrentPolicy, which returns "" both for a genuinely empty policy and
for exit-0-but-degraded output (an error/warning/status body, a non-object
top level, or unparseable YAML). On a degraded read mergePresetIntoPolicy
rebuilt the policy from only the new preset and policy set overwrote the
live policy, dropping every other preset and every non-network section.
The remove path already guards this; the apply paths did not.

Abort the apply when rawPolicy is non-empty but parseCurrentPolicy returns
empty (a degraded read), while still letting a genuinely empty read build
from the scaffold (fresh sandbox). This mirrors the existing remove-path
guard.

Fixes NVIDIA#4586

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 31, 2026

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
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 31, 2026

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: b883d7c9-0e27-490d-96a4-6e8dcaf05eea

📥 Commits

Reviewing files that changed from the base of the PR and between 17ace9e and 1ad657e.

📒 Files selected for processing (1)
  • src/lib/policy/index.ts
💤 Files with no reviewable changes (1)
  • src/lib/policy/index.ts

📝 Walkthrough

Walkthrough

applyPresetContent and applyPresets now detect when a captured policy read is non-empty but fails parsing and abort the apply (log an error and return false) instead of overwriting the sandbox policy. Regression tests for issue #4586 cover degraded and empty read cases.

Changes

Policy Safety Guard for Preset Application

Layer / File(s) Summary
Add validation guards to preset application functions
src/lib/policy/index.ts
applyPresetContent and applyPresets now check runCapture output and parseCurrentPolicy; if the raw output is non-empty but parsing yields an empty/invalid policy, they log an error and return false without applying presets.
Regression tests for issue #4586
test/policies.test.ts
New tests with a mocked OpenShell binary and stubbed registry functions verify that degraded policy get output causes applyPresetContent and applyPresets to return false (and log unreadable-policy error), while genuinely empty reads allow applying presets (true and "Applied preset" log).

Sequence Diagram(s)

sequenceDiagram
  participant applyPreset as applyPresetContent/applyPresets
  participant OpenShell as OpenShell (runCapture / `policy get`)
  participant Parser as parseCurrentPolicy
  participant Registry as registry.addCustomPolicy / policy set

  applyPreset->>OpenShell: runCapture("policy get") -> rawOutput
  OpenShell-->>applyPreset: rawOutput
  applyPreset->>Parser: parseCurrentPolicy(rawOutput)
  Parser-->>applyPreset: parsedPolicy (empty when unreadable)
  alt parsedPolicy non-empty
    applyPreset->>Registry: merge & policy set (apply preset)
    Registry-->>applyPreset: success
  else parsedPolicy empty but rawOutput non-empty
    applyPreset-->>applyPreset: log error "could not read current policy"
    applyPreset-->>Registry: abort (return false)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#4577: Both PRs touch the preset-application pipeline in src/lib/policy/index.ts and how applyPresetContent/applyPresets behave when policy get output can’t be parsed.

Suggested labels

fix, enhancement: policy

Suggested reviewers

  • cv

Poem

🐰 A rabbit found a sandbox frail,
Where garbled lines might cause a fail,
So checks were placed to guard the night—
No lost presets, no silent blight.
sniff-sniff 🌿

🚥 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 accurately and clearly summarizes the main change: refusing to apply presets when live policy cannot be read, which directly addresses the core problem described in the PR objectives.
Linked Issues check ✅ Passed The changes fully satisfy all coding requirements from issue #4586: detecting degraded reads by checking non-empty rawPolicy with empty parseCurrentPolicy result, aborting apply to prevent policy overwrite, and preserving fresh sandbox behavior [#4586].
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #4586: the logic change in src/lib/policy/index.ts and regression tests in test/policies.test.ts target only the stated policy degraded-read issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

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

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

@wscurran
Copy link
Copy Markdown
Contributor

wscurran commented Jun 1, 2026

✨ Thanks for submitting this detailed PR about refusing to apply a preset when the live policy could not be read. This proposes a fix for a bug in the NemoClaw CLI that prevents silent overwriting of existing presets and policy rules.


Related open issues:

@wscurran wscurran added the v0.0.58 Release target label Jun 2, 2026
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: policy Network policy, egress rules, presets, or sandbox policy bug-fix PR fixes a bug or regression feature PR adds or expands user-visible functionality and removed NemoClaw CLI labels Jun 3, 2026
Copy link
Copy Markdown
Contributor

@prekshivyas prekshivyas left a comment

Choose a reason for hiding this comment

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

LGTM — mirrors the existing remove-path guard in applyPresetContent / applyPresets, narrow scope, and the new regression tests cover both apply functions plus the fresh-sandbox happy path. CI green on 1ad657e, no CodeRabbit threads.

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

Labels

area: cli Command line interface, flags, terminal UX, or output area: policy Network policy, egress rules, presets, or sandbox policy bug-fix PR fixes a bug or regression feature PR adds or expands user-visible functionality v0.0.58 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

policy-add and onboard preset apply overwrite the live policy when policy get returns degraded exit-0 output

3 participants