Skip to content

fix(sandbox): add host-mediated gateway restart#5874

Merged
jyaunches merged 80 commits into
mainfrom
fix/issue-2426-gateway-restart
Jun 30, 2026
Merged

fix(sandbox): add host-mediated gateway restart#5874
jyaunches merged 80 commits into
mainfrom
fix/issue-2426-gateway-restart

Conversation

@ericksoa

@ericksoa ericksoa commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a supported host-mediated gateway restart command for NemoClaw-managed OpenClaw and Hermes gateways and routes automatic recovery through the same topology-specific authenticated controller or supervisor path. The lifecycle acts only on proven process and listener identity, applies configuration and state changes transactionally, and fails closed when privileged execution or built-in health probes are ambiguous.

Related Issue

Fixes #2426
Fixes #5253
Supersedes #5416

Changes

  • Added sandbox:gateway:restart plus public nemoclaw <name> gateway restart and nemohermes <name> gateway restart routing while keeping healthy recover idempotent.
  • Added managed gateway control for both supported topologies: a root PID 1 request channel for direct-root entrypoints and an authenticated root-owned controller paired with the nonroot supervisor in OpenShell-managed sandboxes.
  • Enforced exact PID and process-start identity checks, listener ownership validation, post-stop absence proof, exact reaping or respawn proof, health waits, and port-forward recovery.
  • Added descriptor-based, no-follow, atomic configuration and state guards, including bounded Hermes secret-boundary and configuration-hash validation.
  • Serialized shields mutations and recovery timers, and ordered snapshot, destroy, and inference transitions so stale callbacks cannot reapply state.
  • Made built-in OpenClaw and Hermes probes fail closed after trusted execution failure or timeout; unsupported privileged-exec drivers and ambiguous container selection are rejected while explicit custom gateway agents retain their compatibility path.
  • Wired runtime helpers into optimized build contexts with root-owned, non-writable permissions and preserved root PID 1 access to mutable sandbox-group state when hardened runtimes drop CAP_DAC_OVERRIDE.
  • Published a Trusted Computing Base page in both guide variants covering the direct-root and OpenShell-managed boundaries, shared-UID and mutable-config limits, JSON5 read compatibility, root group membership, and compatibility-removal conditions.
  • Restricted managed-controller procfs and filesystem overrides to source execution with the explicit test flag, and verified the pinned Node/JSON5 installation is root-owned and non-writable.
  • Added final-image proof for both built-in images covering root-only helper modes, required supplementary groups, root probe access, and sandbox-user refusal; made sandbox-operations assertions topology-aware for direct-root and OpenShell-managed runs.
  • Excluded authenticated, exact-identity Hermes controller replacements from crash quarantine with a root-only 0600 lifecycle lock and root-owned 0444 authorization bound to the live root controller; all orphaned, mismatched, unexpected, and failed replacement exits still count.
  • Tightened the OpenClaw image health fallback to read the tracked PID start identity before and after an exact installed gateway command line, while retaining known rewritten process-title compatibility.
  • Preserved the injected managed supervisor through the post-restart settle probe and locked the built-in completion protocol to GATEWAY_PID= rather than accepting the legacy custom-script ALREADY_RUNNING marker.
  • Migrated the branch's live recovery coverage onto the typed E2E workflow and removed the legacy shell lanes deleted on main.
  • Updated lifecycle, runtime-control, command, troubleshooting, security, and Hermes documentation.
  • Review scope: the existing OpenShell bridge-host allowance is preserved while adjacent private or internal endpoint shapes are DNS-validated and rejected. Broad module splitting and consumer-wide HTTPS binding remain separate architecture work rather than widening this security-sensitive recovery fix.

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: Independent security review found no blocking findings across privilege, process identity, filesystem, network, fail-closed, and regression-coverage boundaries; human security acceptance remains pending and required before merge.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push, or npx prek run --from-ref main --to-ref HEAD passes
  • Targeted tests pass for changed behavior
  • Full npm test passes (broad runtime changes only)
  • 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)

Exact-head evidence for 8dbe420d3d835546683cbfa67fec0537791ad7c1:

  • Signed, DCO-compliant commit d86c60c325a3dbc74fc42f74447bc00f89be4400 addresses the current CodeRabbit correctness and documentation findings. Signed merge commit c9061c68fd82b1b73044383bc4e8962808644744 incorporates main at e10462ff3e2e0727350a2532fc7bb7edc64116b2 without rebasing or rewriting the verified history. Signed cleanup commit 8dbe420d3d835546683cbfa67fec0537791ad7c1 addresses the resulting CodeQL/code-quality diagnostics.
  • Post-merge controller, trust-contract, provisioning, managed-exit authorization, OpenClaw/Hermes config-guard, state-dir guard, endpoint-security, restart/boundary, and workflow-boundary suites pass: 15 files, 258 tests.
  • npm run build:cli, npm run typecheck:cli, Biome, ShellCheck, Python compilation, branch diff checks, test-size/project/title guards, and npm run docs:check-agent-variants pass.
  • npm run docs completes with 0 errors and two existing Fern warnings; the warning-free checkbox remains unchecked.
  • All 80 PR commits appear as GitHub Verified; all three new commits contain the DCO sign-off declaration.
  • The review-fix commit's normal formatting, lint, repository, secret-scan, commitlint, source-shape, and test-size hooks pass. The normal pre-push CLI typecheck and version-sync hooks pass. The full local test-cli hook and full-npm test boxes remain unchecked; exact-head CI is required for those broader platform lanes.
  • Standard CI, automated current-head review, human security acceptance, and exact-head E2E evidence are pending on this head and must settle before merge.

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

Summary by CodeRabbit

  • New Features

    • Added a gateway restart command for sandboxes with forced reload and post-restart health/forward verification.
  • Bug Fixes

    • Improved recovery so host forwards and supervised gateway processes are repaired more reliably.
    • Strengthened failure handling to be fail-closed when required Hermes secret-boundary validation or supervisor control is unavailable.
    • Corrected forward-health classification so stopped/occupied forwards are handled consistently.
  • Documentation

    • Expanded lifecycle, runtime-controls, command reference, and troubleshooting guidance for recover, gateway restart, shields windows, and Hermes recovery constraints.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa self-assigned this Jun 26, 2026
@coderabbitai

coderabbitai Bot commented Jun 26, 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 02212e51-5c4f-4e9a-ae25-a31832082a1e

📥 Commits

Reviewing files that changed from the base of the PR and between e09c253 and 8dbe420.

📒 Files selected for processing (21)
  • Dockerfile
  • agents/hermes/start.sh
  • docs/manage-sandboxes/lifecycle.mdx
  • docs/manage-sandboxes/runtime-controls.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/security/openshell-0.0.71-gateway-auth-review.mdx
  • docs/security/tcb-boundary.mdx
  • scripts/managed-gateway-control.py
  • scripts/nemoclaw-start.sh
  • src/lib/actions/inference-set.test.ts
  • src/lib/actions/sandbox/gateway-restart.test.ts
  • src/lib/actions/sandbox/hermes-secret-boundary-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/onboard/docker-driver-gateway-config-auth-contract.test.ts
  • test/hermes-gateway-supervisor-recovery.test.ts
  • test/hermes-managed-exit-authorization.test.ts
  • test/managed-gateway-control.test.ts
  • test/nemoclaw-start-gateway-health.test.ts
  • test/nemoclaw-start.test.ts
  • test/sandbox-provisioning.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/security/tcb-boundary.mdx
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/lib/actions/sandbox/hermes-secret-boundary-recovery.test.ts
  • docs/security/openshell-0.0.71-gateway-auth-review.mdx
  • docs/manage-sandboxes/lifecycle.mdx
  • src/lib/actions/inference-set.test.ts
  • Dockerfile
  • src/lib/actions/sandbox/gateway-restart.test.ts
  • docs/manage-sandboxes/runtime-controls.mdx
  • docs/reference/commands.mdx
  • docs/reference/commands-nemohermes.mdx
  • src/lib/actions/sandbox/process-recovery.ts
  • agents/hermes/start.sh

📝 Walkthrough

Walkthrough

Adds a host-mediated gateway restart path, PID-identity-based gateway supervision, descriptor-safe state/config guards, timer-bound shields locking, and updated docs/tests for the new restart, recovery, and mutation flows.

Changes

Gateway lifecycle and shields flow

Layer / File(s) Summary
Supervisor control and image wiring
scripts/gateway-control.sh, scripts/lib/gateway-supervisor.sh, scripts/managed-gateway-control.py, Dockerfile, agents/hermes/Dockerfile, Dockerfile.base, src/lib/sandbox/build-context.ts, test/hermes-doctor-config-hash.test.ts
Adds the host request/status protocol, PID 1 supervisor library, managed OpenShell gateway controller, and image/build-context wiring for the new scripts and hardened preloads.
Identity supervision in start scripts
scripts/nemoclaw-start.sh, agents/hermes/start.sh
Tracks process start identities in both sandbox start scripts, hardens forwarders/watchdogs/restarts around identity checks, and routes Hermes startup/recovery through the new supervisor path.
State, config, and timer guards
scripts/state-dir-guard.py, agents/hermes/validate-env-secret-boundary.py, src/lib/shields/state-dir-lock.ts, src/lib/shields/openclaw-config-lock.ts, src/lib/shields/timer-control.ts, src/lib/shields/timer.ts, src/lib/shields/timer-bound-lock.ts, src/lib/shields/index.ts, related tests
Adds descriptor-safe state-dir/config guards, timer-bound mutation locking, Hermes sealed/legacy protocol handling, and shields transition/auto-restore changes.
Gateway restart, recovery, and forward repair
src/lib/agent/gateway-restart-*.ts, src/lib/agent/gateway-script-shared.ts, src/lib/agent/runtime.ts, src/lib/actions/sandbox/gateway-restart.ts, src/lib/actions/sandbox/process-recovery.ts, src/lib/actions/sandbox/forward-health.ts, src/lib/actions/sandbox/forward-recovery.ts, src/lib/actions/sandbox/hermes-dashboard-recovery.ts, src/lib/actions/sandbox/hermes-secret-boundary-recovery.ts, src/lib/actions/sandbox/connect.ts, related tests
Adds the managed gateway restart action, shared gateway shell helpers, running-only forward classification, dashboard/messaging/declared forward repair, and updated Hermes secret-boundary enforcement.
Config, inference, destroy, snapshot, and privilege boundaries
src/commands/sandbox/gateway/restart.ts, src/commands/sandbox/recover.ts, src/lib/sandbox/config.ts, src/lib/sandbox/privileged-exec.ts, src/lib/actions/inference-set.ts, src/lib/actions/sandbox/destroy.ts, src/lib/actions/sandbox/snapshot.ts, src/lib/actions/sandbox/rebuild-shields.ts, src/lib/agent/defs.ts, src/lib/agent/onboard.ts, src/lib/cli/public-display-defaults.ts, related tests
Hardens config writes and restart guidance, inference URL validation, destroy/snapshot/rebuild flows, privileged exec discovery, and agent port validation.
Docs, release notes, and tooling
docs/manage-sandboxes/*, docs/reference/*, docs/security/*, docs/about/release-notes.mdx, docs/index.yml, ci/env-var-doc-allowlist.json, scripts/checks/no-test-dist-imports.ts
Updates user-facing docs, security references, release notes, the env-var allowlist, and the dist-import static analysis script to match the new lifecycle and restart behavior.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~180 minutes

Possibly related issues

Possibly related PRs

  • NVIDIA/NemoClaw#1633: Builds on the OpenClaw runtime override flow that this PR now gates behind shields and digest-bound config writes.
  • NVIDIA/NemoClaw#4771: Directly related Hermes secret-boundary enforcement work that this PR extends with supervisor-mediated recovery and stricter refusal paths.
  • NVIDIA/NemoClaw#4811: Overlaps in Hermes image/startup and dashboard forward wiring, which this PR further hardens for restart and recovery.

Suggested labels

platform: ubuntu

Suggested reviewers

  • jyaunches
  • brandonpelfrey
  • cv
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title is concise and accurately reflects the main change: adding a host-mediated gateway restart path.
Linked Issues check ✅ Passed Implements host-mediated Hermes restart/recovery and preload safety checks, satisfying #2426 and #5253.
Out of Scope Changes check ✅ Passed The changes stay centered on gateway restart/recovery, safety boundaries, and supporting docs/tests; no clear unrelated scope is present.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-2426-gateway-restart

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

@github-code-quality

github-code-quality Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the branch is 96%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File 8dbe420 +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/li...bprocess-env.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/bl...print/runner.ts 95%
nemoclaw/src/co...ration-state.ts 94%
nemoclaw/src/bl...ate-networks.ts 94%
nemoclaw/src/index.ts 94%

TypeScript / code-coverage/cli

The overall coverage in the branch is 68%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File 8dbe420 +/-
src/lib/shields...nsition-lock.ts 86%
src/lib/actions...dbox/rebuild.ts 80%
src/lib/actions...all/run-plan.ts 80%
src/lib/state/o...oard-session.ts 79%
src/lib/state/sandbox.ts 72%
src/lib/onboard/preflight.ts 69%
src/lib/shields/index.ts 67%
src/lib/onboard...er-gpu-patch.ts 59%
src/lib/actions...licy-channel.ts 58%
src/lib/onboard.ts 20%

Updated June 30, 2026 18:34 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

Copy link
Copy Markdown
Contributor

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

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: test-e2e-sandbox, test-e2e-gateway-isolation, test-non-root-sandbox-smoke, hermes-root-entrypoint-smoke, hermes-sandbox-secret-boundary, hermes-e2e, hermes-inference-switch, gateway-guard-recovery, sandbox-operations, sandbox-rebuild, rebuild-openclaw, rebuild-hermes, shields-config, inference-routing, openclaw-inference-switch, network-policy, cloud-onboard, full-e2e, onboard-repair, snapshot-commands
Optional E2E: onboard-resume, credential-sanitization, state-backup-restore, gateway-health-honest, runtime-overrides

Dispatch hint: hermes-root-entrypoint-smoke,hermes-sandbox-secret-boundary,hermes-e2e,hermes-inference-switch,gateway-guard-recovery,sandbox-operations,sandbox-rebuild,rebuild-openclaw,rebuild-hermes,shields-config,inference-routing,openclaw-inference-switch,network-policy,cloud-onboard,full-e2e,onboard-repair,snapshot-commands

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • test-e2e-sandbox (medium): Builds the modified production sandbox image and runs the in-image sandbox E2E suite against filesystem, runtime, and lifecycle assumptions changed by the Dockerfiles and guard scripts.
  • test-e2e-gateway-isolation (medium): Required because gateway-control, gateway-supervisor, managed controller, PID/health logic, and gateway isolation boundaries changed.
  • test-non-root-sandbox-smoke (low): Required for the root/gateway/sandbox group-membership and non-root compatibility changes in Dockerfile and Dockerfile.base.
  • hermes-root-entrypoint-smoke (medium): Hermes Dockerfile/start/runtime guard changes alter PID 1 startup, readiness, config sealing, root-owned helpers, and lifecycle behavior.
  • hermes-sandbox-secret-boundary (medium): Required because Hermes secret-boundary validation, runtime guard, Dockerfile permissions, and recovery paths were changed.
  • hermes-e2e (high): End-to-end Hermes onboarding and assistant flow is required because Hermes startup, config, gateway lifecycle, and inference path changed.
  • hermes-inference-switch (high): Required for changes to inference-set logic and Hermes runtime config mutation paths that can affect live provider switching.
  • gateway-guard-recovery (high): Required because gateway guard recovery, supervisor control, marker/PID recording, and process recovery code changed.
  • sandbox-operations (high): Connect, destroy, recover, config set, forward health, and lifecycle command paths changed and need real sandbox operation coverage.
  • sandbox-rebuild (high): Required because build context, rebuild shields, Dockerfile layers, and sandbox rebuild tests were modified.
  • rebuild-openclaw (high): OpenClaw production image layering, config guard, shields, rebuild recovery, and stale-base compatibility changed.
  • rebuild-hermes (high): Hermes Dockerfile, runtime config guard, restart seal, and Hermes rebuild/state transition paths changed.
  • shields-config (high): Required for changes to shields locks, timer-bound locks, transition locks, config locks, and state-dir/openclaw-config guards.
  • inference-routing (high): Inference endpoint set/security code and routing repair tests changed; live routing validation is required.
  • openclaw-inference-switch (high): Required because inference-set and route swap repair changes can affect OpenClaw live provider switching.
  • network-policy (high): Security boundary, proxy, SSRF, privileged exec, and config-set changes can affect egress allow/deny and policy enforcement.
  • cloud-onboard (high): Required for full hosted onboarding confidence because onboarding-adjacent agent, Docker-driver gateway config/auth, image build, and deployment behavior changed.
  • full-e2e (high): Required end-user install/onboard/sandbox/assistant proof for broad runtime, gateway, inference, and lifecycle changes.
  • onboard-repair (high): Required because sandbox recover, markerless/process recovery, rebuild shields, and gateway repair paths changed.
  • snapshot-commands (high): Snapshot action code and backup/restore-facing behavior changed; live snapshot command coverage is required.

Optional E2E

  • onboard-resume (medium): Useful adjacent coverage for disrupted onboarding/recovery, but the strict onboarding resume rule does not appear to be triggered because src/lib/onboard/machine state-machine code was not changed.
  • credential-sanitization (high): Useful because secret-boundary and sandbox state protections changed, but Hermes/OpenClaw boundary-specific required jobs carry the main merge-blocking coverage.
  • state-backup-restore (high): Optional confidence for snapshot/state-dir changes and backup/restore documentation updates.
  • gateway-health-honest (medium): Optional targeted regression for gateway health reporting; relevant to healthcheck/PID changes but less direct than gateway-guard-recovery and gateway-isolation.
  • runtime-overrides (medium): Optional confidence for runtime config/env handling after substantial guard and startup changes.

New E2E recommendations

  • Hermes managed gateway restart and config mutation (high): The PR adds substantial root-owned Hermes runtime-config-guard, managed-gateway-control, readiness, restart-seal, and state transition logic. Existing live tests cover smoke and secret boundaries, but there is no clearly dedicated live E2E that performs a Hermes gateway restart/config mutation through the managed control path and verifies post-restart assistant/dashboard availability.
    • Suggested test: hermes-managed-gateway-restart-recovery-e2e
  • Docker healthcheck PID identity hardening (medium): The Dockerfile healthcheck now validates gateway pid and starttime to avoid PID reuse/false health. Existing gateway health and isolation tests do not appear to exercise Docker HEALTHCHECK behavior under PID reuse or stale pid-file conditions.
    • Suggested test: docker-healthcheck-gateway-pid-identity-e2e

Dispatch hint

  • Workflow: e2e.yaml
  • jobs input: hermes-root-entrypoint-smoke,hermes-sandbox-secret-boundary,hermes-e2e,hermes-inference-switch,gateway-guard-recovery,sandbox-operations,sandbox-rebuild,rebuild-openclaw,rebuild-hermes,shields-config,inference-routing,openclaw-inference-switch,network-policy,cloud-onboard,full-e2e,onboard-repair,snapshot-commands

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.

Actionable comments posted: 4

🧹 Nitpick comments (2)
docs/manage-sandboxes/runtime-controls.mdx (1)

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

Use $$nemoclaw on this shared page.

These Hermes-only references hard-code nemohermes for a host command that also exists on the shared alias surface. Use $$nemoclaw here so the generated OpenClaw and Hermes variants render the correct command name consistently.
As per coding guidelines, Use $$nemoclaw for host CLI command examples on shared OpenClaw and Hermes pages. As per path instructions, ask the author to use $$nemoclaw instead so generated OpenClaw and Hermes docs render the right command name. Based on learnings, use a concrete alias only when the command is intentionally OpenClaw-specific.

Also applies to: 70-70

🤖 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 `@docs/manage-sandboxes/runtime-controls.mdx` at line 60, The runtime-controls
table currently hard-codes the host command as nemohermes on a shared
OpenClaw/Hermes page, which should instead use the shared alias surface. Update
the affected entry in the docs content that references the gateway restart
command to use $$nemoclaw so both generated variants render the correct host CLI
name consistently, and apply the same fix to the other referenced occurrence in
this section.

Sources: Coding guidelines, Path instructions, Learnings

docs/reference/commands.mdx (1)

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

Use $$nemoclaw in the shared reference page.

This note is on a shared docs page, and gateway restart is not Hermes-only. Hard-coding nemohermes here breaks the variant-friendly command style used elsewhere in this page.
As per coding guidelines, Use $$nemoclaw for host CLI command examples on shared OpenClaw and Hermes pages. As per path instructions, ask the author to use $$nemoclaw instead so generated OpenClaw and Hermes docs render the right command name. Based on learnings, concrete aliases are fine when the command is intentionally agent-specific, which is not the case here.

🤖 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 `@docs/reference/commands.mdx` at line 1334, Replace the hard-coded Hermes CLI
name in the shared docs example with the shared host-command placeholder used
elsewhere on this page. Update the command example in the reference docs so it
uses $$nemoclaw instead of nemohermes, keeping the wording variant-friendly for
both OpenClaw and Hermes and preserving the existing gateway restart guidance.

Sources: Coding guidelines, Path instructions, Learnings

🤖 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 `@src/lib/actions/sandbox/process-recovery.test.ts`:
- Around line 295-299: The test is reading failure-only fields from
`restartSandboxGateway` without narrowing the union first, so `result.detail` is
not type-safe after `toMatchObject`. Update the assertion in
`process-recovery.test.ts` to explicitly narrow on `result.ok` for the failure
branch before accessing `detail`, while keeping the existing
`restartSandboxGateway` and `deps.buildOpenClawGatewayRestartScript`
expectations intact.

In `@src/lib/actions/sandbox/process-recovery.ts`:
- Around line 617-624: The success log in process recovery is not honoring
quiet, so `process-recovery.ts` still prints the gateway restart message
unconditionally. Update the `processRecovery` restart path around the
`forwardRecovered` checks so the final `console.log` for “Gateway restarted;
health passed; forwards checked/recovered” only runs when `quiet` is false,
matching the existing quiet handling used for the earlier status messages.
- Around line 593-599: The wedge diagnostics path is bypassing the injected exec
behavior by passing the direct sandbox exec helper instead of the dependency
override. In the process-recovery flow that calls waitForRecoveredSandboxGateway
and printGatewayWedgeDiagnostics, make sure the diagnostics invocation uses
deps.executeSandboxExecCommand when present (falling back to the default helper
only if not injected) so callers can fully control exec behavior during
health-timeout recovery.

In `@src/lib/agent/runtime.ts`:
- Around line 282-291: In buildOpenClawGatewayRestartScript and the
gatewayRootGosuLaunchCommand flow, move the root check ahead of any
state-mutating restart steps so OpenClaw verifies root before log setup, lock
removal, or stale-process termination. Use the existing root-check logic from
gatewayRootGosuLaunchCommand and ensure the non-root path exits before
buildGatewayLogSetup, buildGatewayGuardRecoveryLines, rm -rf lock cleanup, and
buildGatewayStopLines are executed.

---

Nitpick comments:
In `@docs/manage-sandboxes/runtime-controls.mdx`:
- Line 60: The runtime-controls table currently hard-codes the host command as
nemohermes on a shared OpenClaw/Hermes page, which should instead use the shared
alias surface. Update the affected entry in the docs content that references the
gateway restart command to use $$nemoclaw so both generated variants render the
correct host CLI name consistently, and apply the same fix to the other
referenced occurrence in this section.

In `@docs/reference/commands.mdx`:
- Line 1334: Replace the hard-coded Hermes CLI name in the shared docs example
with the shared host-command placeholder used elsewhere on this page. Update the
command example in the reference docs so it uses $$nemoclaw instead of
nemohermes, keeping the wording variant-friendly for both OpenClaw and Hermes
and preserving the existing gateway restart guidance.
🪄 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: 4573e314-45ce-43a2-b097-901ac1580774

📥 Commits

Reviewing files that changed from the base of the PR and between 84ffec1 and 13d407f.

📒 Files selected for processing (17)
  • agents/hermes/Dockerfile
  • docs/manage-sandboxes/install-plugins-hermes.mdx
  • docs/manage-sandboxes/lifecycle.mdx
  • docs/manage-sandboxes/runtime-controls.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • src/commands/sandbox/gateway/restart.ts
  • src/commands/sandbox/oclif-command-adapters.test.ts
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/agent/runtime.test.ts
  • src/lib/agent/runtime.ts
  • src/lib/cli/command-registry.test.ts
  • src/lib/cli/public-argv-translation.test.ts
  • src/lib/cli/public-display-defaults.ts
  • test/hermes-doctor-config-hash.test.ts

Comment thread src/lib/actions/sandbox/process-recovery.test.ts Outdated
Comment thread src/lib/actions/sandbox/process-recovery.ts Outdated
Comment thread src/lib/actions/sandbox/process-recovery.ts Outdated
Comment thread src/lib/agent/runtime.ts Outdated
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: gateway-guard-recovery, hermes-dashboard-vitest, hermes-inference-switch-vitest, hermes-sandbox-secret-boundary-vitest, sandbox-operations-vitest, sandbox-rebuild-vitest
Optional Vitest E2E scenarios: rebuild-hermes-vitest, shields-config-vitest, gateway-health-honest-vitest

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=gateway-guard-recovery
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-dashboard-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-inference-switch-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-sandbox-secret-boundary-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=sandbox-operations-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=sandbox-rebuild-vitest

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • gateway-guard-recovery: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/gateway-guard-recovery.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=gateway-guard-recovery
  • hermes-dashboard-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/hermes-e2e.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-dashboard-vitest
  • hermes-inference-switch-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/hermes-inference-switch.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-inference-switch-vitest
  • hermes-sandbox-secret-boundary-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/hermes-sandbox-secret-boundary.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-sandbox-secret-boundary-vitest
  • sandbox-operations-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/sandbox-operations.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=sandbox-operations-vitest
  • sandbox-rebuild-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/sandbox-rebuild.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=sandbox-rebuild-vitest

Optional Vitest E2E scenarios

  • rebuild-hermes-vitest: Optional adjacent coverage for the Hermes Dockerfile/base-image rebuild path touched by this PR; the primary Hermes runtime/startup coverage is already required above.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=rebuild-hermes-vitest
  • shields-config-vitest: Optional adjacent coverage for the broad shields/config lock changes; required jobs already cover the main sandbox and Hermes live paths affected by the PR.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=shields-config-vitest
  • gateway-health-honest-vitest: Optional adjacent coverage for the Docker healthcheck and gateway PID identity changes; gateway-guard-recovery is the primary required recovery path.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=gateway-health-honest-vitest

Relevant changed files

  • Dockerfile
  • Dockerfile.base
  • agents/hermes/Dockerfile
  • agents/hermes/runtime-config-guard.py
  • agents/hermes/start.sh
  • agents/hermes/validate-env-secret-boundary.py
  • scripts/gateway-control.sh
  • scripts/lib/gateway-supervisor.sh
  • scripts/managed-gateway-control.py
  • scripts/nemoclaw-start.sh
  • scripts/openclaw-config-guard.py
  • scripts/state-dir-guard.py
  • src/commands/sandbox/config/set.ts
  • src/commands/sandbox/gateway/restart.ts
  • src/commands/sandbox/recover.ts
  • src/lib/actions/inference-set.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/destroy.ts
  • src/lib/actions/sandbox/forward-health.ts
  • src/lib/actions/sandbox/forward-recovery.ts
  • src/lib/actions/sandbox/gateway-restart.ts
  • src/lib/actions/sandbox/hermes-dashboard-recovery.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/rebuild-shields.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/agent/defs.ts
  • src/lib/agent/gateway-restart-markers.ts
  • src/lib/agent/gateway-restart-scripts.ts
  • src/lib/agent/gateway-script-shared.ts
  • src/lib/agent/hermes-recovery-boundary.ts
  • src/lib/agent/onboard.ts
  • src/lib/agent/runtime.ts
  • src/lib/sandbox/build-context.ts
  • src/lib/sandbox/config.ts
  • src/lib/sandbox/privileged-exec.ts
  • src/lib/shields/index.ts
  • src/lib/shields/openclaw-config-lock.ts
  • src/lib/shields/state-dir-lock.ts
  • src/lib/shields/timer-bound-lock.ts
  • src/lib/shields/timer-control.ts
  • src/lib/shields/timer.ts
  • src/lib/shields/transition-lock.ts
  • src/lib/shields/verify-lock.ts
  • test/e2e-scenario/live/gateway-guard-recovery.test.ts
  • test/e2e-scenario/live/hermes-e2e.test.ts
  • test/e2e-scenario/live/hermes-inference-switch-helpers.ts
  • test/e2e-scenario/live/hermes-inference-switch.test.ts
  • test/e2e-scenario/live/hermes-sandbox-secret-boundary.test.ts
  • test/e2e-scenario/live/sandbox-operations.test.ts
  • test/e2e-scenario/live/sandbox-rebuild.test.ts
  • test/e2e-scenario/support-tests/hermes-dashboard-workflow-boundary.test.ts
  • tools/e2e-scenarios/hermes-dashboard-workflow-boundary.mts

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Source-of-truth review needed: HTTPS config URL DNS validation.
Open items: 0 required · 3 warnings · 0 suggestions · 3 test follow-ups
Since last review: 2 prior items resolved · 3 still apply · 0 new items found

Action checklist

  • PRA-1 Resolve or justify: Source-of-truth review needed: HTTPS config URL DNS validation
  • PRA-2 Resolve or justify: HTTPS config URL validation still does not bind the runtime destination in src/lib/sandbox/config.ts:766
  • PRA-3 Resolve or justify: Security-critical shields orchestration remains concentrated in a growing coordinator in src/lib/shields/index.ts:1
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: HTTPS config URL DNS validation

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify security src/lib/sandbox/config.ts:766 Either bind HTTPS runtime use to the validated destination/IP, route HTTPS custom endpoint use through an explicit runtime destination policy check, or add code-level documentation plus regression coverage proving all consumers enforce certificate verification with no opt-out for these config URLs.
PRA-3 Resolve/justify architecture src/lib/shields/index.ts:1 For code local to this PR, either extract one cohesive remaining transition/timer/recovery sub-flow that does not weaken ordering, or add branch-local invariant comments at the largest decision points explaining why each branch must stay in the coordinator. Keep validation, rollback, lock ownership, policy restoration, timer authority, and audit recording intact.
Review findings by urgency: 0 required fixes, 3 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: HTTPS config URL DNS validation

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Existing endpoint-security tests cover HTTP pinning and HTTPS hostname preservation, but not a later private DNS result at runtime.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: `rewriteConfigUrlsWithDnsPinning()` returns `validated.originalUrl` for `https:` after `validateUrlValueWithDnsResult()` rejects only the current DNS answers.

PRA-2 Resolve/justify — HTTPS config URL validation still does not bind the runtime destination

  • Location: src/lib/sandbox/config.ts:766
  • Category: security
  • Problem: `rewriteConfigUrlsWithDnsPinning()` rejects private DNS answers at config mutation time and pins HTTP URLs, but persists the original hostname for HTTPS URLs. The changed endpoint-security test proves only that HTTPS hostnames are preserved for certificate verification; it does not prove that every runtime consumer blocks later DNS rebinding to private/internal addresses or cannot disable TLS verification.
  • Impact: A custom HTTPS endpoint that resolves to a public address during `config set` can later resolve to private/internal space. If any runtime path reconnects after re-resolution with weakened TLS verification or a non-policy-bound client, this can become SSRF or a sandbox network-policy bypass through durable inference configuration.
  • Recommended action: Either bind HTTPS runtime use to the validated destination/IP, route HTTPS custom endpoint use through an explicit runtime destination policy check, or add code-level documentation plus regression coverage proving all consumers enforce certificate verification with no opt-out for these config URLs.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `src/lib/sandbox/config.ts` around `validateUrlValueWithDnsResult()` and `rewriteConfigUrlsWithDnsPinning()`, then inspect `src/lib/actions/inference-set-endpoint-security.test.ts`; the current HTTPS case asserts `https://public-endpoint.example/v1\` is preserved, not that a later private DNS result is blocked.
  • Missing regression test: Add a behavior test where an HTTPS custom endpoint validates against a public DNS answer, then runtime resolution returns a private/internal IP, and assert the request is blocked by runtime destination/IP policy or that the only allowed client path enforces TLS verification with no opt-out.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `src/lib/sandbox/config.ts` around `validateUrlValueWithDnsResult()` and `rewriteConfigUrlsWithDnsPinning()`, then inspect `src/lib/actions/inference-set-endpoint-security.test.ts`; the current HTTPS case asserts `https://public-endpoint.example/v1\` is preserved, not that a later private DNS result is blocked.
  • Evidence: `validateUrlValueWithDnsResult()` rejects private config-time DNS answers, but `rewriteConfigUrlsWithDnsPinning()` returns `validated.originalUrl` for `https:` while the nearby test is named `preserves a validated HTTPS hostname for certificate verification`.

PRA-3 Resolve/justify — Security-critical shields orchestration remains concentrated in a growing coordinator

  • Location: src/lib/shields/index.ts:1
  • Category: architecture
  • Problem: `src/lib/shields/index.ts` remains the host-side transaction coordinator for policy snapshots, config posture, timers, state commits, rollback, recovery, and audit ordering. The new top-of-file comment and TCB page explain the coupling, and leaf lock modules were extracted, but the coordinator still grew to about 3249 lines in this PR.
  • Impact: The larger coordinator is harder to audit for ordering mistakes and TOCTOU regressions in shields up/down, timed unlocks, recovery, and rollback. Future changes can accidentally duplicate or bypass transaction ordering despite the extracted leaf modules.
  • Recommended action: For code local to this PR, either extract one cohesive remaining transition/timer/recovery sub-flow that does not weaken ordering, or add branch-local invariant comments at the largest decision points explaining why each branch must stay in the coordinator. Keep validation, rollback, lock ownership, policy restoration, timer authority, and audit recording intact.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read the top-level comment and the main transition/timer/recovery branches in `src/lib/shields/index.ts`, then compare the responsibilities already moved to `transition-lock.ts`, `timer-bound-lock.ts`, `state-dir-lock.ts`, and `openclaw-config-lock.ts`.
  • Missing regression test: Existing changed tests cover transition locks, timer-bound locks, state-dir locks, verify-lock, legacy transitions, timer behavior, and shields flow behavior. If extraction is done, keep those tests and add a focused test for the extracted branch preserving lock acquisition, rollback, and audit ordering.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read the top-level comment and the main transition/timer/recovery branches in `src/lib/shields/index.ts`, then compare the responsibilities already moved to `transition-lock.ts`, `timer-bound-lock.ts`, `state-dir-lock.ts`, and `openclaw-config-lock.ts`.
  • Evidence: The drift context reports `src/lib/shields/index.ts` grew from 1611 to 3249 lines; the file itself states it intentionally remains the host-side transaction coordinator for multiple security-sensitive resources.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
Simplification opportunities: 1 possible cut

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-3 shrink (src/lib/shields/index.ts:1): One cohesive transition/timer/recovery branch that can move out of `src/lib/shields/index.ts` without changing the transaction order.
    • Replacement: A focused helper module with the current coordinator calling one typed operation and retaining the same lock, rollback, timer, policy, state, and audit sequencing.
    • Safety boundary: Do not remove or weaken transition-lock ownership, timer-bound authority, config guard calls, rollback, policy restoration, state commits, or audit recording.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — HTTPS custom endpoint blocks runtime private-DNS rebind after a public config-time DNS answer. This PR changes Dockerfiles, root-owned lifecycle helpers, process identity proofs, Hermes supervisor behavior, and shields/config transaction guards. Static tests and live E2E coverage are extensive for the main gateway restart/recovery behavior, but the HTTPS endpoint runtime-binding security gap still needs a behavior-specific regression.
  • PRA-T2 Runtime validation — HTTPS custom endpoint runtime client cannot disable TLS verification for durable config URLs. This PR changes Dockerfiles, root-owned lifecycle helpers, process identity proofs, Hermes supervisor behavior, and shields/config transaction guards. Static tests and live E2E coverage are extensive for the main gateway restart/recovery behavior, but the HTTPS endpoint runtime-binding security gap still needs a behavior-specific regression.
  • PRA-T3 HTTPS config URL DNS validation — Existing endpoint-security tests cover HTTP pinning and HTTPS hostname preservation, but not a later private DNS result at runtime.. `rewriteConfigUrlsWithDnsPinning()` returns `validated.originalUrl` for `https:` after `validateUrlValueWithDnsResult()` rejects only the current DNS answers.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: HTTPS config URL DNS validation

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Existing endpoint-security tests cover HTTP pinning and HTTPS hostname preservation, but not a later private DNS result at runtime.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: `rewriteConfigUrlsWithDnsPinning()` returns `validated.originalUrl` for `https:` after `validateUrlValueWithDnsResult()` rejects only the current DNS answers.

PRA-2 Resolve/justify — HTTPS config URL validation still does not bind the runtime destination

  • Location: src/lib/sandbox/config.ts:766
  • Category: security
  • Problem: `rewriteConfigUrlsWithDnsPinning()` rejects private DNS answers at config mutation time and pins HTTP URLs, but persists the original hostname for HTTPS URLs. The changed endpoint-security test proves only that HTTPS hostnames are preserved for certificate verification; it does not prove that every runtime consumer blocks later DNS rebinding to private/internal addresses or cannot disable TLS verification.
  • Impact: A custom HTTPS endpoint that resolves to a public address during `config set` can later resolve to private/internal space. If any runtime path reconnects after re-resolution with weakened TLS verification or a non-policy-bound client, this can become SSRF or a sandbox network-policy bypass through durable inference configuration.
  • Recommended action: Either bind HTTPS runtime use to the validated destination/IP, route HTTPS custom endpoint use through an explicit runtime destination policy check, or add code-level documentation plus regression coverage proving all consumers enforce certificate verification with no opt-out for these config URLs.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `src/lib/sandbox/config.ts` around `validateUrlValueWithDnsResult()` and `rewriteConfigUrlsWithDnsPinning()`, then inspect `src/lib/actions/inference-set-endpoint-security.test.ts`; the current HTTPS case asserts `https://public-endpoint.example/v1\` is preserved, not that a later private DNS result is blocked.
  • Missing regression test: Add a behavior test where an HTTPS custom endpoint validates against a public DNS answer, then runtime resolution returns a private/internal IP, and assert the request is blocked by runtime destination/IP policy or that the only allowed client path enforces TLS verification with no opt-out.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `src/lib/sandbox/config.ts` around `validateUrlValueWithDnsResult()` and `rewriteConfigUrlsWithDnsPinning()`, then inspect `src/lib/actions/inference-set-endpoint-security.test.ts`; the current HTTPS case asserts `https://public-endpoint.example/v1\` is preserved, not that a later private DNS result is blocked.
  • Evidence: `validateUrlValueWithDnsResult()` rejects private config-time DNS answers, but `rewriteConfigUrlsWithDnsPinning()` returns `validated.originalUrl` for `https:` while the nearby test is named `preserves a validated HTTPS hostname for certificate verification`.

PRA-3 Resolve/justify — Security-critical shields orchestration remains concentrated in a growing coordinator

  • Location: src/lib/shields/index.ts:1
  • Category: architecture
  • Problem: `src/lib/shields/index.ts` remains the host-side transaction coordinator for policy snapshots, config posture, timers, state commits, rollback, recovery, and audit ordering. The new top-of-file comment and TCB page explain the coupling, and leaf lock modules were extracted, but the coordinator still grew to about 3249 lines in this PR.
  • Impact: The larger coordinator is harder to audit for ordering mistakes and TOCTOU regressions in shields up/down, timed unlocks, recovery, and rollback. Future changes can accidentally duplicate or bypass transaction ordering despite the extracted leaf modules.
  • Recommended action: For code local to this PR, either extract one cohesive remaining transition/timer/recovery sub-flow that does not weaken ordering, or add branch-local invariant comments at the largest decision points explaining why each branch must stay in the coordinator. Keep validation, rollback, lock ownership, policy restoration, timer authority, and audit recording intact.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read the top-level comment and the main transition/timer/recovery branches in `src/lib/shields/index.ts`, then compare the responsibilities already moved to `transition-lock.ts`, `timer-bound-lock.ts`, `state-dir-lock.ts`, and `openclaw-config-lock.ts`.
  • Missing regression test: Existing changed tests cover transition locks, timer-bound locks, state-dir locks, verify-lock, legacy transitions, timer behavior, and shields flow behavior. If extraction is done, keep those tests and add a focused test for the extracted branch preserving lock acquisition, rollback, and audit ordering.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read the top-level comment and the main transition/timer/recovery branches in `src/lib/shields/index.ts`, then compare the responsibilities already moved to `transition-lock.ts`, `timer-bound-lock.ts`, `state-dir-lock.ts`, and `openclaw-config-lock.ts`.
  • Evidence: The drift context reports `src/lib/shields/index.ts` grew from 1611 to 3249 lines; the file itself states it intentionally remains the host-side transaction coordinator for multiple security-sensitive resources.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

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

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28253422289
Target ref: 2bfd6d931b1c81e2668ed9957454f02eb03b1157
Workflow ref: main
Requested jobs: hermes-root-entrypoint-smoke-e2e,hermes-secret-boundary-e2e
Summary: 2 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-root-entrypoint-smoke-e2e ✅ success
hermes-secret-boundary-e2e ✅ success

@wscurran wscurran added the integration: dcode LangChain Deep Code integration behavior label Jun 26, 2026
ericksoa added 2 commits June 26, 2026 10:26
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
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.

Actionable comments posted: 3

🤖 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 `@src/lib/actions/sandbox/process-recovery.ts`:
- Line 401: The restart script is being built with the wrong port value:
`buildHermesGatewayRestartScript` expects the Hermes health/API port for
`_NEMOCLAW_RESTART_HEALTH_PORT`, but `process-recovery.ts` is currently passing
`dashboardPort`. Update the call site to pass the actual Hermes health port from
the recovery context instead of the dashboard port, and make sure the value used
here matches the fixture’s health probe port so
`buildHermesGatewayRestartScript` launches socat/health recovery against the
correct endpoint.
- Around line 395-405: The Hermes recovery path in recoverSandboxProcesses still
prints failure details even when callers request quiet mode, so thread the quiet
flag into this helper and suppress the printGatewayRestartFailure calls when
quiet is true. Update the existing checkAndRecoverSandboxProcesses call site to
pass { quiet }, and use the recoverSandboxProcesses and
printGatewayRestartFailure symbols to locate the affected Hermes branch.

In `@src/lib/agent/runtime.ts`:
- Around line 364-367: The restart validation in runtime.ts should fail closed
instead of falling back to resolving Hermes from PATH. Update the logic in the
validationSteps construction so that if AGENT_BIN at binaryPath is missing or
not executable, it exits with AGENT_MISSING rather than calling command -v on
binaryName. Keep the check within the restart flow that relaunches as gateway,
and ensure the code only accepts the trusted binaryPath for locating the
executable.
🪄 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: e725fd75-9d5c-4add-9d95-ab5fbe819868

📥 Commits

Reviewing files that changed from the base of the PR and between 36c0bca and 2dfcdb8.

📒 Files selected for processing (4)
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/agent/runtime.test.ts
  • src/lib/agent/runtime.ts
  • test/process-recovery.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/agent/runtime.test.ts

Comment thread src/lib/actions/sandbox/process-recovery.ts Outdated
Comment thread src/lib/actions/sandbox/process-recovery.ts Outdated
Comment thread src/lib/agent/runtime.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28254560749
Target ref: 2dfcdb8a8dd9436465ca7a029f4a8a3f47beacf2
Workflow ref: main
Requested jobs: hermes-secret-boundary-e2e,hermes-root-entrypoint-smoke-e2e
Summary: 2 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-root-entrypoint-smoke-e2e ✅ success
hermes-secret-boundary-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28254817942
Target ref: 5648819da358c58d53a46393a31d23713426ff45
Workflow ref: main
Requested jobs: hermes-root-entrypoint-smoke-e2e,hermes-secret-boundary-e2e
Summary: 2 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-root-entrypoint-smoke-e2e ✅ success
hermes-secret-boundary-e2e ✅ success

ericksoa added 2 commits June 26, 2026 10:40
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28255266980
Target ref: d3431fd6d815259c99f98c9a0df647839b03e95a
Workflow ref: main
Requested jobs: hermes-secret-boundary-e2e
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-secret-boundary-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28255490504
Target ref: b1b7451cce9dcbd9635fbf06b4cca2f7ef93ee48
Workflow ref: main
Requested jobs: hermes-secret-boundary-e2e,hermes-root-entrypoint-smoke-e2e
Summary: 2 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-root-entrypoint-smoke-e2e ✅ success
hermes-secret-boundary-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28257003744
Target ref: 7fb4a89396383961879a2735d69c7530a3e6c8ab
Workflow ref: main
Requested jobs: hermes-secret-boundary-e2e,issue-2478-crash-loop-recovery-e2e
Summary: 2 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-secret-boundary-e2e ✅ success
issue-2478-crash-loop-recovery-e2e ✅ success

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All selected jobs passed

Run: 28461753584
Workflow ref: fix/issue-2426-gateway-restart
Requested targets: gateway-guard-recovery,hermes-dashboard,hermes-inference-switch,hermes-sandbox-secret-boundary,sandbox-operations,sandbox-rebuild,security-posture
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, jetson-nvmap-gpu, and sandbox-rlimits-connect are skipped unless selected)
Summary: 7 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
gateway-guard-recovery ✅ success
hermes-dashboard ✅ success
hermes-inference-switch ✅ success
hermes-sandbox-secret-boundary ✅ success
sandbox-operations ✅ success
sandbox-rebuild ✅ success
security-posture ✅ success

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 3

Caution

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

⚠️ Outside diff range comments (1)
Dockerfile (1)

1140-1145: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Use cmdline proof instead of comm for the OpenClaw gateway fallback.

Line 1144 can reject a valid npm-installed OpenClaw gateway whose process comm is node, causing Docker to restart an otherwise healthy local gateway after curl exit 7.
The PID/starttime proof already prevents PID reuse; validate /proc/$gwpid/cmdline for the OpenClaw gateway command instead.

As per path instructions, Dockerfile* must be treated as a security boundary and process identity must be traced across the changed flow.

Proposed fix
-        case "$(ps -p "$gwpid" -o comm= 2>/dev/null)" in openclaw*) ;; *) exit 1 ;; esac; \
+        gwcmdline="$(tr '\0' ' ' <"/proc/$gwpid/cmdline" 2>/dev/null)" || exit 1; \
+        printf '%s' "$gwcmdline" | grep -Eq '(^|[[:space:]/])(openclaw|openclaw[.]mjs)([[:space:]]+gateway[[:space:]]+run|[[:space:]]*$)|openclaw-gateway' || exit 1; \
         [ -s /tmp/gateway.log ]
🤖 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 `@Dockerfile` around lines 1140 - 1145, The OpenClaw gateway fallback is
validating process identity with ps ... comm in the gateway check, which can
misidentify npm-launched gateways whose comm is node. Update the gateway proof
in the Dockerfile block that sets gwidentity/gwstate/gwcurrent to validate
/proc/$gwpid/cmdline instead of comm, and keep the existing PID/starttime check
as the process identity guard for the fallback flow.

Source: Path instructions

🧹 Nitpick comments (2)
docs/security/openshell-0.0.71-gateway-auth-review.mdx (1)

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

Split these multi-sentence bullets to one sentence per source line.

Several new bullets pack multiple sentences onto the same MDX line, which breaks the docs source-formatting rule and makes later diffs harder to review. As per coding guidelines, Keep one sentence per line in Markdown and MDX source files.

Also applies to: 34-35, 52-59

🤖 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 `@docs/security/openshell-0.0.71-gateway-auth-review.mdx` around lines 19 - 24,
The MDX bullets in this review note combine multiple sentences on a single
source line, violating the one-sentence-per-line formatting rule. Update the
affected bullets in the security doc so each sentence is on its own line,
keeping the existing content intact while reflowing the text around the
OpenShell gateway auth, Docker-hosted compatibility, Hermes env-file, JWT
recovery, sandbox recovery, and sessions RPC helper bullets.

Source: Coding guidelines

src/lib/onboard/docker-driver-gateway-config-auth-contract.test.ts (1)

22-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid locking this test to review-note prose.

This assertion list fails on harmless wording edits without proving the gateway auth contract changed. Prefer a small set of machine-readable version markers here and leave the behavioral contract to the TOML/JWT tests below. 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 `@src/lib/onboard/docker-driver-gateway-config-auth-contract.test.ts` around
lines 22 - 53, The `keeps the OpenShell gateway auth source review aligned with
the generated config` test is over-coupled to review-note prose and will fail on
wording-only changes. Replace the long `reviewNote.toContain(...)` checklist
with a minimal set of stable, machine-readable version markers in this spec, and
keep the real behavioral assertions in the TOML/JWT contract tests such as
`openshell_server::config_file::load()` and the gateway auth source contract
tests.

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/start.sh`:
- Around line 2434-2448: The crash-quarantine counter in
record_hermes_managed_gateway_exit is counting intentional controller-driven
restarts the same as unexpected exits, which can wrongly quarantine managed
recovery flows. Update the exit-recording path used by
supervise_hermes_gateway_current_user so host-requested restarts are excluded
from HERMES_MANAGED_GATEWAY_EXIT_TIMES, or explicitly reset/skip the budget for
those cases before the >=5 check. Make sure the restart/recovery loop that
triggers gateway restart does not call into the quarantine logic for expected
exits, while true failures still increment and can call
quarantine_hermes_managed_gateway_relaunch.

In `@src/lib/actions/sandbox/hermes-secret-boundary-recovery.ts`:
- Around line 67-69: The Hermes boundary check in
hermes-secret-boundary-recovery.ts only treats GATEWAY_PID as success, so update
the success condition in the helper that inspects result.stdout/result.stderr to
also accept ALREADY_RUNNING as a valid authenticated marker. Keep the existing
refusal behavior for unexpected output, but ensure the same recovery contract
used elsewhere is honored in this live Hermes path.

In `@src/lib/actions/sandbox/process-recovery.ts`:
- Around line 519-527: The recovery flow in waitForRecoveredSandboxGateway is
still hardcoding executeGatewaySupervisorAction inside managedProbeImpl, which
bypasses the caller-injected supervisor action from restartSandboxGateway.
Update the managed settle probe to use the same injected
deps.requestGatewaySupervisorAction path that restartSandboxGateway receives,
and thread that dependency through confirmRecoveredSandboxGatewayManaged so the
recovery wait stays fully mocked when callers override it.

---

Outside diff comments:
In `@Dockerfile`:
- Around line 1140-1145: The OpenClaw gateway fallback is validating process
identity with ps ... comm in the gateway check, which can misidentify
npm-launched gateways whose comm is node. Update the gateway proof in the
Dockerfile block that sets gwidentity/gwstate/gwcurrent to validate
/proc/$gwpid/cmdline instead of comm, and keep the existing PID/starttime check
as the process identity guard for the fallback flow.

---

Nitpick comments:
In `@docs/security/openshell-0.0.71-gateway-auth-review.mdx`:
- Around line 19-24: The MDX bullets in this review note combine multiple
sentences on a single source line, violating the one-sentence-per-line
formatting rule. Update the affected bullets in the security doc so each
sentence is on its own line, keeping the existing content intact while reflowing
the text around the OpenShell gateway auth, Docker-hosted compatibility, Hermes
env-file, JWT recovery, sandbox recovery, and sessions RPC helper bullets.

In `@src/lib/onboard/docker-driver-gateway-config-auth-contract.test.ts`:
- Around line 22-53: The `keeps the OpenShell gateway auth source review aligned
with the generated config` test is over-coupled to review-note prose and will
fail on wording-only changes. Replace the long `reviewNote.toContain(...)`
checklist with a minimal set of stable, machine-readable version markers in this
spec, and keep the real behavioral assertions in the TOML/JWT contract tests
such as `openshell_server::config_file::load()` and the gateway auth source
contract tests.
🪄 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: 57a68fc4-17b0-4cc6-abd5-1266ef89751c

📥 Commits

Reviewing files that changed from the base of the PR and between d1765ef and e09c253.

📒 Files selected for processing (47)
  • Dockerfile
  • agents/hermes/Dockerfile
  • agents/hermes/runtime-config-guard.py
  • agents/hermes/start.sh
  • agents/hermes/validate-env-secret-boundary.py
  • docs/about/release-notes.mdx
  • docs/index.yml
  • docs/manage-sandboxes/install-plugins-hermes.mdx
  • docs/manage-sandboxes/lifecycle.mdx
  • docs/manage-sandboxes/runtime-controls.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • docs/security/best-practices.mdx
  • docs/security/openshell-0.0.71-gateway-auth-review.mdx
  • docs/security/tcb-boundary.mdx
  • scripts/checks/no-test-dist-imports.ts
  • scripts/gateway-control.sh
  • scripts/lib/gateway-supervisor.sh
  • scripts/managed-gateway-control.py
  • scripts/nemoclaw-start.sh
  • scripts/openclaw-config-guard.py
  • src/commands/sandbox/gateway/restart.ts
  • src/lib/actions/inference-set-endpoint-security.test.ts
  • src/lib/actions/inference-set.test.ts
  • src/lib/actions/inference-set.ts
  • src/lib/actions/sandbox/connect-flow.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/gateway-restart.test.ts
  • src/lib/actions/sandbox/gateway-restart.ts
  • src/lib/actions/sandbox/hermes-secret-boundary-recovery.test.ts
  • src/lib/actions/sandbox/hermes-secret-boundary-recovery.ts
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/agent/gateway-restart-scripts.ts
  • src/lib/cli/public-display-defaults.ts
  • src/lib/onboard/docker-driver-gateway-config-auth-contract.test.ts
  • src/lib/sandbox/build-context.ts
  • src/lib/sandbox/config.ts
  • src/lib/sandbox/privileged-exec.test.ts
  • src/lib/sandbox/privileged-exec.ts
  • src/lib/shields/index.test.ts
  • src/lib/shields/index.ts
  • src/lib/shields/legacy-hermes-compat.test.ts
  • test/cli/connect-recovery-settle.test.ts
  • test/cli/connect-recovery.test.ts
  • test/e2e-gateway-isolation.sh
💤 Files with no reviewable changes (7)
  • src/lib/sandbox/build-context.ts
  • src/lib/shields/index.test.ts
  • src/lib/sandbox/privileged-exec.test.ts
  • src/lib/shields/legacy-hermes-compat.test.ts
  • src/lib/sandbox/privileged-exec.ts
  • src/lib/sandbox/config.ts
  • src/lib/shields/index.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/commands-nemohermes.mdx
🚧 Files skipped from review as they are similar to previous changes (14)
  • src/lib/cli/public-display-defaults.ts
  • src/lib/actions/sandbox/connect.ts
  • src/commands/sandbox/gateway/restart.ts
  • docs/manage-sandboxes/install-plugins-hermes.mdx
  • docs/reference/troubleshooting.mdx
  • scripts/checks/no-test-dist-imports.ts
  • docs/manage-sandboxes/lifecycle.mdx
  • src/lib/agent/gateway-restart-scripts.ts
  • src/lib/actions/sandbox/gateway-restart.test.ts
  • docs/manage-sandboxes/runtime-controls.mdx
  • agents/hermes/validate-env-secret-boundary.py
  • scripts/lib/gateway-supervisor.sh
  • docs/reference/commands.mdx
  • src/lib/actions/sandbox/gateway-restart.ts

Comment thread agents/hermes/start.sh
Comment thread src/lib/actions/sandbox/hermes-secret-boundary-recovery.ts
Comment thread src/lib/actions/sandbox/process-recovery.ts
ericksoa added 2 commits June 30, 2026 11:20
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Comment thread scripts/managed-gateway-control.py Fixed
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28467231522
Workflow ref: fix/issue-2426-gateway-restart
Requested targets: gateway-guard-recovery,hermes-dashboard,hermes-inference-switch,hermes-sandbox-secret-boundary,sandbox-operations,sandbox-rebuild,security-posture
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, jetson-nvmap-gpu, and sandbox-rlimits-connect are skipped unless selected)
Summary: 6 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
gateway-guard-recovery ✅ success
hermes-dashboard ✅ success
hermes-inference-switch ✅ success
hermes-sandbox-secret-boundary ✅ success
sandbox-operations ✅ success
sandbox-rebuild ❌ failure
security-posture ✅ success

Failed jobs: sandbox-rebuild. Check run artifacts for logs.

@jyaunches jyaunches merged commit 0cfaf8f into main Jun 30, 2026
277 of 278 checks passed
@jyaunches jyaunches deleted the fix/issue-2426-gateway-restart branch June 30, 2026 18:46
jyaunches pushed a commit that referenced this pull request Jun 30, 2026
…arning to file (#6065)

## Summary

Two E2E regressions introduced by #5874:

- **`runtime-overrides`**: `reconcile_agent_model_with_provider` ran
after `apply_model_override` and overwrote
`agents.defaults.model.primary` with an `inference/`-prefixed variant
because `qualify()` unconditionally prepends `inference/`. The comment
at the call site already documented that the explicit override should
win; this adds the guard to enforce it.

- **`issue-2478-crash-loop-recovery`**:
`restore_openclaw_runtime_guard_chain` wrote its warning only to stderr.
The new host-mediated recovery path (`docker exec …
nemoclaw-gateway-control recover`) runs inside PID 1, not a fresh
sandbox exec, so stderr never reached `/tmp/gateway.log`. Mirrors the
warning to the gateway log file using the same `_NEMOCLAW_GATEWAY_LOG`
seam the watchdog already uses.

## Test plan

- [ ] Trigger the `runtime-overrides` E2E target — expect
`primaryModel(modelOverride)` to return `"anthropic/claude-sonnet-4-6"`
(not `"inference/anthropic/…"`)
- [ ] Trigger the `issue-2478-crash-loop-recovery` E2E target — expect
`[gateway-recovery] WARNING: .*restoring library guards from packaged
preloads` to appear in `/tmp/gateway.log`
- [ ] Full main E2E run to confirm no regressions

Signed-off-by: Preksha Vijayvargiya <prekshiv@nvidia.com>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

## Summary by CodeRabbit

* **Bug Fixes**
* Preserved explicit model overrides so they are not replaced by later
reconciliation.
* Added startup guard-chain warnings to the gateway log as well as
stderr for easier troubleshooting.

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

Signed-off-by: Preksha Vijayvargiya <prekshiv@nvidia.com>
@jyaunches jyaunches mentioned this pull request Jun 30, 2026
21 tasks
jyaunches added a commit that referenced this pull request Jun 30, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Refreshes the public documentation for NemoClaw v0.0.71 after scanning
commits since v0.0.70. Adds release notes and fills the remaining doc
gaps for Windows bootstrap diagnostics, OpenClaw agent auto-relock
warnings, auto-pair cadence tuning, and plugin-install recovery hints.

## Changes
- `docs/about/release-notes.mdx`: adds the v0.0.71 release-note section,
grouped by gateway recovery, OpenShell auth, policy provenance, day-two
maintenance, messaging/inference, and Windows setup.
- `docs/get-started/windows-preparation.mdx`: documents sanitized WSL
install output and reboot gating in the Windows bootstrap.
- `docs/reference/commands.mdx`: documents the host `agent` wrapper's
shields auto-relock warning and OpenClaw auto-pair watcher tuning
variables.
- `docs/reference/troubleshooting.mdx`: adds plugin-install network
failure recovery guidance and updates Windows WSL troubleshooting for
sanitized install logs and reboot-required handling.

Source summary:
- #6065 -> `docs/about/release-notes.mdx`: Notes explicit model override
preservation and gateway-log guard-chain recovery diagnostics.
- #5874 -> `docs/about/release-notes.mdx`: Summarizes host-mediated
`recover` and `gateway restart`, linking to lifecycle, command,
troubleshooting, and trusted-boundary docs already added by the source
PR.
- #5596 -> `docs/about/release-notes.mdx`: Summarizes OpenShell 0.0.71
gateway auth, loopback binding, and compatibility-container docs already
added by the source PR.
- #5797 and #5798 -> `docs/about/release-notes.mdx`: Summarizes
`policy-list` provenance, Restricted tier suppression, and Balanced tier
weather behavior already reflected in policy docs.
- #5784 -> `docs/about/release-notes.mdx`: Summarizes
`--destroy-user-data` and the safe `--yes` uninstall behavior already
documented in lifecycle and command docs.
- #6034 -> `docs/about/release-notes.mdx`: Summarizes custom Dockerfile
warm-build cache behavior already documented in the command reference.
- #5951 -> `docs/reference/commands.mdx`: Documents the stderr-only host
`agent` wrapper warning after recent shields auto-relock.
- #5387 -> `docs/reference/commands.mdx`: Documents OpenClaw auto-pair
watcher cadence and fast-reentry tuning variables.
- #5835 -> `docs/reference/troubleshooting.mdx`: Adds recovery guidance
for OpenClaw plugin-install network failures.
- #5995 and #5956 -> `docs/about/release-notes.mdx`: Summarizes
Microsoft Teams final-message delivery and runtime mention hints already
covered by messaging docs.
- #5716 -> `docs/about/release-notes.mdx`: Summarizes non-interactive
Ollama loopback safety already covered by local inference docs.
- #5505, #5527, and #5528 -> `docs/about/release-notes.mdx`: Summarizes
compatible local endpoint, model task-fit, and model capability audit
docs.
- #6009 -> `docs/get-started/windows-preparation.mdx`,
`docs/reference/troubleshooting.mdx`: Documents sanitized Windows
bootstrap WSL output and reboot-required gating.
- #6055 -> no additional source doc page change needed beyond the
already-merged quickstart update; release notes did not duplicate
routine quickstart cleanup.

No matching v0.0.71 GitHub announcement discussion was found in the
latest 20 discussions, so this refresh is based on the commit scan and
existing source PR docs.

## Type of Change

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

## Quality Gates
<!-- Check all that apply. For any "covered by existing tests", "not
applicable", or waiver entry, add a brief justification on the same line
or in the Changes section. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: docs-only refresh with no
runtime behavior changes.
- [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:

## Verification
<!-- Check each item you ran and confirmed. Leave unchecked items you
skipped. Doc-only changes do not require npm test unless you ran it. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [ ] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [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) — ran
`npm run docs`; Fern reported 0 errors and 2 existing 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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
* Added a new release-notes entry covering gateway recovery,
authentication, network policy/provenance output, uninstall safety,
Windows bootstrap diagnostics, messaging defaults, and inference setup
guidance.
* Clarified Windows preparation steps around reboot behavior and
redacting troubleshooting transcripts.
* Expanded command reference details for OpenClaw wrapper behavior and
new auto-pair tuning options.
* Improved troubleshooting guidance for plugin installation issues, WSL
repair/reboot cases, and install timing problems.

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

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Co-authored-by: Prekshi Vyas <34834085+prekshivyas@users.noreply.github.com>
jyaunches pushed a commit that referenced this pull request Jul 6, 2026
…st it (#6086)

## Summary

Two regressions from #5874 (fixed in #6065) only surfaced in **live E2E
targets that don't run on PR CI**. This PR closes that class of gap: it
audits the live suite for behavior-critical assertions that are cheaply
mockable, backfills them as fast units that run on **every** PR, and
adds a guard so pure-unit blocks can't hide in live files again.

## What's here

**1. The two direct #6065 regression fences** (mocked shell-units)
- `reconcile`: an explicit `NEMOCLAW_MODEL_OVERRIDE` survives a
divergent gateway model and the stale in-file fallback; normal
drift-correction still runs when unset.
- `guard recovery`: the restore warning is mirrored into
`_NEMOCLAW_GATEWAY_LOG` (the marker the crash-loop E2E polls), and stays
silent when the chain is healthy.

**2. High-priority mockable backfill** (security/recovery class)
- ollama-auth-proxy: Bearer enforcement, no `/api/tags` bypass (#3338),
header stripping, non-ASCII auth no-crash (#4820), backend 502.
- `config get`: credential redaction + `gateway`-key omission (the
`nvapi-` regression class).
- device approval policy: scope-upgrade allowlist gate, gateway-env
stripping, recover-failed rejection paths (#4462).
- shields audit JSONL: credentials redacted before persistence.
- hermes env secret boundary: value-shape (not key-name) discriminator;
raw secrets rejected without echoing.
- dashboard bind: `NEMOCLAW_DASHBOARD_BIND` opt-in incl. negative cases
(#3259).
- whatsapp compact QR: package shape-detection + terminal-only `small`
(#4522).

**3. Medium/low backfill**
- ollama token-file lifecycle (0600 / persisted / divergent-repair);
extra-placeholder-keys canonical placeholder + accepted-keys breadcrumb;
hermes `remove_stale_gateway_file` symlink-safety; token-rotation
selective-rebuild naming; `_validate_port` fail-closed; snapshot `help`
branch.

**4. Regression guard**
- `scripts/checks/no-unit-blocks-in-live-e2e.ts` bans the vitest
`it(...)` primitive inside `test/e2e/live/**` (that glob is uncollected
on PR CI, so such blocks never run). Wired into the checks registry with
its own unit test.
- Relocated the existing offenders (skill-agent +
messaging-compatible-endpoint classifier blocks, plus the bare-`test(`
unit cases in common-egress + openclaw-inference-switch) into importable
`test/e2e/support` modules with PR-collected tests; the live tests
import them unchanged.

## Notes

- Minimal behavior-preserving refactor to `whatsapp-qr-compact.ts` to
export its pure helpers (the preload still auto-installs on require);
`tsconfig.runtime-preloads.json` excludes the new co-located test from
the shipped preload build.
- `nemoclaw-start.sh`: made two possibly-empty-array iterations
bash-3.2-safe via the existing `"${arr[@]+...}"` idiom so the shell-unit
harnesses run on stock macOS bash.
- **Deferred (2 low-value items):** the install.sh "Resolved install
ref:" log assertion and the OpenClaw anthropic plain-baseUrl assertion
both land in legacy-budget-capped test files where the growth guardrail
forbids bumping the budget; the anthropic contract is already covered on
the Hermes side and enforced live on the OpenClaw side.

## Verification

- Every new/changed test verified green individually across the `cli`,
`integration`, and `e2e-support` projects.
- `npm run checks` (incl. the new live-unit-block guard), test-file-size
budget, gitleaks, and CLI typecheck all pass.
- The full `test-cli` pre-commit hook was skipped locally only because
it trips on **pre-existing** macOS bash 3.2 failures in untouched
shell-harness suites (`select`/`set -u`); CI runs bash 5.x, where they
are green.

---
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>


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

* **Bug Fixes**
* Improved startup robustness for environment parsing and background
launch behavior.
* WhatsApp compact-QR rendering more consistently uses the compact
“terminal” style.
* Dashboard remote bind activates only when explicitly opted in via
`NEMOCLAW_DASHBOARD_BIND=0.0.0.0`.
* Tightened audit/config redaction to prevent secret leakage and omit
gateway details.
* **Tests**
* Expanded coverage for guard-chain recovery warnings, model override
precedence, Hermes env-boundary hardening, and proxy/policy correctness.
* **Chores**
* Added a CI safeguard to prevent unit-test primitives from being
included in live E2E tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

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

Labels

area: cli Command line interface, flags, terminal UX, or output area: docs Documentation, examples, guides, or docs build 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 feature PR adds or expands user-visible functionality integration: dcode LangChain Deep Code integration behavior integration: hermes Hermes integration behavior integration: openclaw OpenClaw integration behavior v0.0.71 Release target

Projects

None yet

5 participants