Skip to content

fix(agent): harden recovery proxy env sourcing#5342

Merged
cv merged 10 commits into
mainfrom
codex/harden-recovery-proxy-env-followup
Jun 13, 2026
Merged

fix(agent): harden recovery proxy env sourcing#5342
cv merged 10 commits into
mainfrom
codex/harden-recovery-proxy-env-followup

Conversation

@cv

@cv cv commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Hardens recovery proxy-env handling so gateway and Hermes dashboard recovery inspect existing /tmp/nemoclaw-proxy-env.sh only for diagnostics, then source a freshly generated minimal recovery env. This prevents metadata-valid /tmp shell content from being executed during recovery while preserving the trusted guard-chain restoration path from #5321.

Related Issue

Refs #2701
Refs #2478
Follow-up to #5321

Changes

  • Regenerate and source a fresh minimal recovery proxy-env instead of sourcing pre-existing /tmp/nemoclaw-proxy-env.sh content.
  • Reuse the hardened guard recovery path for Hermes dashboard-only recovery before shell init and runtime-env validation.
  • Reject group/other-writable packaged preload sources in non-root recovery and add regression coverage for hostile proxy-env content.

Type of Change

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

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • 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: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • Tests

    • Expanded recovery suites to verify rebuilt proxy envs never expose raw secrets, confirm absence of secret values in logs/output, add cases for safe rebuilding, guard-file repairs, unsafe-preload fail-closed behavior, and unified validate-then-source assertions. Added helpers for temp cleanup, waiting for markers, and for inspecting generated recovery env contents. E2E crash-loop tests now use bounded log-window checks.
  • Refactor

    • Hardened runtime recovery flow: earlier guard validation, adjusted shell init/sourcing order, and sourcing of a dedicated recovery env.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv added the area: security Security controls, permissions, secrets, or hardening label Jun 12, 2026
@cv cv self-assigned this Jun 12, 2026
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Inspect /tmp/nemoclaw-proxy-env.sh for required Node preload guards, generate a sanitized recovery proxy-env when needed, set and source $_NEMOCLAW_RECOVERY_SOURCE_ENV from the Hermes prologue, and update tests and e2e scripts to assert validate-then-source ordering, recovered-file contents, permission failure modes, and log-windowed guard activation.

Changes

Gateway recovery and Hermes dashboard security hardening

