Skip to content

fix(rebuild): keep Hermes MCP runtime active after rebuild - #8703

Merged
apurvvkumaria merged 4 commits into
mainfrom
codex/fix-8697-hermes-post-rebuild-tool-call
Aug 10, 2026
Merged

fix(rebuild): keep Hermes MCP runtime active after rebuild#8703
apurvvkumaria merged 4 commits into
mainfrom
codex/fix-8697-hermes-post-rebuild-tool-call

Conversation

@apurvvkumaria

@apurvvkumaria apurvvkumaria commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

This draft adds one-shot, credential-redacted diagnostics for the Hermes MCP request that fails immediately after a successful sandbox rebuild. The evidence distinguishes response status/body, result-token, and exact authenticated tools/call reachability failures without retrying the paid completion request. The remaining work will confirm the causal boundary and add the narrow rebuild fix before this draft is marked ready.

Related Issue

Fixes #8697

Changes

  • Send exactly one authenticated Hermes /v1/chat/completions probe and preserve its HTTP status plus a redacted, byte-limited failure body while keeping successful response contents out of artifacts.
  • Reuse the fixture's existing capture bound and common assertions to require one new authenticated fixture tools/call at the managed /mcp endpoint after an HTTP success.
  • Add focused coverage for one-request behavior, API-key redaction, HTTP 500 evidence, duplicate status markers, and result-token validation.
  • Keep the net diagnostic change to three files and 251 added lines, down from the initial 724-line draft.

Current root-cause hypothesis: the scenario's pre-existing 15-minute Shields auto-lock begins before rebuild, while the rebuild path treats both mutable-default and temporarily-unlocked postures as already down and does not capture the old timer generation. The recorded rebuild holds the lifecycle lock across the old deadline, so the timer waits; after rebuild releases that lock, overdue recovery can harden the replacement before the first tool-backed request even though config/hash and gateway-health checks passed. The new HTTP and runtime evidence will confirm whether that handoff also causes the HTTP 500 before the fix is committed.

Evidence Current observation Diagnostic added or remaining
Candidate 68129579827191770cfcf496715e4e272bc96129, GitHub Verified Reused as the exact failing candidate
Live run Run 31357091338, Hermes job 93361110199 Existing artifact confirms rebuild success followed by HTTP 500
Rebuild timing Existing Shields window predates an 883.8-second rebuild and expires 83–89 seconds before rebuild completion Capture the overdue timer handoff, final Shields posture, and runtime logs around the request
HTTP request Existing artifact contains only curl exit 22 and HTTP 500 Capture one status and redacted, bounded response body without retry
MCP fixture Pre-rebuild discovery succeeds; post-rebuild call reachability is absent from the artifact Require exactly one authenticated post-rebuild tools/call after HTTP success
Remaining implementation Causal boundary not yet fixed in this first commit Add the smallest timer/runtime fix, regression tests, final docs and security reviews, and exact-head live evidence

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: the net change only improves Hermes live-E2E diagnostics and assertions; it does not change a supported product or contributor contract.
  • 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: pending after the causal fix
  • 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 remaining change affects only Hermes live-E2E diagnostics and assertions; no supported CLI, API, configuration, default, or runtime contract changes.
  • 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 validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — npx vitest run --project e2e-support test/e2e/support/mcp-bridge-hermes-http.test.ts (2 tests passed)
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — pending the causal fix
  • 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: Apurv Kumaria akumaria@nvidia.com

Summary by CodeRabbit

  • Tests
    • Added end-to-end coverage for Hermes MCP HTTP requests.
    • Added validation for authentication, HTTP status handling, result tokens, retries, redaction, and truncated failure output.
    • Improved adapter tool-call testing with bounded response capture and specialized validation.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria apurvvkumaria self-assigned this Aug 10, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds Hermes MCP HTTP probe helpers, integrates them into live adapter tests, and adds coverage for authenticated requests, bounded redacted failures, HTTP status validation, and result-token validation.

Changes

Hermes MCP HTTP handling

Layer / File(s) Summary
Probe generation and response validation
test/e2e/live/mcp-bridge-hermes-http.ts
The helper builds authenticated Hermes requests, limits captured output, redacts failure bodies, parses HTTP status markers, and validates result tokens.
Hermes adapter integration
test/e2e/live/mcp-bridge.test.ts
The Hermes test uses the shared probe, expanded redaction values, bounded capture, and Hermes-specific response assertions. Other adapters retain their existing checks.
Probe behavior coverage
test/e2e/support/mcp-bridge-hermes-http.test.ts
Mocked curl tests verify single-request behavior, authentication, redaction, truncated HTTP 500 diagnostics, marker validation, and result-token handling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LiveTest as Hermes live test
  participant Probe as Hermes HTTP probe
  participant Gateway as Hermes gateway
  participant Fixture as MCP fixture
  LiveTest->>Probe: Build payload and expected result-token probe
  Probe->>Gateway: Send one authenticated chat request
  Gateway->>Fixture: Invoke MCP tool
  Fixture-->>Gateway: Return tool result
  Gateway-->>Probe: Return HTTP status and response body
  Probe-->>LiveTest: Return bounded command result
  LiveTest->>Probe: Validate status, redaction, and result token
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#8659 — Extends and tests the same Hermes MCP HTTP probe, response validation, redaction, and adapter integration.

Suggested labels: integration: hermes, area: sandbox, bug-fix

Suggested reviewers: prekshivyas, cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes add bounded redacted diagnostics and focused tests, but do not fix or prove the post-rebuild HTTP 500 acceptance criteria in issue #8697. Implement the causal Hermes runtime fix and verify the first post-rebuild request, single authenticated tools/call, fail-closed behavior, logs, cleanup, and regression coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title identifies the Hermes rebuild runtime issue addressed by the diagnostics and post-rebuild validation changes.
Out of Scope Changes check ✅ Passed The changes are limited to Hermes MCP diagnostic helpers and focused end-to-end tests described by issue #8697.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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/fix-8697-hermes-post-rebuild-tool-call

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

@github-code-quality

github-code-quality Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 0bf6625 in the codex/fix-8697-herme... branch remains at 96%, unchanged from commit fa2b577 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 0bf6625 in the codex/fix-8697-herme... branch remains at 82%, unchanged from commit fa2b577 in the main branch.

Show a code coverage summary of the most impacted files.
File main fa2b577 codex/fix-8697-herme... 0bf6625 +/-
src/lib/policy/index.ts 67% 67% 0%
src/lib/inferen...ter-topology.ts 89% 89% 0%
src/lib/inferen...og-integrity.ts 100% 100% 0%
src/lib/inferen...ter-registry.ts 95% 96% +1%
src/lib/inferen...-ssh-binding.ts 87% 89% +2%
src/lib/policy/...y-validation.ts 97% 100% +3%
src/lib/inferen...talog-loader.ts 80% 84% +4%
src/lib/inferen...er-lifecycle.ts 70% 77% +7%
src/lib/inferen...del-registry.ts 93% 100% +7%
src/lib/inferen...time-context.ts 84% 93% +9%

Updated August 10, 2026 07:38 UTC

@github-actions

github-actions Bot commented Aug 10, 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 terminology decisions differ; normalized E2E selections differ; severity counts match.
3 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • status marker at test/e2e/live/mcp-bridge-hermes-http.ts:88: selected only by the second-opinion lane as define.
  • result token at test/e2e/live/mcp-bridge-hermes-http.ts:97: selected only by the second-opinion lane as define.
  • failure preview at test/e2e/live/mcp-bridge.test.ts:547: selected only by the second-opinion lane as define.
2 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • rebuild-hermes: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • rebuild-hermes-stale-base: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — real MCP tool call at test/e2e/live/mcp-bridge-hermes-http.ts:85: Keep the established term for agent-driven MCP tool invocation.
  • justified — HTTP status marker at test/e2e/live/mcp-bridge-hermes-http.ts:88: Keep this term because it identifies the status record that the assertion validates.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

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.

@apurvvkumaria
apurvvkumaria marked this pull request as ready for review August 10, 2026 07:22

@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 (2)
test/e2e/support/mcp-bridge-hermes-http.test.ts (2)

35-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove source-text assertions.

The fake curl at Lines 54-57 and the count assertion at Line 87 already verify authentication and one request through the shell boundary. Remove these generated-script text checks.

Proposed change
-    expect(script.match(/\bcurl "\$@"/gu)).toHaveLength(1);
-    expect(script).not.toMatch(/\bretry\b/iu);
-    expect(script).toContain("Authorization: Bearer ${API_SERVER_KEY}");

As per path instructions, prefer observable outcomes through the public boundary over source-text 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/e2e/support/mcp-bridge-hermes-http.test.ts` around lines 35 - 37, Remove
the generated-script source-text assertions in the affected test, including the
script.match count, retry absence, and Authorization string checks. Retain the
fake curl boundary setup and the existing request-count assertion, which already
verify authentication and a single request through observable behavior.

Source: Path instructions


109-120: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test duplicate result-token rejection.

hasResultToken requires exactly one NEMOCLAW_HERMES_MCP_RESULT_TOKEN=present marker. Add a case with two present markers and assert that assertHermesMcpHttpResponse throws. This protects the single-marker protocol rule.

🤖 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/support/mcp-bridge-hermes-http.test.ts` around lines 109 - 120, Add
a test beside the existing result-token assertions that passes two
NEMOCLAW_HERMES_MCP_RESULT_TOKEN=present markers to assertHermesMcpHttpResponse
and verifies it throws for violating the exactly-one-marker protocol rule.

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/support/mcp-bridge-hermes-http.test.ts`:
- Around line 35-37: Remove the generated-script source-text assertions in the
affected test, including the script.match count, retry absence, and
Authorization string checks. Retain the fake curl boundary setup and the
existing request-count assertion, which already verify authentication and a
single request through observable behavior.
- Around line 109-120: Add a test beside the existing result-token assertions
that passes two NEMOCLAW_HERMES_MCP_RESULT_TOKEN=present markers to
assertHermesMcpHttpResponse and verifies it throws for violating the
exactly-one-marker protocol rule.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 00d981ea-6284-435c-80d5-561bf3ef3016

📥 Commits

Reviewing files that changed from the base of the PR and between 04e28aa and 2793ab4.

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

@apurvvkumaria
apurvvkumaria enabled auto-merge (squash) August 10, 2026 07:24
@apurvvkumaria
apurvvkumaria merged commit 07d57ed into main Aug 10, 2026
51 checks passed
@apurvvkumaria
apurvvkumaria deleted the codex/fix-8697-hermes-post-rebuild-tool-call branch August 10, 2026 07:38
apurvvkumaria added a commit that referenced this pull request Aug 10, 2026
<!-- markdownlint-disable MD041 -->
## Summary

A long Hermes rebuild can outlive an inherited Shields auto-restore
timer. NemoClaw now settles an expired deferred timer through the
existing fenced Shields-up path before reporting rebuild success, which
prevents lockdown from racing the first post-rebuild tool call.

The live E2E lane now records bounded, redacted HTTP, runtime, fixture,
Shields, and cleanup evidence for this boundary.

## Related Issue

Fixes #8697

## Changes

- Restrict the production change to rebuild windows that defer automatic
Shields restoration while the lifecycle owner is alive. If that timer
expires during rebuild, the existing Shields-up operation settles the
timer before rebuild returns success.
- Preserve ordinary backup behavior when the sandbox already had Shields
down.
- Record gateway process identity before rebuild and after MCP
restoration.
- Record post-rebuild fixture requests without credentials or request
bodies. The record includes only the authentication result, method,
path, response status, and result presence.
- Capture bounded Hermes logs, filesystem permissions,
managed-supervisor status, gateway identity, and Shields status.
Existing artifact redaction removes known credentials.
- Lower Shields before MCP and sandbox cleanup. The cleanup registry
uses last-in, first-out order, so evidence capture runs first,
Shields-down runs second, and older cleanup operations run afterward.

### Confirmed evidence

- Merged PR #8703 added bounded HTTP failure diagnostics for #8697.
- Trusted-main run `31364512126`, Hermes job `93380168425`, completed
rebuild in 845,292 ms.
- The first post-rebuild request returned HTTP 500 in 295 ms with
`Permission denied: '/sandbox/.hermes/logs'`.
- The inherited Shields timer deadline had elapsed while rebuild held
the lifecycle lock. The detached timer applied lockdown when the lock
became available.
- The failed run predates the fixture-request ledger in this PR. Its
failure location indicates that the request ended before the MCP
fixture, but the artifact does not directly record that result.

### Root cause and correction

The failure was not stale MCP configuration or credential rotation. The
overdue Shields timer made `/sandbox/.hermes` read-only immediately
after rebuild released its lifecycle lock. Rebuild now settles that
timer with the existing fenced Shields-up state transition before it
reports success.

### Remaining validation

- Run the canonical trusted `mcp-bridge (hermes)` lane on the exact PR
commit.
- Confirm the first post-rebuild request returns
`MCP_AUTH_REWRITE_OK::nemoclaw-authenticated-mcp-proof`.
- Confirm the fixture records exactly one authenticated `tools/call`
with the rotated provider credential.
- Confirm the final evidence records the expected gateway identities,
Shields state, redaction, and cleanup result.

## Type of Change

- [x] 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

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: The change corrects an
internal timer-settlement race and adds test evidence. It does not
change a command, option, configuration, output contract, or recovery
procedure.
- [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 Codex
security review covered all nine repository categories and found no
actionable finding. The trusted-main live E2E run remains pending.
- [ ] 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: `no-docs-needed`
- Evidence: Existing rebuild documentation already states that the
detached auto-lock timer remains authoritative until rebuild commits a
successful Shields-up state. `docs/` is unchanged.
- Agent: Codex Desktop
<!-- docs-review-head-sha: d5d0788 -->
<!-- docs-review-agents-blob-sha: c4923a3 -->

## DGX Station Hardware Evidence

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

## 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: 8
timer tests, 63 rebuild/reconciliation tests, 88 Hermes
transaction/convergence/integrity tests, 13 E2E support tests, and 2
bounded HTTP diagnostic tests passed. `npm run typecheck:cli` and `npx
prek run --from-ref origin/main --to-ref HEAD` passed.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable. The diff
changes one lifecycle decision and focused live evidence.
- [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)
- [ ] 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: Apurv Kumaria <akumaria@nvidia.com>


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

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed backup protection windows that could remain unlocked after their
automatic restore timer expired.
* Rebuilding protection settings now correctly settles expired timers
and reapplies lockdown when required.

* **Tests**
* Expanded coverage for timer expiration, relocking behavior, and
rebuild workflows.
* Improved diagnostics captured during runtime and gateway lifecycle
testing, with sensitive values redacted.

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

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@wscurran wscurran added chore Build, CI, dependency, or tooling maintenance area: e2e End-to-end tests, nightly failures, or validation infrastructure area: observability Logging, metrics, tracing, diagnostics, or debug output integration: hermes Hermes integration behavior labels Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: e2e End-to-end tests, nightly failures, or validation infrastructure area: observability Logging, metrics, tracing, diagnostics, or debug output chore Build, CI, dependency, or tooling maintenance integration: hermes Hermes integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hermes MCP rebuild reports verified on OpenShell v0.0.101 but first provider-backed tool call returns HTTP 500

3 participants