Skip to content

fix(status): show gateway active policy version, not the schema constant#3185

Merged
cv merged 4 commits into
mainfrom
fix/issue-1961-policy-active-version-in-status
May 8, 2026
Merged

fix(status): show gateway active policy version, not the schema constant#3185
cv merged 4 commits into
mainfrom
fix/issue-1961-policy-active-version-in-status

Conversation

@laitingsheng

@laitingsheng laitingsheng commented May 7, 2026

Copy link
Copy Markdown
Contributor

Summary

nemoclaw <sandbox> status rendered the merged policy YAML's schema version: 1 even after onboarding had advanced the gateway active version to 6, leaving users uncertain whether their preset selections actually took effect.

Related Issue

Closes #1961

Changes

  • src/lib/actions/sandbox/gateway-state.ts: capture the Active: N line emitted by openshell policy get --full (the metadata block above ---) and rewrite the leading version: in the YAML payload to that value before display.
  • test/gateway-state.test.ts: cover the rewrite, the no-Active: fallback (YAML left untouched), and the error-output case (original output preserved).

Type of Change

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

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

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

Summary by CodeRabbit

  • Bug Fixes

    • Sandbox output now synchronizes its YAML "version" with the live policy "Active" value when present; handles and strips ANSI escape sequences and preserves prior behavior for missing, error-like, or non-YAML live policy content.
  • Tests

    • Added tests for version sync, ANSI-wrapped metadata handling, absent/unusable metadata, and error-string live policy cases.

`nemoclaw <sandbox> status` rendered the merged policy YAML's schema
`version: 1` even after onboarding had advanced the gateway active
version to 6, leaving users uncertain whether their preset selections
took effect. Capture the `Active: N` line emitted by
`openshell policy get --full` and rewrite the leading `version:` in
the displayed YAML to match.

Closes #1961

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

coderabbitai Bot commented May 7, 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: 9e9ce502-74b3-48be-8480-89201e4151b2

📥 Commits

Reviewing files that changed from the base of the PR and between 8f07ef9 and 5891817.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/gateway-state.ts
  • test/gateway-state.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/actions/sandbox/gateway-state.ts

📝 Walkthrough

Walkthrough

mergeLivePolicyIntoSandboxOutput now ANSI-strips live policy output, splits metadata from the YAML document, parses an Active: N value from metadata, and replaces sandbox YAML's version: M with that Active number when present; tests exercising normal and ANSI-wrapped cases were added.

Changes

Policy Version Fix

Layer / File(s) Summary
Metadata Extraction
src/lib/actions/sandbox/gateway-state.ts
Strip ANSI from livePolicyOutput, split at the first --- delimiter to produce metadataPart (before ---) and yamlPart (from ---) and validate YAML body for early-return.
Active Version Parse & Rewriting
src/lib/actions/sandbox/gateway-state.ts
Extract Active: <digits> from metadataPart and, if sandbox YAML contains version: <digits>, replace that version value with the parsed active number while preserving indentation.
Indentation & Reassembly
src/lib/actions/sandbox/gateway-state.ts
Keep existing indentation of rewritten YAML and reassemble the updated YAML back into the sandbox output; preserve prior early-return behavior.
Test Import
test/gateway-state.test.ts
Import mergeLivePolicyIntoSandboxOutput from dist/lib/actions/sandbox/gateway-state.js.
Test Suite
test/gateway-state.test.ts
Add tests: rewrite version to Active, no rewrite when Active absent, unchanged output when livePolicy is an error string, and correct handling when separator/metadata lines include ANSI escapes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I split the YAML where the dashes play,
I stripped the colors the terminals spray.
I found the Active number, snug and true,
I hopped in the sandbox and updated the view.
Now versions align — a tidy hop through!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating status display to show the gateway active policy version instead of the static schema version constant.
Linked Issues check ✅ Passed The PR fully implements the primary coding requirement from issue #1961: extracting the Active policy version from gateway output and rewriting the YAML version field to reflect the active version.
Out of Scope Changes check ✅ Passed All changes are directly scoped to addressing issue #1961: parsing live policy output for Active version, rewriting YAML version field, and adding comprehensive 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/issue-1961-policy-active-version-in-status

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

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/actions/sandbox/gateway-state.ts (1)

58-74: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

ANSI-sensitive delimiter parsing can bypass the version rewrite path.

On Line 58, delimiter detection uses raw livePolicyOutput, but Line 70 parses metadata from ANSI-stripped text. If --- is colorized, delimIdx becomes -1, metadata is treated as YAML, and version won’t be rewritten.

Suggested fix
 export function mergeLivePolicyIntoSandboxOutput(
   output: string,
   livePolicyOutput: string,
 ): string {
@@
-  const delimIdx = livePolicyOutput.search(/^---\s*$/m);
-  const metadataPart = delimIdx !== -1 ? livePolicyOutput.slice(0, delimIdx) : "";
+  const cleanLivePolicy = stripAnsi(String(livePolicyOutput));
+  const delimIdx = cleanLivePolicy.search(/^---\s*$/m);
+  const metadataPart = delimIdx !== -1 ? cleanLivePolicy.slice(0, delimIdx) : "";
   const yamlPart =
     delimIdx !== -1
-      ? livePolicyOutput.slice(delimIdx).replace(/^---\s*[\r\n]+/, "")
-      : livePolicyOutput;
+      ? cleanLivePolicy.slice(delimIdx).replace(/^---\s*[\r\n]+/, "")
+      : cleanLivePolicy;
@@
-  const activeMatch = stripAnsi(metadataPart).match(/^Active:\s*(\d+)\s*$/m);
+  const activeMatch = metadataPart.match(/^Active:\s*(\d+)\s*$/m);
🤖 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/sandbox/gateway-state.ts` around lines 58 - 74, Determine the
delimiter using an ANSI-stripped version of livePolicyOutput so color codes
don't hide the `---` marker: call stripAnsi(livePolicyOutput) first, search for
the delimiter on that stripped string to compute delimIdx, then derive
metadataPart and yamlPart from the stripped text (instead of raw
livePolicyOutput) before running the existing checks and version rewrite logic
(references: livePolicyOutput, stripAnsi, delimIdx, metadataPart, yamlPart,
activeMatch, rewrittenYaml).
🧹 Nitpick comments (1)
test/gateway-state.test.ts (1)

250-283: ⚡ Quick win

Add one ANSI-wrapped metadata test to lock this parser path.

These tests cover core behavior well, but they currently miss Active/--- lines with ANSI escapes. Adding that case would prevent regressions in colored CLI output.

Suggested test addition
 describe("mergeLivePolicyIntoSandboxOutput (`#1961`)", () => {
@@
   it("returns the original output when livePolicy is an error string", () => {
     const merged = mergeLivePolicyIntoSandboxOutput(sandboxOutput, "Error: not found");
     expect(merged).toBe(sandboxOutput);
   });
+
+  it("rewrites version when metadata and separator are ANSI-wrapped", () => {
+    const livePolicy = [
+      "\x1b[1mVersion:\x1b[0m      6",
+      "\x1b[1mActive:\x1b[0m       6",
+      "\x1b[36m---\x1b[0m",
+      "version: 1",
+      "filesystem_policy:",
+      "  include_workdir: false",
+    ].join("\n");
+
+    const merged = mergeLivePolicyIntoSandboxOutput(sandboxOutput, livePolicy);
+    expect(merged).toContain("  version: 6");
+    expect(merged).not.toContain("  version: 1");
+  });
 });
🤖 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 `@test/gateway-state.test.ts` around lines 250 - 283, Add a test in
test/gateway-state.test.ts for mergeLivePolicyIntoSandboxOutput that covers
ANSI-escaped metadata lines: create a livePolicy string where the "Active:"
metadata and the YAML document separator ("---") are wrapped with ANSI escape
sequences (e.g., CSI codes) and assert that the merged output still rewrites the
YAML "version" to the active value (e.g., expects "  version: 6" and not " 
version: 1"); also include a negative case (e.g., when only ANSI-wrapped
metadata is present but no Active value) to ensure the function correctly leaves
YAML untouched. Ensure the new test references mergeLivePolicyIntoSandboxOutput
so it exercises the ANSI-path of the parser.
🤖 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.

Outside diff comments:
In `@src/lib/actions/sandbox/gateway-state.ts`:
- Around line 58-74: Determine the delimiter using an ANSI-stripped version of
livePolicyOutput so color codes don't hide the `---` marker: call
stripAnsi(livePolicyOutput) first, search for the delimiter on that stripped
string to compute delimIdx, then derive metadataPart and yamlPart from the
stripped text (instead of raw livePolicyOutput) before running the existing
checks and version rewrite logic (references: livePolicyOutput, stripAnsi,
delimIdx, metadataPart, yamlPart, activeMatch, rewrittenYaml).

---

Nitpick comments:
In `@test/gateway-state.test.ts`:
- Around line 250-283: Add a test in test/gateway-state.test.ts for
mergeLivePolicyIntoSandboxOutput that covers ANSI-escaped metadata lines: create
a livePolicy string where the "Active:" metadata and the YAML document separator
("---") are wrapped with ANSI escape sequences (e.g., CSI codes) and assert that
the merged output still rewrites the YAML "version" to the active value (e.g.,
expects "  version: 6" and not "  version: 1"); also include a negative case
(e.g., when only ANSI-wrapped metadata is present but no Active value) to ensure
the function correctly leaves YAML untouched. Ensure the new test references
mergeLivePolicyIntoSandboxOutput so it exercises the ANSI-path of the parser.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 676816c4-d313-4b24-8aec-72118c1049d0