Layer / File(s) Summary
Core gateway recovery logic refactor
src/lib/agent/runtime-recovery-preload.ts, src/lib/agent/runtime.ts
Checks /tmp/nemoclaw-proxy-env.sh for required --require entries via _nemoclaw_proxy_env_file_has_require, reorders preload-source permission checks (group/other-writable before root UID), introduces _PE_MISSING/_PROXY_ENV_REWRITE_NEEDED/_PROXY_ENV_PRESERVE_FILE flags, writes generated recovery env via _nemoclaw_write_generated_proxy_env, and adjusts Hermes prologue to inline gateway recovery and move ~/.bashrc after guard checks.
Test harness enhancement and new test cases
src/lib/agent/runtime-recovery-preload.test.ts
makeHarness tracks recovered proxy-env path; runGuardRecovery accepts proxyEnvContent as `string
Behavioral and shape test updates
src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts, src/lib/agent/runtime-hermes-secret-boundary-shape.test.ts, src/lib/agent/runtime.test.ts
Behavioural tests add removeTempDir and waitForPath, update Hermes stub to wait after launch marker, and assert recovery rewrites the volatile proxy-env before sourcing so runtime validation never sees raw secrets; shape/runtime tests require validate-then-source ordering via _nemoclaw_validate_recovery_proxy_env and sourcing from $_NEMOCLAW_RECOVERY_SOURCE_ENV, and disallow conditional sourcing of /tmp/nemoclaw-proxy-env.sh.
E2E crash-loop log-windowed verification
test/e2e/test-issue-2478-crash-loop-recovery.sh
Adds gateway_log_line_count and gateway_log_after_line, extends gateway_guards_active to accept min_log_line and search a bounded log window, snapshots log start per cycle, and relaxes strict byte-identical proxy-env restore when the guard contract is already active.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5321: Further tweaks to runtime-recovery-preload helper and proxy-env validation/rewrite flow used as a foundation.

Suggested labels

security, area: sandbox, bug-fix

Suggested reviewers

  • sandl99

"I am a rabbit in the yard,
I sniff the proxy-env with care,
I stitch a guarded pathway,
I hop past hidden secret snares,
Launches safe, I twirl my ear. 🐇"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(agent): harden recovery proxy env sourcing' directly and clearly describes the main change: hardening proxy environment sourcing during recovery.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/harden-recovery-proxy-env-followup

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

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: issue-2478-crash-loop-recovery-e2e, hermes-secret-boundary-e2e, openclaw-onboard-security-posture-e2e
Optional E2E: sandbox-survival-e2e, hermes-dashboard-e2e, hermes-e2e

Dispatch hint: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e,openclaw-onboard-security-posture-e2e

Auto-dispatched E2E: issue-2478-crash-loop-recovery-e2e, hermes-secret-boundary-e2e, openclaw-onboard-security-posture-e2e via nightly-e2e.yaml at 5e244a3694ec29fa8ed85a70ac430fc1b71b0eabnightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • issue-2478-crash-loop-recovery-e2e (high): Directly covers the modified recovery/preload code path: onboard, kill/recover gateway repeatedly, remove/repair proxy-env.sh, verify guard preloads and inference remain available. This PR also modifies this job and its script, so it must be run to validate the new compat-mock workflow path.
  • hermes-secret-boundary-e2e (high): Required because Hermes recovery secret-boundary behavior changed: generated recovery env sourcing now precedes runtime-env validation, and the PR alters tests around raw secret handling in proxy-env recovery. This E2E verifies raw secret-shaped values do not enter Hermes sandbox env/config boundaries.
  • openclaw-onboard-security-posture-e2e (high): Required security-boundary confidence for the OpenClaw/default sandbox path: recovery now rewrites/sources proxy-env.sh and stages critical NODE_OPTIONS guard preloads. This job validates onboard security posture and runtime guard assertions on the real OpenClaw sandbox.

Optional E2E

  • sandbox-survival-e2e (medium): Useful adjacent coverage for gateway restart recovery and user-visible inference after lifecycle disruptions. issue-2478 is the targeted required test, but sandbox-survival provides broader restart/survival confidence for the same generated recovery machinery.
  • hermes-dashboard-e2e (high): Useful because buildHermesDashboardProcessRecoveryScript changed ordering for Hermes dashboard recovery and proxy-env sourcing. The existing dashboard E2E validates the dashboard real user flow, though it may not force the dashboard-only recovery path.
  • hermes-e2e (high): Useful smoke for the standard Hermes onboard, health, and inference flow after changes to shared runtime recovery and Hermes secret-boundary guard ordering.

New E2E recommendations

  • Hermes dashboard-only process recovery (high): The PR changes buildHermesDashboardProcessRecoveryScript to use generated recovery env sourcing and guard checks, but the existing hermes-dashboard-e2e appears to validate dashboard deployment/health rather than killing only the dashboard and forcing dashboard-specific recovery with a poisoned or incomplete proxy-env.sh.
    • Suggested test: Add a Hermes dashboard recovery E2E that onboards with NEMOCLAW_E2E_HERMES_DASHBOARD=1, removes or poisons /tmp/nemoclaw-proxy-env.sh, kills only the Hermes dashboard process, triggers dashboard recovery, and verifies the dashboard comes back with trusted NODE_OPTIONS guards and no raw secret leakage.
  • Trusted proxy-env preservation across recovery (medium): Unit tests cover preserving root-owned trusted proxy-env.sh entries while generating a recovery source copy, but there is no explicit E2E proving that real sandbox tokens/tool-cache/proxy metadata remain intact after recovery repair on an actual sandbox.
    • Suggested test: Extend or add an E2E that seeds a real trusted proxy-env.sh with gateway token/proxy/tool-cache entries, forces gateway recovery, and asserts those runtime entries plus safety-net/ciao preloads survive without sourcing unsafe shell content.

Dispatch hint

  • Workflow: nightly-e2e.yaml
  • jobs input: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e,openclaw-onboard-security-posture-e2e

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: gateway-guard-recovery
Optional Vitest E2E scenarios: None

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=gateway-guard-recovery

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

Optional Vitest E2E scenarios

  • None.

Relevant changed files

  • src/lib/agent/runtime-recovery-preload.ts
  • src/lib/agent/runtime.ts
  • test/e2e/test-issue-2478-crash-loop-recovery.sh

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor

Findings: 3 needs attention, 7 worth checking, 0 nice ideas
Since last review: 0 prior items resolved, 10 still apply, 0 new items found

Review findings

🛠️ Needs attention

  • Generated recovery env still executes preserved proxy-env shell content (src/lib/agent/runtime-recovery-preload.ts:141): The PR says recovery inspects existing /tmp/nemoclaw-proxy-env.sh only for diagnostics and sources a freshly generated minimal recovery env. The trusted-root path still copies the full root-owned proxy-env into the generated file and then sources that generated file, so metadata-valid /tmp shell content remains executable during recovery.
    • Recommendation: Make the generated recovery env genuinely allowlisted and minimal, or explicitly document that root-owned 0444 proxy-env shell is an intentional trusted execution boundary. If execution is not intentional, add a fake-root/root-owned hostile-command regression test proving preserved shell content is not executed.
    • Evidence: _PROXY_ENV_PRESERVE_FILE is set to /tmp/nemoclaw-proxy-env.sh for root-owned 0444 files; _nemoclaw_write_generated_proxy_env emits `if [ -n "$preserve_file" ]; then cat "$preserve_file"; fi;`; recovery later runs `. "$_NEMOCLAW_RECOVERY_SOURCE_ENV"`. The preservation test asserts the generated recovery source contains OPENCLAW_GATEWAY_TOKEN, an openclaw() shell function, and /tmp/nemoclaw-http-proxy-fix.js.
  • Recovery preload test monolith grew by 91 lines (src/lib/agent/runtime-recovery-preload.test.ts:1): The main recovery preload test file is already a large security-critical hotspot, and this PR adds another substantial block of root/non-root, trusted/unsafe, and credential-boundary scenarios. Continued growth makes the recovery matrix harder to audit.
    • Recommendation: Extract shared trusted-proxy-env fixtures/helpers or split root-preservation, unsafe-proxy-env, trusted-preload-source, and credential-boundary scenarios into smaller focused test modules before adding more coverage.
    • Evidence: Deterministic monolith analysis reports src/lib/agent/runtime-recovery-preload.test.ts grew from 382 to 473 lines (+91), exceeding the 20-line large-file hotspot threshold.
  • Hermes secret-boundary behavioural test monolith grew by 21 lines (src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts:1): The Hermes recovery boundary behavioural test is a large security-sensitive test surface, and this PR grows it past the monolith threshold while adding more recovery timing and cleanup helpers.
    • Recommendation: Offset the growth by extracting reusable temporary-directory cleanup, wait helpers, or recovery harness utilities, or move the generated-env behavioural case into a focused module.
    • Evidence: Deterministic monolith analysis reports src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts grew from 495 to 516 lines (+21), exceeding the 20-line large-file hotspot threshold.

🔎 Worth checking

  • Source-of-truth review needed: Recovery proxy-env rebuilding and generated-env sourcing: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: runtime-recovery-preload.ts stages preloads, writes generated proxy envs, can preserve `cat "$preserve_file"`, and sources `$_NEMOCLAW_RECOVERY_SOURCE_ENV`; tests assert full trusted proxy-env preservation including token and shell function content.
  • Recovery creates an additional credential-bearing proxy-env copy (src/lib/agent/runtime-recovery-preload.ts:168): When the trusted-root preservation path is used, recovery writes a second 0444 shell env file containing gateway credentials and runtime helpers. Even if the original root-owned proxy-env is trusted, duplicating OPENCLAW_GATEWAY_TOKEN and shell functions into /tmp/nemoclaw-recovered-proxy-env.sh expands stale-token and discovery surface.
    • Recommendation: Avoid copying credentials into the generated recovery source when only NODE_OPTIONS guards are needed, remove the generated file after sourcing where practical, or document and test the credential lifecycle, permissions, staleness, and cleanup behavior.
    • Evidence: _nemoclaw_write_generated_proxy_env cats preserve_file into the generated env and chmods it 0444. The preservation test expects both proxyEnv and recoverySourceEnv to contain `OPENCLAW_GATEWAY_TOKEN='trusted-token'`.
  • Proxy-env guard detection is grep-based rather than shell-aware (src/lib/agent/runtime-recovery-preload.ts:80): _nemoclaw_proxy_env_file_has_require treats any literal `--require <path>` or `--require=<path>` text in the file as proof that a guard is installed. Comments, inert strings, or dead shell branches can satisfy the check even when sourcing the generated env would not install an active guard export.
    • Recommendation: Add a regression test where comment-only or inert-string guard markers do not satisfy detection and cause active regenerated exports, or replace the grep check with a stricter parser for the expected export lines.
    • Evidence: The helper uses `grep -F -- "--require $wanted" "$env_file"` and `grep -F -- "--require=$wanted" "$env_file"`; changed tests cover substring mismatch but not comment-only, inert-string, or dead-branch false positives.
  • Hermes dashboard-only guard recovery can lose recovery diagnostics (src/lib/agent/runtime.ts:182): The dashboard-only recovery script now runs buildGatewayGuardRecoveryLines, but unlike gateway recovery paths it does not set up or select _GATEWAY_LOG before those helpers run. Missing, unsafe, or incomplete proxy-env warnings may only go to stderr, and the guard-missing error is not written to a durable recovery log.
    • Recommendation: Initialize an appropriate recovery/dashboard log before buildGatewayGuardRecoveryLines in the dashboard-only script, or explicitly test and document that stderr-only diagnostics are acceptable for this recovery surface.
    • Evidence: buildHermesDashboardProcessRecoveryScript calls buildGatewayGuardRecoveryLines directly after buildHermesEnvFileBoundaryGuard. buildOpenClawRecoveryScript and buildRecoveryScript call buildGatewayLogSetup/buildGatewayLogSelection first.
  • Issue [DGX Spark] Gateway crash loop on startup: @homebridge/ciao networkInterfaces() returns EPERM in OpenShell sandbox #2478 E2E still passes GITHUB_TOKEN to target-ref code (.github/workflows/nightly-e2e.yaml:1008): The PR removes NVIDIA_API_KEY from this E2E lane by switching to the local compatible mock, but the job still enables github_token: true while the changed shell script does not appear to use GITHUB_TOKEN. The reusable workflow runs the checked-out target ref script, so this is unnecessary credential exposure even with contents: read permissions.
    • Recommendation: Set github_token: false for issue-2478-crash-loop-recovery-e2e unless a concrete use is documented and covered by the test.
    • Evidence: nightly-e2e.yaml removes `nvidia_api_key: true` for issue-2478-crash-loop-recovery-e2e but keeps `github_token: true`; grep of test/e2e/test-issue-2478-crash-loop-recovery.sh shows no GITHUB_TOKEN usage.
  • Trusted-root recovery path lacks hostile-content and credential-lifecycle validation (src/lib/agent/runtime-recovery-preload.test.ts:232): The added shell harness tests cover useful non-root, unsafe-mode, symlink, missing source, and group-writable cases, but the riskiest trusted-root behavior is only tested by asserting full preservation of credentials and shell functions. There is no runtime or unit test proving hostile root-owned 0444 shell content cannot execute, nor a lifecycle test for the generated credential-bearing env copy.
    • Recommendation: Add targeted validation for root-owned 0444 proxy env preservation: either prove hostile commands are not executed, or explicitly record intentional trust. Also test generated-env minimality or credential preservation lifecycle and cleanup.
    • Evidence: `preserves a trusted full proxy-env.sh while sourcing only a generated recovery copy` asserts preservation of OPENCLAW_GATEWAY_TOKEN, openclaw(), and /tmp/nemoclaw-http-proxy-fix.js. No changed test covers hostile trusted-root shell content or recovered-token cleanup/staleness.
  • Source-of-truth contract for recovery env rebuilding remains unresolved (src/lib/agent/runtime-recovery-preload.ts:27): This is localized recovery behavior for invalid /tmp proxy-env states, but the changed code does not clearly state why the proxy-env source writer cannot make missing, unsafe, or incomplete states impossible, why trusted-root recovery must preserve full shell instead of allowlisting recovery exports, or when the generated-env workaround can be removed.
    • Recommendation: Document the invalid-state source boundary, why it cannot be fixed at the writer in this PR, the regression that protects the source invariant, and the removal condition. Prefer fixing the proxy-env source so invalid states are impossible, or make the root-owned proxy-env trust contract explicit.
    • Evidence: buildGatewayGuardRecoveryLines stages preloads, writes generated proxy envs, may preserve `cat "$preserve_file"`, and sources `$_NEMOCLAW_RECOVERY_SOURCE_ENV`; tests exercise recovery behavior but not a source-writer invariant or removal condition.

🌱 Nice ideas

  • None.
Consider writing more tests for
  • **Runtime validation** — Runtime sandbox validation: root-owned 0444 /tmp/nemoclaw-proxy-env.sh containing `touch /tmp/hostile-marker` is not executed during gateway recovery, or a test explicitly records that such execution is intentional.. The changed behavior is generated shell executed inside sandbox recovery and depends on actual filesystem ownership, /tmp semantics, root-vs-sandbox execution, shell sourcing order, Hermes/OpenClaw launch timing, workflow credential boundaries, and credential lifecycle. Unit shell harnesses are valuable but do not fully validate the trusted-root security boundary.
  • **Runtime validation** — Unit or runtime validation: generated recovery env is minimal and omits OPENCLAW_GATEWAY_TOKEN, shell functions, /tmp/nemoclaw-http-proxy-fix.js, and unrelated tool-cache exports unless full trusted-root preservation is documented as intentional.. The changed behavior is generated shell executed inside sandbox recovery and depends on actual filesystem ownership, /tmp semantics, root-vs-sandbox execution, shell sourcing order, Hermes/OpenClaw launch timing, workflow credential boundaries, and credential lifecycle. Unit shell harnesses are valuable but do not fully validate the trusted-root security boundary.
  • **Runtime validation** — Unit validation: comment-only or dead-branch `--require <guard>` markers in proxy-env do not suppress regenerated active `export NODE_OPTIONS=...` lines.. The changed behavior is generated shell executed inside sandbox recovery and depends on actual filesystem ownership, /tmp semantics, root-vs-sandbox execution, shell sourcing order, Hermes/OpenClaw launch timing, workflow credential boundaries, and credential lifecycle. Unit shell harnesses are valuable but do not fully validate the trusted-root security boundary.
  • **Runtime validation** — Runtime Hermes dashboard-only validation: dashboard recovery writes guard-recovery warnings/errors to a durable recovery or dashboard log before runtime-env validation and relaunch.. The changed behavior is generated shell executed inside sandbox recovery and depends on actual filesystem ownership, /tmp semantics, root-vs-sandbox execution, shell sourcing order, Hermes/OpenClaw launch timing, workflow credential boundaries, and credential lifecycle. Unit shell harnesses are valuable but do not fully validate the trusted-root security boundary.
  • **Runtime validation** — Credential lifecycle validation: /tmp/nemoclaw-recovered-proxy-env.sh either does not contain gateway tokens or is removed/rotated/permissioned with a documented lifecycle after sourcing.. The changed behavior is generated shell executed inside sandbox recovery and depends on actual filesystem ownership, /tmp semantics, root-vs-sandbox execution, shell sourcing order, Hermes/OpenClaw launch timing, workflow credential boundaries, and credential lifecycle. Unit shell harnesses are valuable but do not fully validate the trusted-root security boundary.
  • **Recovery preload test monolith grew by 91 lines** — Extract shared trusted-proxy-env fixtures/helpers or split root-preservation, unsafe-proxy-env, trusted-preload-source, and credential-boundary scenarios into smaller focused test modules before adding more coverage.
  • **Hermes secret-boundary behavioural test monolith grew by 21 lines** — Offset the growth by extracting reusable temporary-directory cleanup, wait helpers, or recovery harness utilities, or move the generated-env behavioural case into a focused module.
  • **Trusted-root recovery path lacks hostile-content and credential-lifecycle validation** — Add targeted validation for root-owned 0444 proxy env preservation: either prove hostile commands are not executed, or explicitly record intentional trust. Also test generated-env minimality or credential preservation lifecycle and cleanup.
Since last review details

Current findings:

  • Source-of-truth review needed: Recovery proxy-env rebuilding and generated-env sourcing: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: runtime-recovery-preload.ts stages preloads, writes generated proxy envs, can preserve `cat "$preserve_file"`, and sources `$_NEMOCLAW_RECOVERY_SOURCE_ENV`; tests assert full trusted proxy-env preservation including token and shell function content.
  • Generated recovery env still executes preserved proxy-env shell content (src/lib/agent/runtime-recovery-preload.ts:141): The PR says recovery inspects existing /tmp/nemoclaw-proxy-env.sh only for diagnostics and sources a freshly generated minimal recovery env. The trusted-root path still copies the full root-owned proxy-env into the generated file and then sources that generated file, so metadata-valid /tmp shell content remains executable during recovery.
    • Recommendation: Make the generated recovery env genuinely allowlisted and minimal, or explicitly document that root-owned 0444 proxy-env shell is an intentional trusted execution boundary. If execution is not intentional, add a fake-root/root-owned hostile-command regression test proving preserved shell content is not executed.
    • Evidence: _PROXY_ENV_PRESERVE_FILE is set to /tmp/nemoclaw-proxy-env.sh for root-owned 0444 files; _nemoclaw_write_generated_proxy_env emits `if [ -n "$preserve_file" ]; then cat "$preserve_file"; fi;`; recovery later runs `. "$_NEMOCLAW_RECOVERY_SOURCE_ENV"`. The preservation test asserts the generated recovery source contains OPENCLAW_GATEWAY_TOKEN, an openclaw() shell function, and /tmp/nemoclaw-http-proxy-fix.js.
  • Recovery preload test monolith grew by 91 lines (src/lib/agent/runtime-recovery-preload.test.ts:1): The main recovery preload test file is already a large security-critical hotspot, and this PR adds another substantial block of root/non-root, trusted/unsafe, and credential-boundary scenarios. Continued growth makes the recovery matrix harder to audit.
    • Recommendation: Extract shared trusted-proxy-env fixtures/helpers or split root-preservation, unsafe-proxy-env, trusted-preload-source, and credential-boundary scenarios into smaller focused test modules before adding more coverage.
    • Evidence: Deterministic monolith analysis reports src/lib/agent/runtime-recovery-preload.test.ts grew from 382 to 473 lines (+91), exceeding the 20-line large-file hotspot threshold.
  • Hermes secret-boundary behavioural test monolith grew by 21 lines (src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts:1): The Hermes recovery boundary behavioural test is a large security-sensitive test surface, and this PR grows it past the monolith threshold while adding more recovery timing and cleanup helpers.
    • Recommendation: Offset the growth by extracting reusable temporary-directory cleanup, wait helpers, or recovery harness utilities, or move the generated-env behavioural case into a focused module.
    • Evidence: Deterministic monolith analysis reports src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts grew from 495 to 516 lines (+21), exceeding the 20-line large-file hotspot threshold.
  • Recovery creates an additional credential-bearing proxy-env copy (src/lib/agent/runtime-recovery-preload.ts:168): When the trusted-root preservation path is used, recovery writes a second 0444 shell env file containing gateway credentials and runtime helpers. Even if the original root-owned proxy-env is trusted, duplicating OPENCLAW_GATEWAY_TOKEN and shell functions into /tmp/nemoclaw-recovered-proxy-env.sh expands stale-token and discovery surface.
    • Recommendation: Avoid copying credentials into the generated recovery source when only NODE_OPTIONS guards are needed, remove the generated file after sourcing where practical, or document and test the credential lifecycle, permissions, staleness, and cleanup behavior.
    • Evidence: _nemoclaw_write_generated_proxy_env cats preserve_file into the generated env and chmods it 0444. The preservation test expects both proxyEnv and recoverySourceEnv to contain `OPENCLAW_GATEWAY_TOKEN='trusted-token'`.
  • Proxy-env guard detection is grep-based rather than shell-aware (src/lib/agent/runtime-recovery-preload.ts:80): _nemoclaw_proxy_env_file_has_require treats any literal `--require <path>` or `--require=<path>` text in the file as proof that a guard is installed. Comments, inert strings, or dead shell branches can satisfy the check even when sourcing the generated env would not install an active guard export.
    • Recommendation: Add a regression test where comment-only or inert-string guard markers do not satisfy detection and cause active regenerated exports, or replace the grep check with a stricter parser for the expected export lines.
    • Evidence: The helper uses `grep -F -- "--require $wanted" "$env_file"` and `grep -F -- "--require=$wanted" "$env_file"`; changed tests cover substring mismatch but not comment-only, inert-string, or dead-branch false positives.
  • Hermes dashboard-only guard recovery can lose recovery diagnostics (src/lib/agent/runtime.ts:182): The dashboard-only recovery script now runs buildGatewayGuardRecoveryLines, but unlike gateway recovery paths it does not set up or select _GATEWAY_LOG before those helpers run. Missing, unsafe, or incomplete proxy-env warnings may only go to stderr, and the guard-missing error is not written to a durable recovery log.
    • Recommendation: Initialize an appropriate recovery/dashboard log before buildGatewayGuardRecoveryLines in the dashboard-only script, or explicitly test and document that stderr-only diagnostics are acceptable for this recovery surface.
    • Evidence: buildHermesDashboardProcessRecoveryScript calls buildGatewayGuardRecoveryLines directly after buildHermesEnvFileBoundaryGuard. buildOpenClawRecoveryScript and buildRecoveryScript call buildGatewayLogSetup/buildGatewayLogSelection first.
  • Issue [DGX Spark] Gateway crash loop on startup: @homebridge/ciao networkInterfaces() returns EPERM in OpenShell sandbox #2478 E2E still passes GITHUB_TOKEN to target-ref code (.github/workflows/nightly-e2e.yaml:1008): The PR removes NVIDIA_API_KEY from this E2E lane by switching to the local compatible mock, but the job still enables github_token: true while the changed shell script does not appear to use GITHUB_TOKEN. The reusable workflow runs the checked-out target ref script, so this is unnecessary credential exposure even with contents: read permissions.
    • Recommendation: Set github_token: false for issue-2478-crash-loop-recovery-e2e unless a concrete use is documented and covered by the test.
    • Evidence: nightly-e2e.yaml removes `nvidia_api_key: true` for issue-2478-crash-loop-recovery-e2e but keeps `github_token: true`; grep of test/e2e/test-issue-2478-crash-loop-recovery.sh shows no GITHUB_TOKEN usage.
  • Trusted-root recovery path lacks hostile-content and credential-lifecycle validation (src/lib/agent/runtime-recovery-preload.test.ts:232): The added shell harness tests cover useful non-root, unsafe-mode, symlink, missing source, and group-writable cases, but the riskiest trusted-root behavior is only tested by asserting full preservation of credentials and shell functions. There is no runtime or unit test proving hostile root-owned 0444 shell content cannot execute, nor a lifecycle test for the generated credential-bearing env copy.
    • Recommendation: Add targeted validation for root-owned 0444 proxy env preservation: either prove hostile commands are not executed, or explicitly record intentional trust. Also test generated-env minimality or credential preservation lifecycle and cleanup.
    • Evidence: `preserves a trusted full proxy-env.sh while sourcing only a generated recovery copy` asserts preservation of OPENCLAW_GATEWAY_TOKEN, openclaw(), and /tmp/nemoclaw-http-proxy-fix.js. No changed test covers hostile trusted-root shell content or recovered-token cleanup/staleness.
  • Source-of-truth contract for recovery env rebuilding remains unresolved (src/lib/agent/runtime-recovery-preload.ts:27): This is localized recovery behavior for invalid /tmp proxy-env states, but the changed code does not clearly state why the proxy-env source writer cannot make missing, unsafe, or incomplete states impossible, why trusted-root recovery must preserve full shell instead of allowlisting recovery exports, or when the generated-env workaround can be removed.
    • Recommendation: Document the invalid-state source boundary, why it cannot be fixed at the writer in this PR, the regression that protects the source invariant, and the removal condition. Prefer fixing the proxy-env source so invalid states are impossible, or make the root-owned proxy-env trust contract explicit.
    • Evidence: buildGatewayGuardRecoveryLines stages preloads, writes generated proxy envs, may preserve `cat "$preserve_file"`, and sources `$_NEMOCLAW_RECOVERY_SOURCE_ENV`; tests exercise recovery behavior but not a source-writer invariant or removal condition.

Workflow run details

This is an automated advisory review. A human maintainer must make the final merge decision.

cv added 2 commits June 12, 2026 11:00
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@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.

Caution

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

⚠️ Outside diff range comments (1)
src/lib/agent/runtime.test.ts (1)

124-136: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Assert the validation step on the Hermes dashboard-only recovery path.

This is the only dashboard-only check in the supplied tests, and it now verifies only the source step. The stronger ordering checks in src/lib/agent/runtime-recovery-preload.test.ts still cover only buildRecoveryScript and buildOpenClawRecoveryScript, so buildHermesDashboardProcessRecoveryScript could regress to sourcing $_NEMOCLAW_RECOVERY_SOURCE_ENV before _nemoclaw_validate_recovery_proxy_env /tmp/nemoclaw-proxy-env.sh and this suite would still pass.

Suggested assertion upgrade
   it("can recover only the optional Hermes dashboard process", () => {
     const script = buildHermesDashboardProcessRecoveryScript({
       publicPort: 9119,
       internalPort: 19119,
       tuiEnabled: false,
     });
+    expect(script).toContain(
+      "_nemoclaw_validate_recovery_proxy_env /tmp/nemoclaw-proxy-env.sh",
+    );
     expect(script).toContain('. "$_NEMOCLAW_RECOVERY_SOURCE_ENV"');
+    const validateIdx = script.indexOf(
+      "_nemoclaw_validate_recovery_proxy_env /tmp/nemoclaw-proxy-env.sh",
+    );
+    const sourceIdx = script.indexOf('. "$_NEMOCLAW_RECOVERY_SOURCE_ENV"');
+    expect(validateIdx).toBeGreaterThanOrEqual(0);
+    expect(sourceIdx).toBeGreaterThanOrEqual(0);
+    expect(validateIdx).toBeLessThan(sourceIdx);
     expect(script).toContain("/usr/local/bin/hermes");
     expect(script).toContain(
       '"$AGENT_BIN" dashboard --host 127.0.0.1 --port 19119 --skip-build --no-open',
     );
     expect(script).not.toContain("--tui");

Based on the PR objective to harden Hermes dashboard-only recovery before shell initialization, this path needs the same validation/order 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/agent/runtime.test.ts` around lines 124 - 136, The test for
buildHermesDashboardProcessRecoveryScript currently only asserts the recovery
source is present; update it to also assert the validation step occurs before
sourcing by checking the presence and ordering of the validation script
invocation/name (e.g. "_nemoclaw_validate_recovery_proxy_env" or
"/tmp/nemoclaw-proxy-env.sh") appears before '$_NEMOCLAW_RECOVERY_SOURCE_ENV' in
the generated script from buildHermesDashboardProcessRecoveryScript so the
validation step is enforced prior to sourcing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lib/agent/runtime.test.ts`:
- Around line 124-136: The test for buildHermesDashboardProcessRecoveryScript
currently only asserts the recovery source is present; update it to also assert
the validation step occurs before sourcing by checking the presence and ordering
of the validation script invocation/name (e.g.
"_nemoclaw_validate_recovery_proxy_env" or "/tmp/nemoclaw-proxy-env.sh") appears
before '$_NEMOCLAW_RECOVERY_SOURCE_ENV' in the generated script from
buildHermesDashboardProcessRecoveryScript so the validation step is enforced
prior to sourcing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ac081684-4117-499e-9f4d-7de6520e5aaf

📥 Commits

Reviewing files that changed from the base of the PR and between a531be8 and b239afc.

📒 Files selected for processing (4)
  • src/lib/agent/runtime-hermes-secret-boundary-shape.test.ts
  • src/lib/agent/runtime-recovery-preload.test.ts
  • src/lib/agent/runtime-recovery-preload.ts
  • src/lib/agent/runtime.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/agent/runtime-hermes-secret-boundary-shape.test.ts
  • src/lib/agent/runtime-recovery-preload.ts

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 27433941308
Target ref: b239afc44e8ed38e548135a82801eb059f46124f
Workflow ref: main
Requested jobs: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e
Summary: 1 passed, 0 failed, 1 cancelled, 0 skipped

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts (1)

454-503: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add success assertions to confirm recovery completed.

The test verifies that the security boundary does not refuse (line 490) and that the proxy-env was rewritten (lines 492-495), but does not verify that recovery actually succeeded. Add assertions for:

  • result.status should be 0 (or at least not 1)
  • harness.hermesLaunchMarker should exist to confirm Hermes was launched

Other passing tests (e.g., lines 146-156) check both exit status and launch markers. Without these checks, the test could pass if recovery failed for a different reason before reaching the runtime-env validator.

✅ Proposed fix to add success verification
     try {
       const result = runRecovery({
         ...harness,
         validatorPath: realValidator,
         envFilePath: envFile,
         proxyEnvPath: proxyEnvFile,
       });
+      expect(result.status).toBe(0);
       expect(result.stdout).not.toContain("SECRET_BOUNDARY_REFUSED");
       expect(result.stderr).not.toContain("TELEGRAM_BOT_TOKEN");
+      expect(fs.existsSync(harness.hermesLaunchMarker)).toBe(true);
       const proxyEnv = fs.readFileSync(proxyEnvFile, "utf-8");
       expect(proxyEnv).not.toContain("TELEGRAM_BOT_TOKEN");
       expect(proxyEnv).toContain(harness.preloadTmpSafetyNet);
       expect(proxyEnv).toContain(harness.preloadTmpCiao);
       const log = fs.readFileSync(harness.recoveryLogPath, "utf-8");
       expect(log).not.toContain("[SECURITY] Refusing Hermes startup");
       expect(log).not.toContain("TELEGRAM_BOT_TOKEN");
       expect(log).not.toContain("1234567890:AAExample-RawSecretValueHere");
     } finally {
       removeTempDir(harness.tmp);
     }
🤖 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/agent/runtime-hermes-secret-boundary-behavioural.test.ts` around
lines 454 - 503, Add explicit success assertions after the existing expect
checks: verify the recovery process exited successfully by asserting
result.status is 0 (or at least not 1) and verify Hermes was actually launched
by asserting the launch marker exists (check harness.hermesLaunchMarker via
fs.existsSync or equivalent). Update the test in
runtime-hermes-secret-boundary-behavioural.test.ts (the "does not import a raw
secret..." case that calls runRecovery) to include these two assertions after
reading the log and proxyEnv.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts`:
- Around line 454-503: Add explicit success assertions after the existing expect
checks: verify the recovery process exited successfully by asserting
result.status is 0 (or at least not 1) and verify Hermes was actually launched
by asserting the launch marker exists (check harness.hermesLaunchMarker via
fs.existsSync or equivalent). Update the test in
runtime-hermes-secret-boundary-behavioural.test.ts (the "does not import a raw
secret..." case that calls runRecovery) to include these two assertions after
reading the log and proxyEnv.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3bbdcd3a-5ed5-4bac-bd1b-b913e68b17db

📥 Commits

Reviewing files that changed from the base of the PR and between b239afc and fadd14f.

📒 Files selected for processing (1)
  • src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 27434328394
Target ref: fadd14f29f8185b7a8ab89113d3d64096e1d53c6
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

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 27434730354
Workflow ref: codex/harden-recovery-proxy-env-followup
Requested scenarios: (selector rejected by workflow validation)
Requested jobs: (selector rejected by workflow validation)
Summary: 0 passed, 1 failed, 21 skipped

Job Result
credential-migration-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ❌ failure
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

Failed jobs: generate-matrix. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All jobs passed

Run: 27434781701
Workflow ref: codex/harden-recovery-proxy-env-followup
Requested scenarios: ubuntu-repo-docker-post-reboot-recovery
Requested jobs: (default — all free-standing when no scenarios are requested)
Summary: 2 passed, 0 failed, 20 skipped

Job Result
credential-migration-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ✅ success
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All jobs passed

Run: 27434781643
Workflow ref: codex/harden-recovery-proxy-env-followup
Requested scenarios: (default — all supported)
Requested jobs: gateway-guard-recovery
Summary: 2 passed, 0 failed, 20 skipped

Job Result
credential-migration-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ✅ success
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

@cv

cv commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up on the Vitest E2E selector failure in run 27434730354: that dispatch used both scenarios and jobs together, which the workflow rejects before running tests. It is superseded by the two separate required E2E runs, both green on fadd14f29:

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 27445228792
Target ref: ae0e624f0c4dcadf8310e72d6300791e66e93dc2
Workflow ref: main
Requested jobs: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

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

Failed jobs: issue-2478-crash-loop-recovery-e2e. Check run artifacts for logs.

@cv cv enabled auto-merge (squash) June 12, 2026 22:00
@cv

cv commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

Folded #5365 into this PR and enabled squash auto-merge once the remaining review requirement is satisfied.

What changed after the fold-in:

  • Included test(e2e): accept recovered proxy env #5365's recovered proxy-env fallback test update.
  • Added assertions that recovery validates the proxy env before sourcing it.
  • Hardened the Hermes secret-boundary regression test so it proves recovery actually launches Hermes successfully.
  • Tightened the issue-2478 E2E guard checks to look only at fresh gateway log lines after each recovery attempt, avoiding stale-marker false positives.

Validation run locally:

  • npx prek run --files src/lib/agent/runtime.test.ts src/lib/agent/runtime-hermes-secret-boundary-behavioural.test.ts test/e2e/test-issue-2478-crash-loop-recovery.sh
  • bash -n test/e2e/test-issue-2478-crash-loop-recovery.sh
  • npm run build:cli
  • focused Vitest coverage for recovery/proxy-env and Hermes secret-boundary suites
  • npm run typecheck:cli
  • full npm test

All standard PR checks are green. I also inspected the selective issue-2478 E2E failure from run 27445228792: it failed during install/provider validation with NVIDIA Endpoints HTTP 429s before the recovery scenario executed, while the Hermes secret-boundary selective E2E passed.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

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

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

Failed jobs: issue-2478-crash-loop-recovery-e2e. Check run artifacts for logs.

@copy-pr-bot

copy-pr-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 27448401529
Target ref: ac996e602415231270648f2a4e795e9986780ac9
Workflow ref: main
Requested jobs: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

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

Failed jobs: issue-2478-crash-loop-recovery-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 27449030862
Target ref: 78921d3dd589c063d939e933c715641b44f847a3
Workflow ref: main
Requested jobs: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

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

Failed jobs: issue-2478-crash-loop-recovery-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 27449359195
Target ref: 49de451ff5463b0a19d57738e131bb56362e92c7
Workflow ref: main
Requested jobs: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e,hermes-dashboard-e2e,sandbox-survival-e2e
Summary: 1 passed, 3 failed, 0 cancelled, 0 skipped

Job Result
hermes-dashboard-e2e ❌ failure
hermes-secret-boundary-e2e ✅ success
issue-2478-crash-loop-recovery-e2e ❌ failure
sandbox-survival-e2e ❌ failure

Failed jobs: hermes-dashboard-e2e, issue-2478-crash-loop-recovery-e2e, sandbox-survival-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 27449849361
Target ref: 5e244a3694ec29fa8ed85a70ac430fc1b71b0eab
Workflow ref: main
Requested jobs: issue-2478-crash-loop-recovery-e2e,hermes-secret-boundary-e2e,openclaw-onboard-security-posture-e2e
Summary: 2 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
hermes-secret-boundary-e2e ✅ success
issue-2478-crash-loop-recovery-e2e ✅ success
openclaw-onboard-security-posture-e2e ❌ failure

Failed jobs: openclaw-onboard-security-posture-e2e. Check run artifacts for logs.

@cv cv added the v0.0.65 Release target label Jun 13, 2026
@cv cv disabled auto-merge June 13, 2026 00:15
@cv cv merged commit 09a5c69 into main Jun 13, 2026
31 checks passed
@cv cv deleted the codex/harden-recovery-proxy-env-followup branch June 13, 2026 00:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: security Security controls, permissions, secrets, or hardening v0.0.65 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants