Skip to content

test(hermes): cover MCP integrity through restart - #7761

Merged
cv merged 6 commits into
mainfrom
codex/7499-hermes-mcp-integrity-restart-v2
Jul 28, 2026
Merged

test(hermes): cover MCP integrity through restart#7761
cv merged 6 commits into
mainfrom
codex/7499-hermes-mcp-integrity-restart-v2

Conversation

@cjagwani

@cjagwani cjagwani commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fix locked Hermes gateway restart after a managed MCP update. The root-owned restart controller now recognizes the guard-generated v1 MCP state record in the strict config hash while continuing to reject malformed, duplicate, unknown, or ambiguous records.

The PR also adds a focused live regression covering managed add, shields restoration, real gateway restart, integrity verification, and failed-reload rollback. It replaces #7743 on current main; repository rules forbid force-pushing the published replacement branch. One narrow test-only timeout adjustment salvages a workflow-boundary check that twice exhausted Vitest's default 5-second envelope despite its child process already being bounded to 30 seconds.

Related Issue

Closes #7499

Changes

  • Parse zero or one exact nemoclaw-hermes-mcp-state-v1 metadata record in the locked Hermes strict hash, preserving legacy two-record hashes.
  • Reject malformed, duplicate, or unknown metadata and duplicate config hash paths with GATEWAY_CONFIG_HASH_MISMATCH.
  • Exercise the existing Hermes MCP live target through managed add, shields restoration, supervisor-mediated restart, exact locked file/hash verification, and public transaction inspection.
  • Inject a first-reload failure and require the real rollback path to restore config and both anchors byte-for-byte, prove a healthy rollback reload, and confirm current state through the packaged public inspect flow.
  • Scan raw Hermes files and the startup log after restart to confirm the fake bridge secret is absent.
  • Give the existing workflow-boundary test a 40-second Vitest envelope around its already-bounded 30-second child process.

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: This restores the existing documented locked Hermes restart contract; the v1 hash record is an internal guard-generated implementation detail.
  • 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: Manual nine-category security review on 79767cd8c passed all categories. The root ownership/mode checks remain unchanged; parsing is bounded ASCII with an exact known-record regex, and negative tests cover malformed, duplicate, unknown, and ambiguous input.
  • 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: no-docs-needed
  • Evidence: The parser restores the existing locked Hermes restart contract while preserving fail-closed validation. The E2E follow-up only strengthens verification through public packaged behavior.
  • Agent: Codex Desktop /root/replacement_docs_review

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 — managed gateway control 4/4; Hermes MCP transaction 27/27; serial MCP live-selection E2E-support 41/41; workflow-boundary E2E-support 33/33; live Hermes target collection/import; semantic E2E phases 115 tests across 73 files; CLI typecheck; exact Vitest project-membership and test-size gates.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • 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)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Charan Jagwani cjagwani@nvidia.com

Summary by CodeRabbit

  • Tests
    • Expanded end-to-end coverage for managed MCP bridge setup, including Hermes shield restoration across a locked gateway restart.
    • Added rollback validation that confirms a failed managed reload restores Hermes configuration and integrity anchors.
    • Tightened Hermes-related secret expectations and updated Hermes phase sequencing.
    • Added unit coverage for strict locked-hash parsing, covering legacy/current Hermes state variants and rejecting malformed/ambiguous inputs.
    • Increased timeout for workflow-to-PR reporting integration E2E.
  • Bug Fixes
    • Strengthened locked Hermes config-hash validation with strict state-line parsing and clearer mismatch handling.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani cjagwani added integration: hermes Hermes integration behavior area: security Security controls, permissions, secrets, or hardening labels Jul 28, 2026
@cjagwani cjagwani self-assigned this Jul 28, 2026
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Hermes end-to-end coverage for shield restoration, gateway restart, locked configuration integrity, MCP registry state, rollback after an injected reload failure, strict hash parsing, and an explicit workflow test timeout.

Changes

Hermes MCP integrity lifecycle

Layer / File(s) Summary
Locked Hermes hash validation
scripts/managed-gateway-control.py, test/managed-gateway-control.test.ts
Parses Hermes state metadata from locked-hash input and rejects malformed, duplicate, or ambiguous records with GATEWAY_CONFIG_HASH_MISMATCH.
Restart and integrity validation
test/e2e/live/mcp-bridge-hermes-lifecycle.ts, test/e2e/live/mcp-bridge-phases.ts, test/e2e/live/mcp-bridge.test.ts
Restores shields, restarts and health-checks the gateway, validates filesystem and MCP state, and wires the new phase into the Hermes shard test.
Managed transaction rollback
test/e2e/live/mcp-bridge-hermes-lifecycle.ts
Injects a reload failure and verifies restoration of configuration bytes, hash anchors, gateway health, and the current integrity state.

Workflow report test timeout

Layer / File(s) Summary
Workflow report timeout
test/e2e/support/e2e-report-to-pr-workflow-boundary.test.ts
Sets an explicit 40,000-millisecond timeout for the planner matrix workflow-output test.

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

Sequence Diagram(s)

sequenceDiagram
  participant HermesTest
  participant SandboxClient
  participant HermesGateway
  participant TransactionHelper
  HermesTest->>SandboxClient: restore shields and restart gateway
  SandboxClient->>HermesGateway: run health checks
  HermesGateway-->>SandboxClient: report healthy status
  HermesTest->>TransactionHelper: run managed add with injected reload failure
  TransactionHelper->>HermesGateway: attempt reload
  HermesGateway-->>TransactionHelper: fail first reload
  TransactionHelper->>TransactionHelper: restore config and hash anchors
  TransactionHelper->>HermesGateway: perform rollback reload
  HermesGateway-->>TransactionHelper: report success
  TransactionHelper-->>HermesTest: return current integrity state
Loading

Possibly related PRs

Suggested labels: area: e2e, bug-fix

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The fix and regression test address the stale config-hash restart failure, rollback behavior, shields restoration, and integrity guarantees from #7499.
Out of Scope Changes check ✅ Passed The only extra change is a test timeout increase, which is incidental support for the new e2e coverage and not unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main theme: Hermes/MCP integrity validated through restart behavior.
✨ 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 codex/7499-hermes-mcp-integrity-restart-v2

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

@github-code-quality

github-code-quality Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 8481c68 in the codex/7499-hermes-mc... branch remains at 96%, unchanged from commit 0fe7ed7 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 8481c68 in the codex/7499-hermes-mc... branch remains at 81%, unchanged from commit cf34b72 in the main branch.

Show a code coverage summary of the most impacted files.
File main cf34b72 codex/7499-hermes-mc... 8481c68 +/-
src/lib/onboard...ndbox-create.ts 83% 33% -50%
src/lib/onboard...-create-plan.ts 88% 75% -13%
src/lib/onboard...ndbox-create.ts 91% 83% -8%
src/lib/sandbox...rce-identity.ts 88% 88% 0%

Updated July 28, 2026 23:06 UTC

@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)
test/e2e/live/mcp-bridge-hermes-lifecycle.ts (1)

243-259: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the public inspect flow for the rollback assertion

The rollback check is coupled to the production string config and hashes were restored and to private helpers like _assert_non_root_lifecycle_identity(), _gateway_healthy(), and _load_guard(). The same integrity state is already available through the public inspect path, so this can stay on the supported boundary and avoid brittle internal-shape coupling.

🤖 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/e2e/live/mcp-bridge-hermes-lifecycle.ts` around lines 243 - 259, Update
the rollback assertion in the lifecycle test to use the public inspect flow
instead of matching the production message or calling
_assert_non_root_lifecycle_identity(), _gateway_healthy(), and _load_guard().
Assert rollback success and current integrity through the supported inspect
interface, while preserving the exact restoration check for config and hash
files.

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.

Nitpick comments:
In `@test/e2e/live/mcp-bridge-hermes-lifecycle.ts`:
- Around line 243-259: Update the rollback assertion in the lifecycle test to
use the public inspect flow instead of matching the production message or
calling _assert_non_root_lifecycle_identity(), _gateway_healthy(), and
_load_guard(). Assert rollback success and current integrity through the
supported inspect interface, while preserving the exact restoration check for
config and hash files.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3129b38a-d910-41c1-b6c7-e7b32cd504e6

📥 Commits

Reviewing files that changed from the base of the PR and between 71a7856 and c4f421c.

📒 Files selected for processing (3)
  • test/e2e/live/mcp-bridge-hermes-lifecycle.ts
  • test/e2e/live/mcp-bridge-phases.ts
  • test/e2e/live/mcp-bridge.test.ts

@github-actions

github-actions Bot commented Jul 28, 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 match; 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, security-posture, mcp-bridge, mcp-bridge-dev

Workflow run details

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

Signed-off-by: Charan Jagwani <cjagwani@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.

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 `@scripts/managed-gateway-control.py`:
- Around line 1352-1362: Update _parse_locked_hermes_hash in
scripts/managed-gateway-control.py at lines 1352-1362 to raise ValueError
whenever a normal hash record is encountered after mcp_state_seen, enforcing
terminal MCP metadata ordering. Add state-first and state-between-records
fixtures in test/managed-gateway-control.test.ts at lines 44-51, asserting both
produce GATEWAY_CONFIG_HASH_MISMATCH.
🪄 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: a7fd23ff-fbea-429c-b29a-ee9799a67463

📥 Commits

Reviewing files that changed from the base of the PR and between 1f60079 and 855979c.

📒 Files selected for processing (3)
  • scripts/managed-gateway-control.py
  • test/e2e/live/mcp-bridge-hermes-lifecycle.ts
  • test/managed-gateway-control.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/live/mcp-bridge-hermes-lifecycle.ts

Comment thread scripts/managed-gateway-control.py
@apurvvkumaria
apurvvkumaria enabled auto-merge (squash) July 28, 2026 21:00
@copy-pr-bot

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

@cv
cv disabled auto-merge July 28, 2026 23:11
@cv
cv merged commit 125ca30 into main Jul 28, 2026
42 of 44 checks passed
@cv
cv deleted the codex/7499-hermes-mcp-integrity-restart-v2 branch July 28, 2026 23:11
@cjagwani cjagwani mentioned this pull request Jul 28, 2026
23 tasks
cv pushed a commit that referenced this pull request Jul 28, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Add the canonical dated changelog entry for NemoClaw v0.0.97 before the
release plan captures `origin/main`.
The entry groups the user-visible and maintainer-facing changes since
v0.0.96 while preserving the Deferred dual-Station status, experimental
runtime-identity boundary, and pending physical IGX validation.

## Changes

- Add `docs/changelog/2026-07-28.mdx` with the parser-safe MDX SPDX
comment and exact `## v0.0.97` heading.
- Summarize the 43 merged PRs in the release range, omitting
internal-only changes from the public entry and linking each grouped
change to its most specific published documentation.
- Keep the experimental Okta reference explicitly opt-in and outside
normal onboarding, keep the two-Station path Deferred, and state that
physical IGX Orin validation remains pending.

### Source summary

- [#7440](#7440),
[#7443](#7443), and
[#7445](#7445) ->
`docs/changelog/2026-07-28.mdx`: Document read-only host readiness
reports and fail-closed platform qualification.
- [#7030](#7030) ->
`docs/changelog/2026-07-28.mdx`: Document the Deferred trusted
two-Station vLLM evaluation.
- [#7265](#7265) ->
`docs/changelog/2026-07-28.mdx`: Document the bounded experimental
direct-runner Okta runtime-identity reference.
- [#7711](#7711) and
[#7648](#7648) ->
`docs/changelog/2026-07-28.mdx`: Document compatible-endpoint reasoning
effort and retired NVIDIA Build model paths.
- [#7746](#7746),
[#7763](#7763), and
[#7681](#7681) ->
`docs/changelog/2026-07-28.mdx`: Document safe compatible-provider
creation, replacement refusal, and narrow OpenShell bridge URL handling.
- [#7641](#7641),
[#7690](#7690),
[#7631](#7631), and
[#7710](#7710) ->
`docs/changelog/2026-07-28.mdx`: Document paused-container recovery,
recreation journaling, pre-mutation uninstall checks, and
source-checkout OpenShell selection.
- [#7624](#7624) and
[#7762](#7762) ->
`docs/changelog/2026-07-28.mdx`: Document Jetson release diagnostics and
bounded render-device group propagation.
- [#7639](#7639),
[#7760](#7760),
[#7721](#7721), and
[#7761](#7761) ->
`docs/changelog/2026-07-28.mdx`: Document Telegram, MCP media-type,
Hermes image-mode, and locked-restart fixes.
- [#7653](#7653) and
[#7680](#7680) ->
`docs/changelog/2026-07-28.mdx`: Document Deep Agents policy tasks and
the bounded Claude Code OAuth path.
- [#7679](#7679) ->
`docs/changelog/2026-07-28.mdx`: Document the checksum-bound libssh2 and
Python HTMLParser backports.
- [#7655](#7655),
[#7651](#7651),
[#7664](#7664),
[#7666](#7666),
[#7670](#7670),
[#7719](#7719), and
[#7741](#7741) ->
`docs/changelog/2026-07-28.mdx`: Document exact candidate E2E evidence,
Launchable selection, diagnostic consolidation, and trusted WSL
validation.

## 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 dated changelog contract,
MDX header, heading uniqueness, and release-entry structure.
- [ ] 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: The committed `docs/changelog/2026-07-28.mdx` blob exactly
matches the reviewed file. Completeness, factual accuracy, link shape,
parser-safe MDX header, one-sentence-per-line style, `.docs-skip`
compliance, and bounded product claims passed.
- Agent: Codex Desktop documentation writer subagent
<!-- docs-review-head-sha: da6aa27 -->
<!-- docs-review-agents-blob-sha: be20a09 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; this PR changes only the dated
changelog.
- 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 check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run
test/changelog-docs.test.ts` passed 6/6.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — not applicable to this doc-only release
entry.
- [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) —
completed with 0 errors and 2 pre-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 intentionally have no frontmatter.

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>


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

## Summary by CodeRabbit

* **New Features**
* Added improved host readiness reporting and Jetson onboarding
guidance.
* Added controls for reasoning effort with compatible endpoints and
enhanced managed MCP discovery.
  * Improved Deep Agents task publication and preset support.
* **Bug Fixes**
* Hardened provider switching, sandbox recovery, uninstall behavior, and
Telegram connectivity.
* Improved container image integrity checks, media-type handling, and
checksum validation.
  * Enhanced vLLM evaluation behavior and release diagnostics.
* **Documentation**
  * Added the NemoClaw v0.0.97 changelog.

<!-- 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: security Security controls, permissions, secrets, or hardening integration: hermes Hermes integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Managed Hermes MCP add can leave config hash stale and gateway unavailable

2 participants