📥 Commits

Reviewing files that changed from the base of the PR and between 2c3a392 and aae7d15.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/gateway-state.ts
  • test/gateway-state.test.ts

@wscurran

wscurran commented May 7, 2026

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this PR that fixes the policy version mismatch in nemoclaw <sandbox> status. This change involves capturing the active policy version from openshell policy get --full and rewriting the YAML payload to display the correct version.


Related open issues:

…-active-version-in-status

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

# Conflicts:
#	test/gateway-state.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/gateway-state.test.ts`:
- Around line 295-309: The test must ensure Active is used rather than Version:
change the livePolicy fixture so the "Version:" and "Active:" lines have
different numbers (e.g., "Version:      5" and "Active:       6") and update
assertions to expect "  version: 6" and to not contain "  version: 5"; this
targets the mergeLivePolicyIntoSandboxOutput behavior using the livePolicy and
sandboxOutput variables so failures indicate the function is reading Active
rather than Version.
🪄 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: 33e76a48-b6a1-4048-8b2d-a91bb6923014

📥 Commits

Reviewing files that changed from the base of the PR and between aae7d15 and 8f07ef9.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/gateway-state.ts
  • test/gateway-state.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/actions/sandbox/gateway-state.ts

Comment thread test/gateway-state.test.ts
…data

When 'openshell policy get --full' emits ANSI-coloured output, the raw
'---' delimiter search failed and the metadata path was treated as
YAML, skipping the version rewrite. Strip ANSI on the full input so
delimiter detection, metadata parsing and YAML extraction all see the
same plain-text view.

Also use distinct values for Version: and Active: in the regression
test so it actually distinguishes which line is read, and add an
ANSI-wrapped test case to lock in the colour-aware path.

Per #3185 review feedback.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@cv cv added v0.0.38 and removed v0.0.37 labels May 8, 2026
@cv cv merged commit b1320d5 into main May 8, 2026
16 checks passed
miyoungc added a commit that referenced this pull request May 9, 2026
## Summary
- Bump the docs release metadata to `0.0.38`.
- Document release-prep updates for status policy versions, Local Ollama
validation and cleanup, blueprint policy additions, rebuild backup
handling, and NemoHermes uninstall branding.
- Refresh generated `nemoclaw-user-*` skills from the updated docs.

## Source summary
- #3185 -> `docs/reference/commands.md`: Documents that `nemoclaw <name>
status` displays the gateway active policy version when OpenShell
reports one.
- #3167 -> `docs/reference/commands.md`,
`docs/inference/use-local-inference.md`: Documents uninstall cleanup for
matching Local Ollama auth proxy processes.
- #2737 -> `docs/inference/use-local-inference.md`,
`docs/network-policy/customize-network-policy.md`,
`docs/manage-sandboxes/lifecycle.md`, `docs/reference/commands.md`:
Documents stricter Local Ollama tool-call validation, blueprint policy
additions, and partial rebuild backup handling.
- #3220 -> `docs/reference/commands.md`: Documents NemoHermes-specific
uninstall progress and completion text.
- #3158 -> `.agents/skills/nemoclaw-user-configure-inference/*`:
Refreshes generated user skills from existing
`docs/inference/switch-inference-providers.md` heartbeat documentation.
- #3199 -> `.agents/skills/nemoclaw-user-get-started/SKILL.md`:
Refreshes generated user skills from existing
`docs/get-started/quickstart.md` Model Router wording.

## Skipped
- #3272 and #3268 were already documented by their merged docs updates
on `main`.
- #3154, #3216, #3166, and #3195 have no additional user-facing docs
impact for this release-prep pass.
- No commits matched `docs/.docs-skip`.

## Test plan
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user`
- `make docs`
- `npm run build:cli`
- Commit and pre-push hooks: markdownlint, docs-to-skills verification,
gitleaks, commitlint, skills YAML tests, CLI typecheck


Made with [Cursor](https://cursor.com)

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

## Summary by CodeRabbit

* **Behavior Changes**
* Rebuild now safely handles partial backups, preserving successfully
captured entries while reporting only unarchived paths
* Uninstall for Local Ollama setups now stops proxy processes before
cleanup
* Local Ollama models require stricter tool-call response validation
during onboarding
* Blueprint policy additions enable custom network policy extensions via
`components.policy.additions`
* New `NEMOCLAW_AGENT_HEARTBEAT_EVERY` configuration controls agent
periodic task frequency
  * Status display now shows active policy version when available

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

Co-authored-by: Cursor <cursoragent@cursor.com>
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output 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 bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platform]Policy version mismatch in nemoclaw status

3 participants