Skip to content

chore(hermes): upgrade Hermes Agent to v2026.7.20 - #7771

Merged
jyaunches merged 8 commits into
mainfrom
dep/hermes-v2026.7.20
Jul 29, 2026
Merged

chore(hermes): upgrade Hermes Agent to v2026.7.20#7771
jyaunches merged 8 commits into
mainfrom
dep/hermes-v2026.7.20

Conversation

@ericksoa

@ericksoa ericksoa commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Upgrade the Hermes sandbox from v2026.7.1 / 0.18.0 to the published stable v2026.7.20 / 0.19.0 release with immutable source and package identity pins. Preserve NemoClaw's authorization, browser-evaluation, session-retention, output-disclosure, wrapper, and durable-state contracts across Hermes 0.19, and add a reusable Hermes-upgrade skill plus the audited dependency/security record.

Target landing is Friday, July 31, 2026. Opening this PR does not authorize an earlier merge.

Changes

  • Pin the verified v2026.7.20 annotated release (3ef6bbd201263d354fd83ec55b3c306ded2eb72a) and 0.19.0 package identity, including source archive, npm, and PyPI artifact identities. The audit covers v2026.7.1 -> v2026.7.7 -> v2026.7.7.2 -> v2026.7.20 (2,399 commits), including the four-component CalVer release.
  • Emit Hermes schema 33 and explicitly preserve NemoClaw's prior security/privacy semantics: manual approvals, restricted browser evaluation, bounded daily/idle session reset, hidden reasoning/commentary, and no dependency-owned in-place backup or CUA refresh. Exact-source fallbacks protect config-less named profiles. The dashboard policy mirror validates both source and destination before either write, fails closed with secret-free diagnostics, and preserves stale bytes on invalid input.
  • Update the wrapper for Hermes 0.19 flags and console, preserve global profile selectors plus bare, named, and unquoted multi-word continue/resume forms, and reject resumed one-shot --usage-file instead of silently discarding its report. Focused tests bind the target parser/coalescer boundaries, and the final image compares the wrapper's private session-name boundary AST with the exact installed upstream coalescer.
  • Retarget and integrity-bind the gateway-runtime-metadata, session-preview, Langfuse-placeholder, managed-light-skin, provider-routing, and resumed-one-shot workarounds that remain required against the target source. The gateway repair preserves Hermes 0.19's process-scoped home selector while relocating the central managed default-gateway PID, lock, and status helpers below the writable runtime directory. Direct upstream replacement/stop, marker, profile/multiplexer, and service/boot consumers remain the documented inherited Medium residual.
  • Online-back up the new default-profile cron and Discord SQLite ledgers. Preserve both cross-UID gateway/sandbox recovery contracts with setgid parents, secure startup repair, exact upstream mode patching where needed, and real image probes. Named-profile ledgers remain the documented Medium residual inside the existing raw profiles capture.
  • Replace the upstream python-multipart==0.0.27 resolution with attested, hash-pinned 0.0.32, clearing its three advisories. The selected target graph introduces no advisory or license regression; reachable pre-existing Pillow and Starlette findings remain explicit baseline debt for security disposition.
  • Add nemoclaw-contributor-update-hermes, its CalVer release supplement, contract map, regression tests, and the Hermes 0.19 dependency review so future upgrades repeat the release, configuration, wrapper, state, image-publication, and exact-head runtime checks.
  • Publish the exact source-pin commit as linux/amd64 and linux/arm64 images in trusted workflow run 30411365314, then pin the verified OCI index: ghcr.io/nvidia/nemoclaw/hermes-sandbox-base@sha256:c4aee5c9b087840da6e1eb2127fef9f4a2eab0862992008d1741dc09f632422e.

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)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • 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: exact-head differential security review PASS with the inherited HERMES-21 residual scoped; prior full-review residual dispositions are unchanged.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: Exact-head PR diff and body re-reviewed. .agents/skills/nemoclaw-contributor-update-hermes/SKILL.md, .agents/skills/nemoclaw-contributor-update-hermes/references/hermes-contract-map.md, .agents/skills/nemoclaw-skills-guide/SKILL.md, and docs/security/hermes-0.19.0-dependency-review.md adequately document the Hermes 0.19 migration, supported managed path, inherited residuals, and remaining runtime gates. The update-branch merge introduced no contributor-authored documentation change.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — prior full focused Hermes release/config/wrapper/patch/state/skill suite: 223 passed, 58 intentionally skipped; current repair: 7 focused files / 99 tests passed, including drift rejection and final-image integrity; exact-head scope correction: 15 focused runtime/integrity tests and 7 skill-contract tests passed; immutable v2026.7.20 source patching passed while preserving _get_process_hermes_home(); test-title, source-shape, syntax, formatting, and skill validation passed.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: exact-head CI / Pull Request run 30463072807 passed, including all eight CLI shards and aggregate checks; E2E / PR Gate controller 30464094971 verified first-attempt child run 30464129619 with every selected E2E shard passing.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only) — build completed with 0 errors and two unchanged environment/site-theme warnings.
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Aaron Erickson aerickson@nvidia.com
Signed-off-by: Julie Yaunches jyaunches@nvidia.com

Summary by CodeRabbit

  • New Features
    • Added Hermes Agent 0.19.0 support with pinned profile policy defaults and Discord recovery permissions patching.
    • Expanded reviewed dashboard policy seeding and durable-state backup/restore to cover additional Hermes SQLite databases.
    • Introduced contributor tooling and guidance for auditing, validating, and generating Hermes upgrade release supplements.
  • Bug Fixes
    • Improved Hermes wrapper compatibility for resumed/continued one-shots, including stricter refusal behavior for unsupported usage-reporting options.
    • Hardened cross-UID Hermes state directory repair and permissions, plus more build-time proof checks.
  • Documentation
    • Added Hermes 0.19.0 dependency/compatibility review materials and expanded the Hermes upgrade contract map.
  • Tests
    • Updated and added coverage for the new config defaults, wrapper routing/flag handling, patchers, ledger backup/restore, and release-supplement collection.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa added dependencies Pull requests that update a dependency file integration: hermes Hermes integration behavior area: packaging Packages, images, registries, installers, or distribution area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening chore Build, CI, dependency, or tooling maintenance area: skills Skills, agent behaviors, prompts, or skill packaging labels Jul 29, 2026
@ericksoa ericksoa self-assigned this Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 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

This PR adds Hermes 0.19.0 release-audit tooling and upgrades NemoClaw’s Hermes configuration, wrapper compatibility, image build checks, cross-UID state handling, dashboard policy seeding, dependency pins, and SQLite persistence validation.

Changes

Hermes 0.19 upgrade

Layer / File(s) Summary
Release evidence and contributor workflow
.agents/skills/nemoclaw-contributor-update-hermes/*, .agents/skills/nemoclaw-skills-guide/SKILL.md, test/hermes-upgrade-skill.test.ts, test/hermes-release-supplement.test.ts
Adds the Hermes upgrade workflow, contract map, catalog entry, authoritative release/tag collector, and validation tests.
Runtime and compatibility contracts
agents/hermes/config/*, agents/hermes/hermes-wrapper.py, agents/hermes/manifest.yaml, agents/hermes/patch-*, src/lib/domain/sandbox/connect-env.ts
Pins Hermes 0.19.0, updates policy and durable-state declarations, adapts one-shot argument parsing, and adds fail-closed compatibility patchers.
Image and state enforcement
agents/hermes/Dockerfile*, agents/hermes/start.sh, agents/hermes/seed-dashboard-config.py, src/lib/state/state-file-restore.ts
Adds pinned patch execution, policy seeding, dependency verification, SQLite probes, cross-UID directory repair, and immutable file-layout checks.
Migration and security validation
docs/security/hermes-0.19.0-dependency-review.md, test/hermes-*, test/seed-hermes-dashboard-config.test.ts, test/sandbox-*.test.ts
Documents migration evidence and validates configuration, dashboard policy, wrapper behavior, runtime metadata, image layout, and snapshot/restore paths.

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

Sequence Diagram(s)

sequenceDiagram
  participant Contributor
  participant ReleaseCollector
  participant HermesGit
  participant DockerBuild
  participant RuntimeTests
  Contributor->>ReleaseCollector: provide release and tag-ref snapshots
  ReleaseCollector->>HermesGit: verify tag identities and calculate ranges
  Contributor->>DockerBuild: build pinned Hermes images
  DockerBuild->>RuntimeTests: execute policy, state, and compatibility probes
  RuntimeTests-->>Contributor: return migration and runtime validation results
Loading

Possibly related issues

Possibly related PRs

Suggested labels: bug-fix

Suggested reviewers: cv, jyaunches

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.16% 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
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the primary change: upgrading Hermes Agent to v2026.7.20.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dep/hermes-v2026.7.20

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

@github-actions

Copy link
Copy Markdown
Contributor

@github-code-quality

github-code-quality Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 89bf4f1 in the dep/hermes-v2026.7.2... branch remains at 96%, unchanged from commit ae71359 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 89bf4f1 in the dep/hermes-v2026.7.2... branch remains at 81%, unchanged from commit ae71359 in the main branch.

Show a code coverage summary of the most impacted files.
File main ae71359 dep/hermes-v2026.7.2... 89bf4f1 +/-
src/lib/onboard/docker-cdi.ts 80% 70% -10%
src/lib/onboard...host-anchors.ts 94% 90% -4%
src/lib/actions...eway-restart.ts 95% 94% -1%
src/lib/onboard/preflight.ts 80% 80% 0%
src/lib/actions...light-guards.ts 86% 90% +4%
src/lib/onboard...box-gpu-mode.ts 92% 97% +5%
src/lib/domain/.../connect-env.ts 89% 97% +8%
src/lib/actions...confirmation.ts 69% 79% +10%
src/lib/actions...ocker-health.ts 65% 82% +17%
src/lib/onboard...box-prebuild.ts 74% 92% +18%

Updated July 29, 2026 15:04 UTC

ericksoa added 2 commits July 28, 2026 17:32
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized E2E selections differ; severity counts match.

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-inference, cloud-onboard, full-e2e, hermes-e2e, security-posture, onboard-repair, onboard-resume, state-backup-restore, upgrade-stale-sandbox

7 optional E2E recommendations
  • gateway-guard-recovery
  • rebuild-hermes
  • rebuild-hermes-stale-base
  • hermes-discord
  • hermes-inference-switch
  • hermes-shields-config
  • mcp-bridge

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@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

🧹 Nitpick comments (4)
.agents/skills/nemoclaw-contributor-update-hermes/scripts/collect-hermes-release-supplement.py (1)

335-357: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate, less-hardened git subprocess call — reuse run_git.

The ancestry check re-implements a raw subprocess.run with a narrower environment (missing GIT_ATTR_NOSYSTEM, GIT_PAGER, GIT_TERMINAL_PROMPT) than run_git uses elsewhere in this same script. Since run_git already supports check=False, this call can be folded into it for consistent hardening and less duplication. Separately, zip(endpoints, endpoints[1:]) is flagged by Ruff (B905/RUF007); itertools.pairwise is the more idiomatic pairwise iterator here (note strict=True would be wrong since the two sequences differ in length by design).

The subprocess-from-request/S603 static-analysis hints on this call and on line 213 are false positives: both use argv lists (no shell), git_executable is pre-validated, and tag values are constrained by CALVER_RE.

♻️ Proposed refactor
+from itertools import pairwise
+
     ranges: list[dict[str, Any]] = []
-    for older, newer in zip(endpoints, endpoints[1:]):
-        ancestry = subprocess.run(
-            [
-                git_executable,
-                "-C",
-                str(repo),
-                "merge-base",
-                "--is-ancestor",
-                older["commitSha"],
-                newer["commitSha"],
-            ],
-            check=False,
-            capture_output=True,
-            env={
-                "GIT_CONFIG_GLOBAL": os.devnull,
-                "GIT_CONFIG_NOSYSTEM": "1",
-                "GIT_NO_LAZY_FETCH": "1",
-                "GIT_NO_REPLACE_OBJECTS": "1",
-                "LC_ALL": "C",
-                "PATH": os.defpath,
-            },
-            timeout=COMMAND_TIMEOUT_SECONDS,
-        )
-        if ancestry.returncode != 0:
+    for older, newer in pairwise(endpoints):
+        try:
+            run_git(
+                git_executable,
+                repo,
+                "merge-base",
+                "--is-ancestor",
+                older["commitSha"],
+                newer["commitSha"],
+            )
+        except SupplementError:
             raise SupplementError(
                 f"{older['tag']!r} is not an ancestor of {newer['tag']!r}"
             )
🤖 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
@.agents/skills/nemoclaw-contributor-update-hermes/scripts/collect-hermes-release-supplement.py
around lines 335 - 357, Replace the raw subprocess.run ancestry check in the
endpoint iteration with the existing run_git helper, preserving check=False,
timeout, and the current merge-base arguments. Import and use itertools.pairwise
instead of zip(endpoints, endpoints[1:]) without strict mode, while leaving the
existing subprocess safety suppressions unchanged where they address false
positives.
test/hermes-profile-policy-defaults.test.ts (1)

126-133: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the established python3 availability gate.

test/hermes-wrapper-provider-merge.test.ts guards its python-dependent suite with describe.skipIf(!canRun) so a maintainer on macOS/Windows does not see a spurious red on npm test. This suite shells out to python3 unconditionally; when the interpreter is absent, spawnSync returns status: null and the assertion fails with an opaque message rather than skipping.

🤖 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/hermes-profile-policy-defaults.test.ts` around lines 126 - 133, Update
the “Hermes profile policy defaults” suite to use the established python3
availability gate, reusing the existing canRun detection pattern from the
related test and applying describe.skipIf(!canRun) before the suite executes.
Keep the current spawnSync behavior unchanged when python3 is available.
test/hermes-light-skin-boundary.test.ts (1)

16-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

The newly added v2026.7.20 entry is inert in both cases.

The positive case still pins v2026.7.1 and the negative case pins v2026.8.1, so neither test would fail if v2026.7.20 were dropped from reviewedVersions. Since the shipped Dockerfile now pins v2026.7.20, assert the pass path for that version.

♻️ Suggested coverage for the newly reviewed version
-        reviewedVersions: ["v2026.6.19", "v2026.7.1", "v2026.7.20"],
+        reviewedVersions: ["v2026.6.19", "v2026.7.1", "v2026.7.20"],
+      }),
+    ).toBeNull();
+    expect(
+      checkHermesLightSkinBoundary({
+        dockerfileText: dockerfileWithVersion("v2026.7.20"),
+        reviewedVersions: ["v2026.6.19", "v2026.7.1", "v2026.7.20"],
       }),
     ).toBeNull();
🤖 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/hermes-light-skin-boundary.test.ts` around lines 16 - 24, Update the
positive test using checkHermesLightSkinBoundary to pin v2026.7.20 in its
dockerfileText, so the test directly verifies the newly reviewed version passes.
Keep the existing negative test for the unreviewed v2026.8.1 unchanged.
test/hermes-dependency-review.test.ts (1)

72-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Substring checks on production source stand in for behavioral coverage of the changed contracts. Both suites assert that a source file contains an identifier rather than that the changed behavior holds, so they pass even if the referenced code is unreachable, commented out, or semantically wrong.

  • test/hermes-dependency-review.test.ts#L72-L76: assert membership in the wrapper's parsed flag constants (as the Dockerfile AST gate does), or drop the case and rely on test/hermes-wrapper-provider-merge.test.ts and test/hermes-wrapper-oneshot-routing.test.ts.
  • test/hermes-discord-recovery-permissions.test.ts#L184-L219: replace the os.fchown/os.fchmod/O_NOFOLLOW toContain assertions with a runCrossUidParentRepair success case that asserts the created directory ends up at mode 2770.

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

🤖 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/hermes-dependency-review.test.ts` around lines 72 - 76, Replace the
source-text substring assertions in test/hermes-dependency-review.test.ts:72-76
with an assertion that the wrapper’s parsed flag constants contain the expected
entries, or remove this case if coverage is already provided by
hermes-wrapper-provider-merge.test.ts and
hermes-wrapper-oneshot-routing.test.ts. In
test/hermes-discord-recovery-permissions.test.ts:184-219, replace the os.fchown,
os.fchmod, and O_NOFOLLOW toContain checks with a successful
runCrossUidParentRepair scenario that verifies the created directory has mode
2770.

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 `@agents/hermes/Dockerfile.base`:
- Around line 440-455: Lower the python-multipart pin in the override from
0.0.32 to 0.0.31, including both package hashes and the version assertion in the
uv pip install block. Update the surrounding Hermes security rationale to
identify 0.0.31 as the first stable release addressing the stated GHSAs.

In `@agents/hermes/hermes-wrapper.py`:
- Around line 395-441: Add a Dockerfile build-time drift check for
_HERMES_SESSION_NAME_BOUNDARIES, comparing the wrapper’s set with the pinned
Hermes v0.19 reference used by the existing drift gate. Integrate it into the
current validation flow without changing the boundary set or the existing
subcommand and flag checks.

---

Nitpick comments:
In
@.agents/skills/nemoclaw-contributor-update-hermes/scripts/collect-hermes-release-supplement.py:
- Around line 335-357: Replace the raw subprocess.run ancestry check in the
endpoint iteration with the existing run_git helper, preserving check=False,
timeout, and the current merge-base arguments. Import and use itertools.pairwise
instead of zip(endpoints, endpoints[1:]) without strict mode, while leaving the
existing subprocess safety suppressions unchanged where they address false
positives.

In `@test/hermes-dependency-review.test.ts`:
- Around line 72-76: Replace the source-text substring assertions in
test/hermes-dependency-review.test.ts:72-76 with an assertion that the wrapper’s
parsed flag constants contain the expected entries, or remove this case if
coverage is already provided by hermes-wrapper-provider-merge.test.ts and
hermes-wrapper-oneshot-routing.test.ts. In
test/hermes-discord-recovery-permissions.test.ts:184-219, replace the os.fchown,
os.fchmod, and O_NOFOLLOW toContain checks with a successful
runCrossUidParentRepair scenario that verifies the created directory has mode
2770.

In `@test/hermes-light-skin-boundary.test.ts`:
- Around line 16-24: Update the positive test using checkHermesLightSkinBoundary
to pin v2026.7.20 in its dockerfileText, so the test directly verifies the newly
reviewed version passes. Keep the existing negative test for the unreviewed
v2026.8.1 unchanged.

In `@test/hermes-profile-policy-defaults.test.ts`:
- Around line 126-133: Update the “Hermes profile policy defaults” suite to use
the established python3 availability gate, reusing the existing canRun detection
pattern from the related test and applying describe.skipIf(!canRun) before the
suite executes. Keep the current spawnSync behavior unchanged when python3 is
available.
🪄 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: 7f7149a2-7ebc-43e6-ac58-a7fd41ff3fd5

📥 Commits

Reviewing files that changed from the base of the PR and between eeab81c and d246752.

📒 Files selected for processing (35)
  • .agents/skills/nemoclaw-contributor-update-hermes/SKILL.md
  • .agents/skills/nemoclaw-contributor-update-hermes/agents/openai.yaml
  • .agents/skills/nemoclaw-contributor-update-hermes/references/hermes-contract-map.md
  • .agents/skills/nemoclaw-contributor-update-hermes/scripts/collect-hermes-release-supplement.py
  • .agents/skills/nemoclaw-skills-guide/SKILL.md
  • agents/hermes/Dockerfile
  • agents/hermes/Dockerfile.base
  • agents/hermes/config/hermes-config.ts
  • agents/hermes/hermes-wrapper.py
  • agents/hermes/manifest.yaml
  • agents/hermes/patch-discord-recovery-permissions.py
  • agents/hermes/patch-langfuse-credentials.mts
  • agents/hermes/patch-profile-policy-defaults.py
  • agents/hermes/patch-session-list-preview.py
  • agents/hermes/seed-dashboard-config.py
  • agents/hermes/start.sh
  • docs/security/hermes-0.19.0-dependency-review.md
  • src/lib/domain/sandbox/connect-env.test.ts
  • src/lib/domain/sandbox/connect-env.ts
  • src/lib/state/state-file-restore.ts
  • test/generate-hermes-config.test.ts
  • test/hermes-dependency-review.test.ts
  • test/hermes-discord-recovery-permissions.test.ts
  • test/hermes-doctor-config-hash.test.ts
  • test/hermes-final-image-layout.test.ts
  • test/hermes-light-skin-boundary.test.ts
  • test/hermes-profile-policy-defaults.test.ts
  • test/hermes-release-supplement.test.ts
  • test/hermes-start.test.ts
  • test/hermes-state-ledger-snapshot.test.ts
  • test/hermes-upgrade-skill.test.ts
  • test/hermes-wrapper-oneshot-routing.test.ts
  • test/hermes-wrapper-provider-merge.test.ts
  • test/seed-hermes-dashboard-config.test.ts
  • test/snapshot.test.ts
💤 Files with no reviewable changes (1)
  • test/snapshot.test.ts

Comment thread agents/hermes/Dockerfile.base
Comment thread agents/hermes/hermes-wrapper.py
Signed-off-by: Aaron Erickson <aerickson@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 (1)
agents/hermes/seed-dashboard-config.py (1)

537-544: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the intentionally broad except Exception catches for the linter.

Static analysis flags all four blind excepts (BLE001). Each is deliberately broad for a documented security reason (avoid interpolating credential-bearing parser/decoder context into stderr), which is the right call here — but without a # noqa: BLE001 explaining that, the linter will keep re-flagging these on every run.

🧹 Example suppression
-    except Exception:
+    except Exception:  # noqa: BLE001 - avoid leaking parser context that may contain secrets

Also applies to: 606-612, 627-634, 660-668

🤖 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 `@agents/hermes/seed-dashboard-config.py` around lines 537 - 544, Add an inline
# noqa: BLE001 suppression to each of the four intentionally broad except
Exception handlers, including the handler near the shown security log and those
in the referenced sections. Preserve the existing credential-protective comments
and error-handling behavior.

Source: Linters/SAST tools

🤖 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 `@agents/hermes/seed-dashboard-config.py`:
- Around line 537-544: Add an inline # noqa: BLE001 suppression to each of the
four intentionally broad except Exception handlers, including the handler near
the shown security log and those in the referenced sections. Preserve the
existing credential-protective comments and error-handling behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c6b631c1-f07b-425f-8344-ecb77a5e77c3

📥 Commits

Reviewing files that changed from the base of the PR and between 71264e9 and c37d1e9.

📒 Files selected for processing (11)
  • .agents/skills/nemoclaw-contributor-update-hermes/SKILL.md
  • .agents/skills/nemoclaw-contributor-update-hermes/references/hermes-contract-map.md
  • agents/hermes/Dockerfile
  • agents/hermes/seed-dashboard-config.py
  • docs/security/hermes-0.19.0-dependency-review.md
  • test/hermes-light-skin-boundary.test.ts
  • test/sandbox-provisioning.test.ts
  • test/sandbox-rlimit-hooks.test.ts
  • test/seed-hermes-dashboard-config.test.ts
  • test/snapshot-stale-directory-restore.test.ts
  • test/update-hermes-agent-script.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • .agents/skills/nemoclaw-contributor-update-hermes/references/hermes-contract-map.md
  • .agents/skills/nemoclaw-contributor-update-hermes/SKILL.md
  • docs/security/hermes-0.19.0-dependency-review.md
  • agents/hermes/Dockerfile

@ericksoa

Copy link
Copy Markdown
Contributor Author

Exact-head security review

PASS at head c37d1e92455c8f724519bac4d12a39259bb5d093 against base eeab81cc5542902538c97db63c132c0fdbd4341c.

No upgrade-created exploitable vulnerability, credential exposure, command/path injection, authorization bypass, or container/root escape remains. This is safe to continue toward merge once exact-head CI, protected E2E, and required review pass.

Fixed finding

agents/hermes/seed-dashboard-config.py now parses and validates gateway YAML, reviewed policy, and existing dashboard YAML before either destination write. Malformed, non-mapping, routing-free, or unreadable inputs return nonzero with fixed secret-free diagnostics, preserve both destination files byte-for-byte, and cause start.sh to refuse dashboard launch. The targeted seeder suite passes 31/31.

Explicit residual dispositions

  • Generic restore TOCTOU — warning, accepted pre-existing bounded debt. The generic restore primitive still checks and then uses pathnames under cross-UID state parents. Fixed normalized manifest paths, sandbox-UID execution, atomic replacement, and no-follow static checks prevent command injection or root escape; the remaining impact is sandbox-local integrity/availability if a live gateway races an owned parent. Follow-up belongs in generic snapshot hardening via descriptor-relative/no-follow inode anchoring or producer quiescing.
  • Pillow/Starlette advisories — warning, accepted baseline debt. Reachable Pillow 12.2 parser and Starlette 1.0.1 form-DoS advisories predate this upgrade, and the selected target adds no advisory regression. Remediate upstream-coherently with a regenerated lock and wider tests rather than an untracked overlay.
  • Named-profile database raw tar — warning, accepted Medium scope residual. Default-profile cron and Discord ledgers use online SQLite backup. Dynamic profiles/<name> databases remain in the raw directory capture and can be inconsistent during a concurrent snapshot. Generic validated profile-local SQLite discovery is follow-up work; there is no default-profile regression.
  • Retained patcher shape/count binding — Low hardening debt, accepted. The Discord, session, and Langfuse patchers do not bind whole-file source hashes, but current source is immutably bound by the verified multi-platform base digest/revision plus exact source shapes and runtime build probes. Add per-file reviewed hashes on the next patch touch or Hermes upgrade; there is no current bypass.

Security categories: secrets PASS; input validation PASS; authentication/authorization PASS; dependencies WARNING (accepted baseline); errors/logging PASS; cryptography PASS; configuration PASS; security testing PASS; system security WARNING (accepted bounded residuals).

Base provenance also passes: trusted workflow run 30411365314 published amd64 and arm64 manifests under OCI index sha256:c4aee5c9b087840da6e1eb2127fef9f4a2eab0862992008d1741dc09f632422e, and the pinned final image reports Hermes 0.19.0 plus attested python-multipart 0.0.32 with reviewed ownership modes.

@ericksoa
ericksoa requested review from cv and jyaunches July 29, 2026 01:20
@ericksoa

Copy link
Copy Markdown
Contributor Author

Ready for maintainer review

Exact head c37d1e92455c8f724519bac4d12a39259bb5d093 against base eeab81cc5542902538c97db63c132c0fdbd4341c is mergeable and mechanically green:

  • 40 applicable PR checks pass, including all eight CLI shards, CodeQL, both advisors, CodeRabbit, multi-architecture sandbox builds, self-hosted smoke/isolation checks, macOS, and WSL.
  • The protected E2E child run passed all nine selected scenarios (ten expanded jobs), including Hermes E2E, state backup/restore, and stale-sandbox upgrade.
  • The trusted required E2E gate and coordination check are success.
  • The exact-head security review is PASS with all residuals explicitly dispositioned.
  • No review threads remain unresolved.

The remaining branch-protection item is independent approval. Target landing remains Friday, July 31, 2026; please do not merge earlier.

@cv cv added the v0.0.98 label Jul 29, 2026
@copy-pr-bot

copy-pr-bot Bot commented Jul 29, 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.

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@jyaunches

Copy link
Copy Markdown
Contributor

Exact-head differential security review — PASS

Reviewed base fa96c91f4a3f9a8fb986f360c504acad8392617a through head 6c493598205a133f929538ce7e35d499731fbb2e, including the merge-created Hermes 0.19 gateway-runtime-metadata repair.

  1. Authentication and authorization: No authentication, approval, token, or reviewer-routing behavior changes. The repair preserves Hermes' process-scoped home selector, so profile context cannot redirect process-owned gateway metadata.
  2. Input validation and path safety: The patcher requires each exact upstream helper shape exactly once before writing. Unexpected, obsolete, already-patched, or partially changed input fails closed without modifying the target.
  3. Injection and execution: No new shell interpolation or untrusted command input. The image executes a repository-owned Python patcher with fixed source and destination paths.
  4. Information disclosure: No new logs expose paths, credentials, source lines, or configuration contents. Drift errors report only aggregate source-shape state.
  5. Dependency and supply chain: No dependency identity changes in this repair. The patcher is bound by SHA-256 before root-owned build execution, and the existing final-image integrity contract verifies the declared digest and copied path.
  6. Cryptography and secrets: SHA-256 is used only for artifact integrity. No cryptographic protocol, key, credential, or secret-source behavior changes.
  7. Concurrency and TOCTOU: PID, lock, and status readers share the same process-scoped writable runtime root. The explicit pid_path lock derivation remains unchanged.
  8. Resource handling and availability: The repair moves only three small lifecycle metadata files. Exact-shape rejection prevents a silently incomplete patch that could cause false PID races or failed managed-gateway replacement.
  9. Isolation and permissions: Root-owned HERMES_HOME configuration remains immutable; only PID, lock, and status metadata move below the existing writable runtime directory. No sandbox, network, UID, or capability boundary broadens.

Blocking findings: none.

HERMES-20 is closed by the exact-source retarget, negative drift test, patcher hash binding, and final-image path/integrity probes. The managed-gateway restart E2E remains the exact-PR-SHA runtime gate. The four non-blocking residual dispositions from the prior full review are unchanged.

Local evidence: selected-file hooks passed; 7 focused files / 99 tests passed; immutable v2026.7.20 source patching passed while preserving _get_process_hermes_home(); normal commit and pre-push hooks passed; GitHub marks every commit, including 6c4935982, as Verified.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa

Copy link
Copy Markdown
Contributor Author

Exact-head security review — PASS

Reviewed 34fed5abdde711b0b4333f885071643121e0e64c.

The Hermes 0.19 retarget preserves _get_process_hermes_home(), hash-binds the patcher, and relocates the central PID, lock, and status helpers needed by the supported NemoClaw host-managed default-gateway lifecycle. I found no new credential, authorization, network, or process-identity regression in that supported path.

Direct upstream gateway run --replace, planned-stop/takeover markers, named-profile and multiplexer readers, and service/boot/web/Windows/backup/Docker consumers still use top-level metadata paths. This is now explicitly recorded as inherited Medium residual HERMES-21; the same limitation exists in base SHA fa96c91f, and this review does not claim those direct Hermes lifecycle paths work under shields-up.

The Hermes-upgrade skill now requires a full pinned-tree search for explicit path consumers and forbids treating a helper-level image probe as complete relocation evidence. Integrity, focused patch/image tests, and skill validation pass.

Security disposition: safe to merge once normal exact-head checks and the protected managed-restart E2E pass. This accepts the documented inherited residual only; it is not a waiver asserting broader direct-CLI support.

@jyaunches
jyaunches merged commit 0c541e1 into main Jul 29, 2026
94 of 95 checks passed
@jyaunches
jyaunches deleted the dep/hermes-v2026.7.20 branch July 29, 2026 15:28
jyaunches added a commit that referenced this pull request Jul 30, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Hermes 0.19 introduced deterministic runtime regressions after
`v0.0.97`: dashboard seed-marker drift, an unsupported blanket
reasoning-effort request, and a mutable cron execution ledger inside the
sealed cron job-definition directory. This change aligns the reviewed
configuration contracts and relocates only mutable cron execution
history into the writable runtime boundary while keeping cron job
definitions sealed.

The trusted exact-head E2E also exposed a stale Hermes MCP fixture:
Hermes 0.19 names native MCP tools as `mcp__server__tool`, but the
fixture still queried the Hermes 0.18 single-underscore name and
accepted an echoed search query as a match. The fixture now uses the
v0.19 name and requires an exact structural match before progressing.

## Changes

- Require the current Hermes dashboard seed marker and omit the blanket
reasoning-effort default from generated requests.
- Patch the hash-pinned Hermes 0.19 execution ledger and quick-snapshot
sources to use `runtime/cron-executions.db`.
- Repair the writable `gateway` and `runtime` boundaries during restart
while preserving `cron` as `root:sandbox` with mode `0755`.
- Emit fixed, allowlisted startup diagnostics without exposing untrusted
output.
- Align the Hermes MCP fixture with the v0.19 `mcp__server__tool` name
and fail closed unless discovery and schema responses structurally
identify the exact deferred tool.
- Add focused unit, integration, E2E-support, and live-E2E regression
coverage for the post-tag failure paths.
- Document the sealed cron definition boundary, runtime ledger, restore
behavior, and exact-head Hermes dependency evidence.

## Type of Change

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

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Codex Desktop completed
the repository nine-category review for exact head `8e0bbe24a` against
base and merge base `d52d4599a`; all categories passed with no findings.
The final delta is test-only and strengthens fail-closed MCP fixture
validation.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `docs/manage-sandboxes/backup-restore.mdx` documents the
relocated cron ledger and named-profile snapshot limitation.
`docs/security/hermes-0.19.0-dependency-review.md` documents the restart
regression, protected `cron` directory, writable `runtime` boundary, and
Hermes v0.19 `mcp__server__tool` naming. The final test-only delta
aligns the fixture with that documented naming and requires an exact
structural discovery match; no additional user-facing documentation is
required.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 8e0bbe2 -->
<!-- docs-review-agents-blob-sha: c052d60 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable
- Station profile/scenario: Not applicable
- Result: Not applicable
- Supporting evidence: Not applicable

## Trusted E2E Failure and Fix

The approved trusted run for prior exact head `cdd62f906` passed
Bedrock-compatible Anthropic with Hermes and both Hermes
inference-switch scenarios, but failed [MCP bridge
(Hermes)](https://github.com/NVIDIA/NemoClaw/actions/runs/30502554974/job/90745710062).
This is a deterministic fixture regression, not a flake or production
MCP failure. [PR #7771](#7771)
upgraded Hermes to 0.19; upstream commit
[`e01f58ff1`](NousResearch/hermes-agent@e01f58f)
changed native MCP names to `mcp__server__tool`. The fixture retained
`mcp_fake_fake_echo`, and its substring assertion mistook the echoed
query for a discovery match before calling `tool_describe` with the
nonexistent legacy name.

Exact head `8e0bbe24a` corrects the tool name, requires `matches[].name`
to equal the deferred name, validates the exact described schema, and
adds an echoed-query-with-empty-matches regression test. A new
exact-head trusted E2E verdict is required before merge.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification:
Focused Hermes suites passed 111 tests with 3 skips; the post-writing
affected set passed 86 tests with 1 skip; startup passed 39 tests;
MCP/E2E-support passed 57 tests; PR-risk/gate coverage passed 97 tests.
On exact head `8e0bbe24a`, `npm exec -- vitest run
test/mcp-bridge-servers.test.ts` passed all 10 tests after normal hooks;
`npm run typecheck`, targeted Biome checks, `git diff --check`, and `npm
run checks:repository` passed.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Exact-head GitHub CI is in
progress.
- [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) —
result: exact-head build completed with 0 errors and 2 existing Fern
warnings.
- [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)

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

---------

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@sandl99 sandl99 mentioned this pull request Jul 30, 2026
23 tasks
cv pushed a commit that referenced this pull request Jul 30, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Add the canonical pre-tag release entry for NemoClaw v0.0.98.
The dated entry records the user-visible changes merged after v0.0.97
and links each release theme to its published documentation.

## Changes

- Add `docs/changelog/2026-07-29.mdx` with the exact `## v0.0.98`
release heading.
- Summarize Hermes 0.19, Deep Agents Code automation and skill safety,
readiness diagnostics, lifecycle recovery, uninstall behavior, messaging
conflicts, dependency hardening, and bounded diagnostics.
- Use the parser-safe MDX SPDX comment and root-absolute routes for
published OpenClaw, Hermes, and Deep Agents documentation.

### Source summary

- [#7849](#7849) ->
`docs/changelog/2026-07-29.mdx`: Record the Hermes 0.19 runtime
migration repairs for cron state, dashboard seeding, and MCP naming.
- [#7662](#7662) ->
`docs/changelog/2026-07-29.mdx`: Record bounded gateway and Docker
subprocess diagnostics.
- [#7850](#7850) ->
`docs/changelog/2026-07-29.mdx`: Record verified no-clobber Deep Agents
Code skill installation.
- [#7848](#7848) ->
`docs/changelog/2026-07-29.mdx`: Record post-reboot delivery-chain
recovery for visible OpenClaw sandboxes.
- [#7831](#7831) ->
`docs/changelog/2026-07-29.mdx`: Record OpenShell gateway-state
preservation during uninstall.
- [#7827](#7827) ->
`docs/changelog/2026-07-29.mdx`: Record the removal of upstream test
sources from published Hermes images.
- [#7775](#7775) ->
`docs/changelog/2026-07-29.mdx`: Record the blocking diagnostic for
unsupported `DOCKER_HOST` values.
- [#7833](#7833) ->
`docs/changelog/2026-07-29.mdx`: Record reviewed Python dependency
baselines for Hermes and Deep Agents Code images.
- [#7771](#7771) ->
`docs/changelog/2026-07-29.mdx`: Record the managed Hermes Agent 0.19.0
upgrade.
- [#7811](#7811) ->
`docs/changelog/2026-07-29.mdx`: Record fail-closed messaging channel
conflict handling.
- [#7797](#7797) ->
`docs/changelog/2026-07-29.mdx`: Record the managed non-interactive Deep
Agents Code JSON envelope.
- [#7782](#7782) ->
`docs/changelog/2026-07-29.mdx`: Record the storage-remediation
readiness capability.
- [#7784](#7784) ->
`docs/changelog/2026-07-29.mdx`: Record the 120-second OpenShell
readiness budget for sandbox recreation.
- [#7810](#7810) ->
`docs/changelog/2026-07-29.mdx`: Record rejection of stale Deep Agents
Code security inventories.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification:
`test/changelog-docs.test.ts` validates the native changelog contract,
including the version heading, MDX SPDX comment, and published routes.
- [ ] Tests not applicable — justification:
- [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:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `docs/changelog/2026-07-29.mdx` was reviewed against
`docs/CONTRIBUTING.md` and `WRITING.md` for release meaning,
terminology, structure, voice, sentence form, MDX structure, published
routes, and code-sample presentation. The changelog contract passed 6
tests. The docs build completed with 0 errors and 2 existing Fern
warnings.
- Agent: Codex CLI
<!-- docs-review-head-sha: e3221d1 -->
<!-- docs-review-agents-blob-sha: c052d60 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable. `scripts/prepare-dgx-station-host.sh`
is unchanged.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run
test/changelog-docs.test.ts` passed 6 tests.
- [ ] 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) — The
build completed with 0 errors and 2 existing Fern warnings.
- [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)
— Native changelog entries use the required parser-safe MDX SPDX comment
and do not use frontmatter.

---
Signed-off-by: San Dang <sdang@nvidia.com>


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

## Summary by CodeRabbit

- **New Features**
- Added managed Hermes upgrades with verified releases, version
reporting, and preserved configuration contracts.
- Improved Deep Agents Code JSON output and skill installation behavior.
  - Added clearer Docker host and system readiness reporting.
  - Improved post-reboot delivery recovery and sandbox readiness timing.
- **Bug Fixes**
  - Preserved gateway state when uninstalling with `--keep-openshell`.
- Prevented conflicting messaging credentials from blocking onboarding
and rebuilds.
- Improved gateway diagnostics, dependency security, runtime filesystem
protection, and evidence handling.
- **Documentation**
  - Published the v0.0.98 release notes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
cv pushed a commit that referenced this pull request Aug 3, 2026
<!-- markdownlint-disable MD041 -->
## Summary

`nemoclaw shields down` replaced the complete live OpenShell policy and
dropped generated policy entries for registered Model Context Protocol
(MCP) servers. This change reconciles only exact NemoClaw-managed MCP
entries during Shields transitions, so a surviving server remains
reachable while removed servers stay removed.

Stacked on prerequisite #8130, which makes Shields deadline recovery
serialize with lifecycle mutations without signaling the lock owner,
this focused fix supersedes the MCP portion of #7980.

## Related Issue

Fixes #7952

## Changes

- Prove managed MCP policy ownership from exact agreement between the
sandbox registry, committed generated-policy record, and live gateway
policy.
- Save the owned MCP key manifest with the Shields snapshot, remove
snapshot-time managed entries during restoration, and overlay only
current exact entries.
- Fail closed on ambiguous, stale, incomplete, malformed, or legacy
ownership during manual transitions. At an expired deadline, omit
unproven managed MCP entries and audit the omission instead of extending
the Shields-down window.
- Preserve current managed MCP entries when building the permissive
runtime policy, while rejecting an unreadable or ambiguous live policy.
- Clean staged runtime policy files across early failure paths.
- Restore the Hermes live regression assertions at the actual failure
boundary and around the unrelated server lifecycle.
- Document MCP policy reconciliation for manual and automatic
restoration.

## Failure Timing and Hermes Upgrade Context

The original journey had a hidden Shields lifecycle between the first
successful call to server A and the later lifecycle for server B:

1. Run `shields up`.
2. Restart the Hermes gateway.
3. Run `shields down`.
4. Exercise the configuration rollback path.
5. Add and remove B.
6. Call A.

Boundary instrumentation recorded in #7952 showed that A remained
healthy through Shields up and the gateway restart. It became unusable
immediately after Shields down, which dropped A's generated MCP policy.
The later failure after B was removed was only where the test noticed
the already-broken route; B removal was a misleading correlation.

This surfaced during the Hermes upgrade work because new coverage and
upgrade repairs landed nearly back-to-back:

- #7761 added the Hermes MCP helper containing Shields up, gateway
restart, Shields down, and rollback. Its verification collected and
imported the live target but did not run the complete live E2E.
- #7771 upgraded Hermes the next day, but its selected E2Es skipped the
`mcp-bridge` target.
- #7849 repaired Hermes 0.19 migrations and updated MCP tool naming,
allowing the live test to progress far enough to expose the later
failure.
- #7866 moved the explicit `mcp restart A` before the first post-removal
call. Restart reapplied A's generated policy and masked the
missing-policy state.

The corrected regression order is:

1. Run `shields up`.
2. Restart the Hermes gateway.
3. Run `shields down`.
4. Call A immediately.
5. Exercise the configuration rollback path.
6. Add B, prove the DNS-rebinding connection is denied, remove B, and
verify that A's managed policy is unchanged while B's policy is gone.
7. Call A before the later explicit restart.
8. Capture the authenticated rediscovery offset.
9. Run `mcp restart A` without resupplying the secret.
10. Call A and verify authenticated rediscovery.

Whole-policy Shields replacement and the filesystem-only runtime merge
predate the Hermes upgrade. This is a latent NemoClaw Shields
policy-composition defect detected by expanded Hermes regression
coverage, not a Hermes upgrade regression.

## Type of Change

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

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Independent exact-head
Codex security review passed all nine categories at
`18039569796d6ac7604de032edb7abf84f2c73c4`; no findings.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: Reviewed `docs/manage-sandboxes/runtime-controls.mdx` and
`docs/reference/commands.mdx`, all rendered guide variants, changed
operator-facing text, comments, test titles, and the Hermes E2E
chronology. Verified claims against source, issue #7952, and PRs #7761,
#7771, #7849, and #7866. `npm run docs` completed with 0 errors and 2
existing Fern warnings.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 1803956 -->
<!-- docs-review-agents-blob-sha: 3dd7c24 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; `scripts/prepare-dgx-station-host.sh`
is unchanged.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification:
Focused CLI 123/123, integration 11/11, E2E support 13/13, `npm run
typecheck:cli`, `npm run checks:repository`, test-size guardrail, E2E
semantic phase plans, and serial `npm run test:changed` 674/674 passed.
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: [Standard PR CI run
30824992396](https://github.com/NVIDIA/NemoClaw/actions/runs/30824992396)
passed. One inherited 50 ms lifecycle-lock assertion timing flake passed
on the failed-job rerun without a code 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)
- [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)

`npm run docs` passed with 0 errors and 2 existing Fern warnings, so the
warning-free checkbox remains unchecked. No new documentation pages were
added.

Trusted E2E [run
30826792180](https://github.com/NVIDIA/NemoClaw/actions/runs/30826792180)
passed all 10 selected checks: cloud inference, cloud onboard, security
posture, inference routing, MCP bridge, MCP bridge dev, network policy,
onboard repair, onboard resume, and OpenShell credential-generation
window. The primary review advisor reported no findings. Nemotron
completed after retrying a protocol-only failure; its one test warning
requested the exact transition/state ownership-mismatch deadline
regression already present in
`src/lib/shields/policy-transition.test.ts`, which passed.

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: packaging Packages, images, registries, installers, or distribution area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening area: skills Skills, agent behaviors, prompts, or skill packaging chore Build, CI, dependency, or tooling maintenance dependencies Pull requests that update a dependency file integration: hermes Hermes integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants