Skip to content

fix(gpu): prefer native OpenShell injection#6142

Merged
ericksoa merged 31 commits into
mainfrom
fix/hermes-gpu-startup-6110
Jul 2, 2026
Merged

fix(gpu): prefer native OpenShell injection#6142
ericksoa merged 31 commits into
mainfrom
fix/hermes-gpu-startup-6110

Conversation

@ericksoa

@ericksoa ericksoa commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Routes ordinary native CDI Linux through OpenShell 0.0.71's native --gpu path instead of the legacy Docker container swap. The legacy path remains available for WSL, Jetson, and explicit NEMOCLAW_DOCKER_GPU_PATCH=1, with its OpenShell supervisor command boundary and rollback diagnostics hardened.

Related Issue

Related to #6110

Changes

  • Use native OpenShell GPU injection by default on ordinary native CDI Linux.
  • Document the NEMOCLAW_DOCKER_GPU_PATCH auto, forced-legacy, and native-routing behavior for ordinary native Linux, Docker Desktop WSL, and Jetson/Tegra.
  • Keep NEMOCLAW_DOCKER_GPU_PATCH=1 as the explicit legacy-swap force control and =0 as the existing native opt-out; Docker Desktop WSL still ignores =0, and Jetson keeps its compatibility default.
  • Preserve OpenShell's supervisor entrypoint on the legacy swap: Docker receives no command tail, while the workload stays in OPENSHELL_SANDBOX_COMMAND.
  • Validate legacy startup tokens before stopping or renaming the original container and serialize extra-placeholder keys as one comma-delimited token.
  • Defer every legacy recreate through the same supervisor-wait/finalize boundary so failed clones are captured before rollback on both create timing paths.
  • Persist only allowlisted/redacted failed-clone topology, state, process, network, and log evidence, with a 10-second total / 2-second per-call budget so diagnostics cannot materially delay rollback.
  • Permit only the canonical OpenShell Docker/Podman TLS key path in the Hermes runtime environment; arbitrary values and persisted .env entries remain rejected.
  • Refresh the Dockerfile integrity pin for the changed validator so production Hermes images fail closed on any later digest drift.
  • Prove native and legacy Docker command boundaries separately, including Ready/CUDA status, supervisor PID 1, placeholder transport, config hashes, no backup-container leak, and inference requests.

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 exact-diff review found no remaining substantive issue after startup-envelope secret redaction, bounded pre-rollback capture, unified finalize ordering, and route-specific live assertions
  • 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)

Local exact-candidate verification at d76f1647a5f354ba04737a6a049b82bfbf6d5454:

  • CLI build and typecheck passed.
  • Hermes GPU support/client/workflow coverage passed 48/48; the built gateway-cleanup module resolves through Node, and runtime cleanup, registration removal, and bind availability remain fail-closed.
  • The shared Docker GPU diagnostic collector owns redaction for every text/JSON artifact and returned summary; direct conventional *_KEY and custom-placeholder canaries, JSON-validity, inspect-before-write, exhausted-budget, and collector-owned top regressions pass.
  • All 12 Docker GPU suites pass 126/126; the exact-head focused E2E-support set passes 39/39, including six process-token self-match regressions, the scrubbed integrity-proof environment, and total forbidden-marker count.
  • Conditional scan, source-shape, test-size, Biome, repository checks, commit hooks, and push typecheck passed for the final harness correction; only the documented macOS-invalid full CLI hook lane was excluded.
  • The forbidden-marker request sensor support suite passed 14/14 and records counts only, never raw request bodies or marker values.
  • OpenShell transport-boundary coverage passed 4/4; Docker GPU command-envelope coverage passed 6/6; extra-placeholder parsing coverage passed 16/16.
  • Hermes validator and wrapper integrity pins match their source SHA256 digests; hadolint and diff checks pass.
  • Hermes startup/boundary coverage passed 43/43 locally; the Linux-only wrapper cases are delegated to exact-head CI.
  • The full local CLI hook is not a valid gate on this macOS Node 22 host: unchanged a1fc52c7 TypeScript entrypoints fail through the CommonJS preload with ERR_UNKNOWN_FILE_EXTENSION; exact-head Linux CI remains required.
  • Hermes runtime-guard plus current-main docs regression tests: 24/24 passed.
  • Hermes workflow-boundary test passed.
  • Project-boundary, project-membership, test-title, source-shape, test-size, targeted Biome, and diff checks passed.
  • npm run docs:sync-agent-variants, npm run docs:check-agent-variants, and npm run docs pass; Fern reports 0 errors and 2 existing warnings.

Live A/B evidence:

  • Forced legacy swap at 97e3e7e1: run 28554699811 reproduced sustained OpenShell Error followed by safe rollback. It also exposed and now closes a lifecycle instrumentation gap: the post-create ensureApplied() branch bypassed pre-rollback capture.
  • Native OpenShell route at signed diagnostic SHA 15f50182: run 28555110558 completed onboarding with exit 0, reached Phase: Ready, reported CUDA verified, and sent authenticated Hermes chat-completions requests to the hermetic inference endpoint. The job's only failure was the now-fixed test regex not stripping ANSI around Ready.
  • Prior native evidence at 7cb219d9: full run 28559814959 and second pass 28559816026 both reached Ready/CUDA with clean runtime and teardown; their Hermes proof stopped on the now-fixed ANSI matcher before downstream assertions.
  • Prior forced-legacy diagnostic on production parent a1fc52c7 plus workflow-only child 6d0cf6a5: run 28561607207 selected the legacy swap and rolled back cleanly, but failed because the Hermes boundary rejected the driver-owned OpenShell OPENSHELL_TLS_KEY path. Candidate 54cf259d adds an exact runtime-only allowance with negative boundary tests.
  • Prior exact-head set at a1fc52c7: run 28561548749 proved the GPU and security companion jobs, while Hermes GPU stopped at a sandbox-user /proc permission probe after Ready/CUDA. Candidate 54cf259d keeps the same proof but runs it as root and restricts the match to the exact nemoclaw-start process.
  • Prior second native pass at a1fc52c7: run 28561555945 reproduced only the same harness permission failure after Ready/CUDA, correct PID 1 topology, authenticated inference, zero forbidden-marker matches, and clean teardown.
  • Superseded six-job set at 54cf259d: run 28564960504 exposed the stale Dockerfile validator digest and was canceled before runtime proof. Candidate 970803a4 updates the integrity pin, retained by final head c5a67c4c.
  • Superseded second native pass at 54cf259d: run 28564973806 was canceled during pre-cleanup and supplies no acceptance evidence.
  • Superseded forced-legacy proof on production parent 54cf259d plus child 69f4e1b2: run 28564983760 was canceled during pre-cleanup and supplies no acceptance evidence.
  • Superseded six-job set at 970803a4: run 28565197328 was canceled before acceptance execution when the canonical placeholder-format advisor fix advanced the head.
  • Superseded second native pass at 970803a4: run 28565207911 was canceled before runner assignment and supplies no acceptance evidence.
  • Superseded forced-legacy proof on production parent 970803a4 plus child b4d5679e: run 28565222881 was canceled before runner assignment and supplies no acceptance evidence.
  • Superseded six-job set at 7335903b: run 28565576066 was intentionally canceled when the documentation gap advanced the candidate; the root-entrypoint smoke passed, but the remaining lanes provide no complete acceptance proof.
  • Superseded second native pass at 7335903b: run 28565587094 was canceled before acceptance execution and supplies no acceptance evidence.
  • Superseded forced-legacy proof on production parent 7335903b plus child 091e16fd: run 28565603460 was canceled before acceptance execution and supplies no acceptance evidence.
  • Superseded six-job set at c5a67c4c: run 28566083673 reached the native GPU/runtime proofs before the obsolete raw strict-hash assertion failed; messaging independently hit the process-probe self-match fixed by merged test(e2e): prevent process-token probe self-matches #6167. GPU, root-entrypoint, secret-boundary, and credential companion lanes passed.
  • Superseded second native pass at c5a67c4c: run 28566083641 proved native routing, Ready/CUDA, nvidia-smi, /proc, cuInit(0)=0, PID 1, authenticated inference, and cleanup, then failed only the obsolete raw strict-hash assertion.
  • Superseded forced-legacy proof on production parent c5a67c4c plus child 48c46a7f: run 28566083589 proved the same runtime boundary on the legacy route, then failed only the obsolete raw strict-hash assertion.
  • Superseded six-job set at a04a70ac: run 28568069499 exposed a pre-onboarding harness defect: direct Vitest import of the production cleanup helper could not resolve its lazy CommonJS TypeScript dependencies. Companion results do not count as final-head evidence.
  • Superseded second native pass at a04a70ac: run 28568069558 failed at the same pre-onboarding cleanup boundary and supplies no runtime acceptance evidence.
  • Superseded forced-legacy proof on production parent a04a70ac plus child 085a3b7d: run 28568069530 failed at the same pre-onboarding cleanup boundary and supplies no runtime acceptance evidence.
  • Superseded six-job set at 6ac4ebc8: run 28568490864 exposed a clean-runner preinstall edge: the compiled cleanup child was invoked before OpenShell existed and failed before onboarding. Companion results do not count as final-head evidence.
  • Superseded second native pass at 6ac4ebc8: run 28568494928 failed at the same pre-onboarding cleanup boundary and supplies no runtime acceptance evidence.
  • Superseded forced-legacy proof on production parent 6ac4ebc8 plus child 5d3742a7: run 28568501430 failed at the same pre-onboarding cleanup boundary and supplies no runtime acceptance evidence.
  • Superseded six-job set at 65b06d64: run 28568954862 passed all six jobs, but the candidate advanced to close the advisor-confirmed shared diagnostic-redaction boundary and two proof-hardening review threads.
  • Superseded second native pass at 65b06d64: run 28568959028 passed the full native runtime proof but is not final-head evidence.
  • Superseded forced-legacy proof on production parent 65b06d64 plus child 2c6dca1b: run 28568966557 passed but is not final-parent evidence.
  • Final six-job exact-head set at d76f1647: run 28601346031 passed all six requested jobs. Native GPU, Hermes startup, root-entrypoint, secret-boundary, credential-sanitization, and messaging proofs are green; all 21 messaging raw-token surface probes are ABSENT, and every cleanup record has zero failures.
  • Final second native Hermes GPU pass at d76f1647: run 28601348023 passed 9/9 assertions. Artifact 8043702467 (sha256:0ef929fa2478f5c9579ad2f282c46de8fe4d6eefb04acb062de1af29b4eb002c) proves native routing, Ready/CUDA, nvidia-smi, /proc, successful cuInit(0), OpenShell PID 1, one container/no backup, authenticated inference with zero forbidden-marker matches, and clean teardown.
  • Final failed-clone rollback proof checks out exact production SHA d76f1647 from signed workflow-only child 4c49b5bc: run 28602166456 passed. Artifact 8044114375 (sha256:b5cff9cc7e7cf361f55e074a265c8cfefd3e6dc21ad0d300b140d2a749cde00b) records clone exit 137 with failure_kind=patched_container_failed and rolled_back=no before finalize, then rolled_back=yes, exactly one running original container, no backup leak, guard-observed clone removal, clean canary scans, and clean fixture teardown.
  • Final forced-legacy success proof on exact production parent d76f1647 plus signed workflow-only child 078a372d: run 28603335692 passed 9/9 assertions. Artifact 8044550700 (sha256:56d97c5caa8536ebff735ff600399ac7fafa2fed71206de1f5470e7d15549f6f) proves gpuRoute=legacy-patch, --device nvidia.com/gpu=all, Ready/CUDA with all three GPU probes, correct OpenShell PID 1/command envelope, one container/no backup, integrity and negative guard checks, two authenticated inference requests with zero forbidden-marker matches, a clean artifact canary scan, and clean teardown.

Source-of-truth review for the retained compatibility path:

  • Invalid state: the legacy swap temporarily leaves a stopped backup and running clone with the same OpenShell sandbox ID.
  • Source boundary: OpenShell's Docker driver reconciles container summaries into a map keyed only by sandbox ID; 0.0.71 can let the stopped backup overwrite the running clone and drive the gateway into terminal Error.
  • Source-fix constraint: the NemoClaw-supported OpenShell release does not contain deterministic active-container selection. The focused source fix is open as NVIDIA/OpenShell#2116 and passes 96/96 Docker-driver tests, strict clippy, and formatting, but is not yet released or pinned here.
  • Regression coverage: routing tests pin native auto / forced legacy / WSL / Jetson behavior; recreate tests pin capture-before-finalize on both create timing paths; the secret canary uses the actual single OPENSHELL_SANDBOX_COMMAND=env ... envelope; the live test pins native and legacy runtime topology separately.
  • Removal condition: remove the legacy swap and its rollback/diagnostic modules after WSL and Jetson are proven on native OpenShell GPU injection and the supported OpenShell floor contains deterministic duplicate-container reconciliation.
  • WSL boundary: Docker Desktop WSL does not expose a usable native CDI route to this flow, so WSL retains the compatibility path and ignores NEMOCLAW_DOCKER_GPU_PATCH=0; routing tests lock that behavior. Remove it when Docker Desktop exposes usable nvidia.com/gpu CDI devices to the WSL distro.
  • Jetson boundary: Tegra /dev/nvmap and /dev/nvhost-* device ownership requires host group propagation for the non-root sandbox user; group-add tests lock that behavior. Remove it only when the platform/runtime supplies equivalent access without the compatibility recreate.

Diagnostic redaction boundary:

  • Source-of-truth invariant: collectDockerGpuPatchDiagnostics() constructs the trusted per-bundle redactor, discovers conventional and custom-placeholder values from every known/discovered full inspect before writing, recursively redacts JSON values, and publishes every summary, Docker, OpenShell, and pre-rollback top artifact through that boundary.
  • Bounded pre-rollback path: the caller contributes only additive values discovered from the failed clone before snapshot capture so the shared 10-second budget cannot hide opaque values; the collector still performs its own discovery and owns every write. Direct raw-caller and exhausted-budget regressions scan all artifacts and returned summaries.
  • Removal condition: remove the additive pre-rollback discovery only when the shared collector can own snapshot capture inside the same budget without delaying rollback.

Advisor architecture and follow-up rationale:

  • docker-gpu-patch.ts grows 58 lines to keep token validation before container mutation and bounded failed-clone capture before rollback. Splitting this security-critical ordering during the release-blocker fix would add cross-module state transfer; extract it when the legacy swap is retired after WSL and Jetson native proof.
  • docker-gpu-local-inference.test.ts grows 32 lines so bridge-probe routing assertions stay beside the behavior under test. Extract a bridge-probe module and focused test file if that surface grows again.
  • docker-gpu-local-inference.ts grows 15 lines to keep the bridge-probe/host-network decision beside its caller-facing contract; extract it with the tests if that surface grows again.
  • docker-gpu-patch.test.ts grows 13 lines and remains below 1,350 lines; split the mode-routing cases on the next growth.
  • The live fixture now supplies the canonical comma-delimited placeholder transport. Whitespace compatibility remains covered by parser unit tests and the messaging-provider scenario; the live proof intentionally matches the exact canonical startup environ token.
  • Dedicated OPENSHELL_TLS_KEY tests prove exact runtime acceptance, arbitrary/PEM/relative/near-miss rejection, persisted .env rejection, and continued rejection of supervisor identity tokens. The exact allowed path is sourced from NVIDIA/OpenShell@v0.0.71 (a242f84bb367d6df7d4d133e95a93857406c67f7), where driver_utils.rs::TLS_KEY_MOUNT_PATH defines /etc/openshell/tls/client/tls.key and the Docker/Podman drivers inject it.

This PR does not claim #6110 resolved until the reporter-class DGX Spark aarch64 or DGX Station GB300 NVIDIA Endpoints path passes. No such runner is declared in this repository, and organization runner inventory is not visible with the current permissions. Missing reporter hardware is an external acceptance blocker, not a passing result.

The #6155 docs regression fix and current main through 9fe45362 are integrated. A refreshed pairwise merge-tree audit at d76f1647 is clean with #5595 and #6153. #5876 directly conflicts in e2e.yaml and related Hermes/docs/workflow-boundary files; its resolution must union hermes-gpu-startup and mcp-bridge-dev selectors/result summaries and recompute uploader validation. #6020 already conflicts with current main and also overlaps #6142 outside e2e.yaml; #6053 is mergeable with main but conflicts pairwise in the uploader boundary. Those later branches must preserve #6142's explicit-only inventory and artifact contracts during retargeting; #6142 itself remains mergeable/CLEAN.


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

Summary by CodeRabbit

  • New Features
    • Strengthened Hermes GPU startup proof and managed startup integrity assertions, plus added a skipped-by-default GPU live E2E run for startup readiness.
  • Bug Fixes
    • Tightened PID 1 identity validation to block runtime mutation under a foreign PID 1.
    • Improved Docker GPU/OpenShell sandbox command and placeholder handling; enhanced GPU failure diagnostics with safer redaction.
  • Documentation
    • Refined GPU passthrough and NEMOCLAW_DOCKER_GPU_PATCH guidance across native Linux, Docker Desktop WSL, and Jetson/Tegra.
  • Tests
    • Expanded unit/E2E coverage for placeholder parsing, readiness refusal, env/secret boundary enforcement, and diagnostic redaction.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa added v0.0.72 Release target bug-fix PR fixes a bug or regression area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery integration: hermes Hermes integration behavior labels Jul 1, 2026
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR tightens Hermes startup and environment-boundary checks, updates Docker GPU patch selection and diagnostics, adds Hermes GPU startup proof/live E2E coverage, wires a new workflow job into validation, and updates related docs and tests.

Changes

Hermes GPU startup validation

Layer / File(s) Summary
PID 1 readiness guard
agents/hermes/runtime-config-guard.py, agents/hermes/start.sh, test/hermes-runtime-config-guard.test.ts
_pid1_is_nemoclaw_start() now rejects OpenShell supervisor cmdlines even when they contain nemoclaw-start, the startup comment wording is updated, and the runtime-config-guard test covers the polluted supervisor argv case.
Docker GPU command contract
src/lib/onboard/extra-placeholder-keys.ts, src/lib/onboard/docker-gpu-patch.ts, src/lib/onboard/docker-gpu-patch.test.ts, src/lib/onboard/docker-gpu-patch-validation.test.ts, src/lib/onboard/extra-placeholder-keys.test.ts, src/lib/onboard/docker-gpu-local-inference.ts, src/lib/onboard/docker-gpu-local-inference.test.ts, src/lib/onboard/onboard.ts, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx
OpenShell sandbox command serialization rejects empty or whitespace-bearing tokens, clone command args follow the OPENSHELL_SANDBOX_COMMAND contract, GPU patch selection uses host/platform-aware gating, and EXTRA_PLACEHOLDER_KEYS_ENV is serialized with comma-separated keys and covered by updated tests and docs.
GPU diagnostics redaction
src/lib/onboard/docker-gpu-diagnostic-redaction.ts, src/lib/onboard/docker-gpu-diagnostic-redaction.test.ts, src/lib/onboard/docker-gpu-patch.ts
Docker GPU diagnostics now discover sensitive values, redact inspect and log artifacts, and apply the redaction path through diagnostics collection tests.
Pre-rollback diagnostics
src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts, src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts, src/lib/onboard/docker-gpu-sandbox-create.ts, src/lib/onboard/docker-gpu-sandbox-create.test.ts, src/lib/onboard/docker-gpu-sandbox-create-diagnostics.test.ts
captureDockerGpuPreRollbackDiagnostics captures Docker GPU failure diagnostics, and sandbox-create wiring now invokes it before rollback with tests covering the success, failure, and injection paths.
GPU startup proof helper
test/e2e/live/hermes-gpu-startup-proof.ts, test/e2e/live/hermes-gpu-startup.test.ts, test/e2e/live/hermes-gpu-startup-integrity.ts, test/e2e/support/hermes-gpu-startup-integrity.test.ts, test/e2e/fixtures/fake-openai-compatible.ts, test/e2e/lib/fake-openai-compatible-api.mts, test/e2e/support/hosted-inference.test.ts
The new proof helper validates Hermes GPU startup logs, sandbox readiness, PID 1 topology, placeholder environment round-trips, startup hashes, and Docker container state, while the live test adds forbidden-marker tracking and fake OpenAI request assertions.
GPU workflow boundary validation
tools/e2e/hermes-gpu-startup-workflow-boundary.mts, tools/e2e/workflow-boundary.mts, test/e2e/support/hermes-workflow-boundary.test.ts, .github/workflows/e2e.yaml, test/e2e/support/upload-e2e-artifacts-workflow-boundary.test.ts, tools/e2e/upload-e2e-artifacts-workflow-boundary.mts, test/e2e/support/jetson-workflow-boundary.test.ts
A dedicated validator checks the hermes-gpu-startup job’s runner, gating, timeout, env values, secret exposure, and required test step, and the shared boundary validator and coverage test include it. The E2E workflow adds hermes-gpu-startup, marks it as explicit-only, includes it in PR reporting, and updates the workflow-boundary counts and expectations for the added job.
Hermes runtime environment boundaries
agents/hermes/validate-env-secret-boundary.py, agents/hermes/Dockerfile, test/hermes-gateway-wrapper.test.ts, test/hermes-openshell-runtime-env-boundary.test.ts
The Hermes runtime env validator allowlists the canonical OpenShell TLS key path, the build hash is updated, and the gateway wrapper plus runtime-env tests enforce the boundary for canonical and noncanonical OpenShell TLS inputs.

Estimated code review effort: 5 (Critical) | ~120 minutes
Suggested reviewers: jyaunches, cjagwani

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: preferring native OpenShell GPU injection over the legacy Docker patch path.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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/hermes-gpu-startup-6110

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

@github-code-quality

github-code-quality Bot commented Jul 1, 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 d76f164 +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/blueprint/ssrf.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 69%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File d76f164 +/-
src/lib/actions...dbox/rebuild.ts 82%
src/lib/actions...all/run-plan.ts 80%
src/lib/state/o...oard-session.ts 80%
src/lib/shields/index.ts 75%
src/lib/state/sandbox.ts 73%
src/lib/onboard...er-gpu-patch.ts 69%
src/lib/onboard/preflight.ts 69%
src/lib/actions...licy-channel.ts 58%
src/lib/policy/index.ts 56%
src/lib/onboard.ts 20%

Updated July 02, 2026 15:28 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: Add or justify PRA-T1 and any related test follow-ups.
Open items: 0 required · 0 warnings · 0 suggestions · 5 test follow-ups
Since last review: 0 prior items resolved · 0 still apply · 0 new items found

Action checklist

  • 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: Runtime validation
  • PRA-T4 Add or justify test follow-up: Acceptance clause
  • PRA-T5 Add or justify test follow-up: Acceptance clause
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 — Identify exact-head runtime validation that ordinary native OpenShell GPU routing reaches Ready/CUDA without invoking the legacy Docker container-swap path.. Unit/static coverage is strong and behavior-specific, but the changed surfaces include Docker/OpenShell sandbox lifecycle, Hermes image integrity, startup process topology, workflow routing, and live GPU/inference behavior where exact-head runtime validation is the best confidence signal.
  • PRA-T2 Runtime validation — Identify exact-head runtime validation that forced legacy Docker GPU routing captures failed-clone diagnostics before rollback and leaves no backup-container leak.. Unit/static coverage is strong and behavior-specific, but the changed surfaces include Docker/OpenShell sandbox lifecycle, Hermes image integrity, startup process topology, workflow routing, and live GPU/inference behavior where exact-head runtime validation is the best confidence signal.
  • PRA-T3 Runtime validation — Identify exact-head Hermes image build validation proving NEMOCLAW_HERMES_VALIDATOR_SHA256 matches the installed validate-hermes-env-secret-boundary.py.. Unit/static coverage is strong and behavior-specific, but the changed surfaces include Docker/OpenShell sandbox lifecycle, Hermes image integrity, startup process topology, workflow routing, and live GPU/inference behavior where exact-head runtime validation is the best confidence signal.
  • PRA-T4 Acceptance clause — Related to [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 — add test evidence or identify existing coverage. The deterministic validation context reported linkedIssues: [], so no literal issue clauses or issue comments were available to map. The diff and tests do cover the PR's [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110-themed startup-command, supervisor-boundary, rollback-diagnostic, and redaction paths.
  • PRA-T5 Acceptance clause — Prove native and legacy Docker command boundaries separately, including Ready/CUDA status, supervisor PID 1, placeholder transport, config hashes, no backup-container leak, and inference requests. — add test evidence or identify existing coverage. Static/unit coverage and the new live harness cover command-envelope, topology, placeholder, diagnostics, workflow, and inference assertions. The advisor does not report external E2E pass/fail status, so exact-head runtime validation remains listed under testDepth suggestedTests.

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.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: hermes-gpu-startup, gpu-e2e, gpu-double-onboard, jetson-nvmap-gpu, hermes-sandbox-secret-boundary, hermes-e2e, cloud-onboard
Optional E2E: diagnostics, inference-routing, onboard-repair

Dispatch hint: hermes-gpu-startup,gpu-e2e,gpu-double-onboard,jetson-nvmap-gpu,hermes-sandbox-secret-boundary,hermes-e2e,cloud-onboard

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • hermes-gpu-startup (high): Direct live coverage for the new explicit-only GPU runner job and the changed Hermes GPU startup proof. It exercises install/onboard, GPU sandbox create, selected GPU route, OpenShell supervisor startup identity, Hermes runtime config guard, placeholder isolation, and fake OpenAI-compatible inference from a real GPU sandbox.
  • gpu-e2e (high): Required because the PR changes GPU onboarding and sandbox-create/patch routing. This validates the existing live GPU onboard path outside the new Hermes-specific proof and catches regressions in general GPU passthrough behavior.
  • gpu-double-onboard (high): Required for changed GPU recreate/patch/rollback lifecycle code. A double-onboard GPU flow is the best existing live check for idempotency, recreate safety, stale gateway cleanup, and patched container replacement behavior.
  • jetson-nvmap-gpu (high): Required because the Docker GPU patch behavior and documentation explicitly touch Jetson/Tegra routing and device-group propagation. This explicit-only live job is the existing hardware-specific coverage for nvmap/nvhost GPU access.
  • hermes-sandbox-secret-boundary (medium): Required for changes to agents/hermes/validate-env-secret-boundary.py, Dockerfile validator hash, runtime-config guard authorization, and start.sh. It validates the real Hermes sandbox secret-boundary contract rather than only unit-level parser behavior.
  • hermes-e2e (high): Required for Hermes Docker/startup changes that can affect ordinary hosted Hermes onboarding and assistant runtime even without GPU. This verifies the real install/onboard/Hermes user flow with hosted inference.
  • cloud-onboard (high): Required because src/lib/onboard.ts changed and the PR alters onboarding decisions. This keeps the full hosted onboarding path covered for non-GPU users and detects regressions not exercised by the GPU-specific jobs.

Optional E2E

  • diagnostics (medium): Useful adjacent confidence for changed Docker GPU diagnostic redaction and pre-rollback diagnostic artifacts; not as targeted as the GPU jobs but can catch artifact/debug-regression fallout.
  • inference-routing (medium): Optional because fake OpenAI-compatible and hosted-inference support changed. Run if reviewers want extra confidence that provider route plumbing was not affected beyond the Hermes GPU startup fake endpoint.
  • onboard-repair (high): Optional recovery confidence for changed sandbox lifecycle and rollback/repair-adjacent diagnostics. The onboarding resume rule does not appear to apply because the changed files are GPU create/patch paths rather than resume state-machine orchestration.

New E2E recommendations

  • Docker Desktop WSL GPU compatibility path (high): The PR changes platform defaults so Docker Desktop WSL ignores NEMOCLAW_DOCKER_GPU_PATCH=0 and must use the compatibility patch, but existing live jobs appear to run on native Linux/Jetson runners rather than a WSL Docker Desktop GPU environment.
    • Suggested test: Add a WSL Docker Desktop GPU live E2E that onboards Hermes with NEMOCLAW_SANDBOX_GPU=1, verifies the compatibility patch path is selected, and proves Hermes reaches Ready with GPU access and stable supervisor startup.
  • Forced legacy GPU patch on ordinary native Linux (medium): hermes-gpu-startup covers the default native OpenShell route on the GPU runner, while the test file has support for NEMOCLAW_DOCKER_GPU_PATCH=1 but the workflow does not expose a separate forced-legacy matrix/job.
    • Suggested test: Add a second hermes-gpu-startup workflow variant or matrix entry with NEMOCLAW_DOCKER_GPU_PATCH=1 on the GPU runner to keep the legacy Docker container-swap path covered.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: hermes-gpu-startup,gpu-e2e,gpu-double-onboard,jetson-nvmap-gpu,hermes-sandbox-secret-boundary,hermes-e2e,cloud-onboard

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: hermes-gpu-startup, e2e-all, onboard-resume, onboard-repair
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-gpu-startup
  • gh workflow run e2e.yaml --ref <pr-head-ref>
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • hermes-gpu-startup: Focused free-standing E2E job wired for changed live test test/e2e/live/hermes-gpu-startup.test.ts.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-gpu-startup
  • e2e-all: The PR changes the shared E2E workflow machinery and shared E2E fixtures, including matrix/free-standing job selection in .github/workflows/e2e.yaml and the fake OpenAI-compatible fixture used by multiple live E2E surfaces. Policy requires the full E2E fan-out for shared workflow/fixture changes.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref>
  • onboard-resume: The PR changes onboarding orchestration and GPU sandbox creation/patching code in src/lib/onboard.ts and src/lib/onboard/docker-gpu-*. The onboarding resume rule requires onboard-resume for changes that can affect onboarding state transitions or resumed live onboarding execution.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • onboard-repair: The same onboarding/GPU orchestration changes can affect repair or backstop behavior from persisted onboarding sessions, so onboard-repair is required alongside onboard-resume rather than optional.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair

Optional E2E targets

  • None.

Relevant changed files

  • .github/workflows/e2e.yaml
  • agents/hermes/Dockerfile
  • agents/hermes/runtime-config-guard.py
  • agents/hermes/start.sh
  • agents/hermes/validate-env-secret-boundary.py
  • src/lib/onboard.ts
  • src/lib/onboard/docker-gpu-diagnostic-redaction.ts
  • src/lib/onboard/docker-gpu-local-inference.ts
  • src/lib/onboard/docker-gpu-patch.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts
  • src/lib/onboard/docker-gpu-sandbox-create.ts
  • src/lib/onboard/extra-placeholder-keys.ts
  • test/e2e/fixtures/fake-openai-compatible.ts
  • test/e2e/lib/fake-openai-compatible-api.mts
  • test/e2e/live/hermes-gpu-startup-integrity.ts
  • test/e2e/live/hermes-gpu-startup-proof.ts
  • test/e2e/live/hermes-gpu-startup.test.ts
  • test/e2e/support/hermes-gpu-startup-integrity.test.ts
  • test/e2e/support/hermes-workflow-boundary.test.ts
  • test/e2e/support/hosted-inference.test.ts
  • test/e2e/support/jetson-workflow-boundary.test.ts
  • test/e2e/support/upload-e2e-artifacts-workflow-boundary.test.ts
  • tools/e2e/hermes-gpu-startup-workflow-boundary.mts
  • tools/e2e/upload-e2e-artifacts-workflow-boundary.mts
  • tools/e2e/workflow-boundary.mts

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-4: docker-gpu-patch.ts monolith growth +58 lines exceeds blocker threshold; then add or justify PRA-T1.
Open items: 6 required · 9 warnings · 8 suggestions · 8 test follow-ups
Since last review: 2 prior items resolved · 5 still apply · 8 new items found

Action checklist

  • PRA-4 Fix: docker-gpu-patch.ts monolith growth +58 lines exceeds blocker threshold in src/lib/onboard/docker-gpu-patch.ts:1
  • PRA-5 Fix: docker-gpu-local-inference.test.ts monolith growth +32 lines exceeds blocker threshold in src/lib/onboard/docker-gpu-local-inference.test.ts:1
  • PRA-6 Fix: Concurrent e2e.yaml modifications across 9 open PRs create merge conflict risk in .github/workflows/e2e.yaml:15
  • PRA-7 Fix: Missing isolated unit tests for pre-rollback diagnostics redaction logic (3 injection vectors) in src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1
  • PRA-8 Fix: Pre-rollback diagnostics redaction wrapper missing SOURCE_OF_TRUTH_REVIEW comment in src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1
  • PRA-9 Fix: OPENSHELL_TLS_KEY exact path allowance lacks OpenShell version citation in agents/hermes/validate-env-secret-boundary.py:48
  • PRA-1 Resolve or justify: Source-of-truth review needed: docker-gpu-pre-rollback-diagnostics.ts
  • PRA-2 Resolve or justify: Source-of-truth review needed: docs/reference/commands-nemohermes.mdx:365
  • PRA-3 Resolve or justify: Source-of-truth review needed: docs/reference/commands-nemohermes.mdx:367
  • PRA-10 Resolve or justify: workflow_dispatch explicit-only jobs list not validated against generate-matrix inventory in tools/e2e/workflow-boundary.mts:1
  • PRA-11 Resolve or justify: shouldSkipGpuBridgeProbe caller passes incomplete options in src/lib/onboard.ts:1893
  • PRA-12 Resolve or justify: docker-gpu-patch.test.ts monolith growth +13 lines exceeds warning threshold in src/lib/onboard/docker-gpu-patch.test.ts:1
  • PRA-13 Resolve or justify: start.sh comment should clarify dual-mode authorization for future auditors in agents/hermes/start.sh:1620
  • PRA-14 Resolve or justify: Proof assertion uses exact string match instead of parser-compatible split for OPENSHELL_SANDBOX_COMMAND transport format in test/e2e/live/hermes-gpu-startup-proof.ts:135
  • PRA-15 Resolve or justify: docker-gpu-local-inference.ts monolith growth +15 lines (warning threshold 1-19) in src/lib/onboard/docker-gpu-local-inference.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: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Missing isolated unit tests for pre-rollback diagnostics redaction logic (3 injection vectors)
  • PRA-T7 Add or justify test follow-up: docker-gpu-patch.test.ts monolith growth +13 lines exceeds warning threshold
  • PRA-T8 Add or justify test follow-up: No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route
  • PRA-16 In-scope improvement: No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route in test/e2e/live/hermes-gpu-startup.test.ts:1
  • PRA-17 In-scope improvement: Behavior change: shouldApplyDockerGpuPatch defaults to native OpenShell GPU injection on Linux in src/lib/onboard/docker-gpu-patch.ts:540
  • PRA-18 In-scope improvement: Docker Desktop WSL compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW in docs/reference/commands-nemohermes.mdx:365
  • PRA-19 In-scope improvement: Jetson/Tegra compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW in docs/reference/commands-nemohermes.mdx:367
  • PRA-20 In-scope improvement: Documentation consistency: troubleshooting.mdx matches commands-nemohermes.mdx for GPU routing in docs/reference/troubleshooting.mdx:1528
  • PRA-21 In-scope improvement: New focused validation test file for [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix — well-scoped addition in src/lib/onboard/docker-gpu-patch-validation.test.ts:1
  • PRA-22 In-scope improvement: E2E_DEFAULT_ENABLED single-use config could be constant in .github/workflows/e2e.yaml:1588
  • PRA-23 In-scope improvement: Simplify E2E_DEFAULT_ENABLED single-use config to constant in .github/workflows/e2e.yaml:1588

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 architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-3 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-4 Required architecture src/lib/onboard/docker-gpu-patch.ts:1 Extract GPU mode selection (selectDockerGpuPatchMode), clone args building (buildDockerGpuCloneRunArgs), and recreate orchestration (recreateOpenShellDockerSandboxWithGpu) into separate modules in a follow-up refactoring PR. Document as a follow-up task in this PR with a linked issue.
PRA-5 Required architecture src/lib/onboard/docker-gpu-local-inference.test.ts:1 Extract bridge probe skipping logic and its tests into a separate module/test file (e.g., docker-gpu-bridge-probe.ts / docker-gpu-bridge-probe.test.ts). Document as follow-up task in this PR.
PRA-6 Required workflow .github/workflows/e2e.yaml:15 Coordinate with overlapping PR authors to resolve merge conflicts. After merge, run workflow-inventory.mts and verify explicit_only_jobs_csv matches the workflow_dispatch.jobs.description text.
PRA-7 Required tests src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1 Add unit tests in docker-gpu-pre-rollback-diagnostics.test.ts that inject known secret canaries through all three vectors and verify redaction in all six output sinks (summary.txt, patched-container-state.json, docker-ps.txt, docker-inspect.json, docker-logs.txt, openshell-*.txt).
PRA-8 Required architecture src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1 Add SOURCE_OF_TRUTH_REVIEW comment in docker-gpu-pre-rollback-diagnostics.ts and docker-gpu-diagnostic-redaction.ts documenting all five elements. The invalid state is secret leakage in diagnostic artifacts; source is docker inspect/openshell output; cannot be fixed at source because Docker/OpenShell don't redact; regression test is docker-gpu-diagnostic-redaction.test.ts; removable when OpenShell/Docker add native secret redaction.
PRA-9 Required security agents/hermes/validate-env-secret-boundary.py:48 Add a comment citing the OpenShell version/commit that establishes this contract (e.g., 'OpenShell 0.0.71 Docker/Podman supervisor TLS mount path at /etc/openshell/tls/client/tls.key'). Verify no other TLS key paths are ever injected.
PRA-10 Resolve/justify architecture tools/e2e/workflow-boundary.mts:1 Add a validation step in tools/e2e/workflow-boundary.mts or hermes-gpu-startup-workflow-boundary.mts that parses workflow_dispatch.jobs.description and asserts it matches generate-matrix explicit_only_jobs_csv output.
PRA-11 Resolve/justify security src/lib/onboard.ts:1893 Fix the caller in onboard.ts:1893 to pass { dockerDriverGateway: true, dockerDesktopWsl: false } explicitly, or add a comment documenting that missing keys default to false safely. Verify resolveDockerDesktopWsl handles undefined correctly.
PRA-12 Resolve/justify tests src/lib/onboard/docker-gpu-patch.test.ts:1 Document as follow-up task in this PR. Current growth is from #6110 security fix tests. Split the mode-routing cases on the next growth.
PRA-13 Resolve/justify correctness agents/hermes/start.sh:1620 Update the comment to explicitly mention both authorization branches: PID 1 direct child (cold start) and startup owner's direct child (runtime config guard calls from PID 1 lifecycle handler).
PRA-14 Resolve/justify correctness test/e2e/live/hermes-gpu-startup-proof.ts:135 Update the proof to split on whitespace including U+0085 (using the same regex as the serializer: /[\s\u0085]+/u), then assert the expected keys are present.
PRA-15 Resolve/justify architecture src/lib/onboard/docker-gpu-local-inference.ts:1 Review whether extraction is feasible. The network downgrade logic could be extracted to a separate module if it grows further.
PRA-16 Improvement tests test/e2e/live/hermes-gpu-startup.test.ts:1 Add a CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 in the hermes-gpu-startup job definition (or a separate job variant) to exercise the legacy patch route.
PRA-17 Improvement architecture src/lib/onboard/docker-gpu-patch.ts:540 Document this behavior change in release notes/migration guide. Verify hermes-gpu-startup live test covers both routes (it does via FORCE_LEGACY_GPU_PATCH env var). Ensure operators know about NEMOCLAW_DOCKER_GPU_PATCH=1 escape hatch.
PRA-18 Improvement scope docs/reference/commands-nemohermes.mdx:365 Add SOURCE_OF_TRUTH_REVIEW comment in docs/reference/commands-nemohermes.mdx:365 documenting: (1) invalid state = Docker Desktop WSL advertises CDI dirs but --device nvidia.com/gpu=all unusable, (2) source = Docker Desktop WSL integration, (3) cannot fix in this PR = upstream Docker Desktop issue, (4) regression test = manual verification on WSL, (5) removable when Docker Desktop exposes usable nvidia.com/gpu CDI specs in WSL.
PRA-19 Improvement scope docs/reference/commands-nemohermes.mdx:367 Add SOURCE_OF_TRUTH_REVIEW comment in docs/reference/commands-nemohermes.mdx:367 documenting: (1) invalid state = Tegra device nodes owned by non-root group, (2) source = Jetson/Tegra board support package, (3) cannot fix in this PR = hardware/BSP constraint, (4) regression test = CI on Jetson hardware, (5) removable when Tegra device nodes default to root:video or similar accessible group.
PRA-20 Improvement correctness docs/reference/troubleshooting.mdx:1528 No action needed. The documentation is consistent.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-4 Required — docker-gpu-patch.ts monolith growth +58 lines exceeds blocker threshold

  • Location: src/lib/onboard/docker-gpu-patch.ts:1
  • Category: architecture
  • Problem: docker-gpu-patch.ts grew from 1840 to 1898 lines (+58), exceeding the 20-line blocker threshold. Growth stems from validation-before-mutation reordering, commandArgs logic change for empty Config.Cmd, new token validation, and pre-rollback diagnostics integration. GPU mode selection (selectDockerGpuPatchMode), clone args building (buildDockerGpuCloneRunArgs), and recreate orchestration (recreateOpenShellDockerSandboxWithGpu) remain coupled in one module.
  • Impact: Monolithic module couples security-critical token validation, container mutation ordering, and diagnostic capture — increases risk of regression when modifying any subsystem and blocks safe parallel development.
  • Required action: Extract GPU mode selection (selectDockerGpuPatchMode), clone args building (buildDockerGpuCloneRunArgs), and recreate orchestration (recreateOpenShellDockerSandboxWithGpu) into separate modules in a follow-up refactoring PR. Document as a follow-up task in this PR with a linked issue.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/onboard/docker-gpu-patch.ts lines 1-2000 and count logical sections that could be extracted. grep for 'export function' to see public surface.
  • Missing regression test: No test needed for extraction itself; existing docker-gpu-patch.test.ts covers behavior. Add test in follow-up PR verifying extracted modules integrate correctly.
  • Done when: The required change is committed and verification passes: Read src/lib/onboard/docker-gpu-patch.ts lines 1-2000 and count logical sections that could be extracted. grep for 'export function' to see public surface.
  • Evidence: diff shows +58 lines in docker-gpu-patch.ts; monolithDeltas in drift context confirms blocker severity

PRA-5 Required — docker-gpu-local-inference.test.ts monolith growth +32 lines exceeds blocker threshold

  • Location: src/lib/onboard/docker-gpu-local-inference.test.ts:1
  • Category: architecture
  • Problem: docker-gpu-local-inference.test.ts grew from 391 to 423 lines (+32), exceeding the 20-line blocker threshold. Growth from bridge probe skipping logic tests and GPU startup integrity tests.
  • Impact: Test file couples bridge probe skipping logic with GPU startup integrity tests, reducing maintainability and increasing review burden.
  • Required action: Extract bridge probe skipping logic and its tests into a separate module/test file (e.g., docker-gpu-bridge-probe.ts / docker-gpu-bridge-probe.test.ts). Document as follow-up task in this PR.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/onboard/docker-gpu-local-inference.test.ts and identify test suites for shouldSkipGpuBridgeProbe/enforceDockerGpuPatchPreserveNetwork that could be extracted.
  • Missing regression test: No test needed for extraction itself; existing tests cover behavior. Add test in follow-up PR verifying extracted modules integrate correctly.
  • Done when: The required change is committed and verification passes: Read src/lib/onboard/docker-gpu-local-inference.test.ts and identify test suites for shouldSkipGpuBridgeProbe/enforceDockerGpuPatchPreserveNetwork that could be extracted.
  • Evidence: diff shows +32 lines in docker-gpu-local-inference.test.ts; monolithDeltas in drift context confirms blocker severity

PRA-6 Required — Concurrent e2e.yaml modifications across 9 open PRs create merge conflict risk

  • Location: .github/workflows/e2e.yaml:15
  • Category: workflow
  • Problem: Concurrent e2e.yaml modifications across 9 open PRs (5876, 6020, 6053, 6153, 6164, 6165, 5595, 5812, 5963) create merge conflict risk. This PR adds hermes-gpu-startup job and modifies workflow_dispatch inputs.
  • Impact: Merge conflicts could delay integration, cause CI failures, or introduce silent workflow misconfiguration if resolved incorrectly.
  • Required action: Coordinate with overlapping PR authors to resolve merge conflicts. After merge, run workflow-inventory.mts and verify explicit_only_jobs_csv matches the workflow_dispatch.jobs.description text.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run `npx tsx tools/e2e/workflow-inventory.mts --shell` and verify explicit_only_jobs_csv includes hermes-gpu-startup, openshell-gateway-auth-contract, jetson-nvmap-gpu, sandbox-rlimits-connect.
  • Missing regression test: Add validation step in tools/e2e/workflow-boundary.mts or hermes-gpu-startup-workflow-boundary.mts that parses workflow_dispatch.jobs.description and asserts it matches generate-matrix explicit_only_jobs_csv output.
  • Done when: The required change is committed and verification passes: Run `npx tsx tools/e2e/workflow-inventory.mts --shell` and verify explicit_only_jobs_csv includes hermes-gpu-startup, openshell-gateway-auth-contract, jetson-nvmap-gpu, sandbox-rlimits-connect.
  • Evidence: openPrOverlaps shows 9 PRs modifying e2e.yaml; diff shows hermes-gpu-startup job added and workflow_dispatch inputs modified

PRA-7 Required — Missing isolated unit tests for pre-rollback diagnostics redaction logic (3 injection vectors)

  • Location: src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1
  • Category: tests
  • Problem: Missing isolated unit tests for pre-rollback diagnostics redaction logic covering 3 injection vectors: (1) OPENSHELL_SANDBOX_COMMAND env vars in container inspect, (2) extra placeholder keys from NEMOCLAW_EXTRA_PLACEHOLDER_KEYS, (3) discovered container IDs from label queries. The test file docker-gpu-pre-rollback-diagnostics.test.ts exists but focuses on integration capture flow, not isolated redaction logic.
  • Impact: Without isolated unit tests, redaction failures in any of the 3 vectors or 6 output sinks could go undetected until integration tests run, increasing risk of secret leakage in diagnostic artifacts.
  • Required action: Add unit tests in docker-gpu-pre-rollback-diagnostics.test.ts that inject known secret canaries through all three vectors and verify redaction in all six output sinks (summary.txt, patched-container-state.json, docker-ps.txt, docker-inspect.json, docker-logs.txt, openshell-*.txt).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts and verify test cases inject secrets via: (a) result.newContainerId inspect Env, (b) discovered container IDs from findOpenShellDockerSandboxContainerIds, (c) NEMOCLAW_EXTRA_PLACEHOLDER_KEYS in startup command. Check all output files for <REDACTED>.
  • Missing regression test: Unit tests for primeSensitiveDiagnosticValues and boundedDiagnosticsDeps covering the three injection vectors with assertions on all six output sinks.
  • Done when: The required change is committed and verification passes: Read src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts and verify test cases inject secrets via: (a) result.newContainerId inspect Env, (b) discovered container IDs from findOpenShellDockerSandboxContainerIds, (c) NEMOCLAW_EXTRA_PLACEHOLDER_KEYS in startup command. Check all output files for <REDACTED>.
  • Evidence: docker-gpu-pre-rollback-diagnostics.test.ts exists but tests integration capture flow; staticTestInventory shows no isolated unit tests for primeSensitiveDiagnosticValues

PRA-8 Required — Pre-rollback diagnostics redaction wrapper missing SOURCE_OF_TRUTH_REVIEW comment

  • Location: src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1
  • Category: architecture
  • Problem: Pre-rollback diagnostics redaction wrapper (captureDockerGpuPreRollbackDiagnostics) and the diagnostic redactor (createDockerGpuDiagnosticRedactor in docker-gpu-diagnostic-redaction.ts) lack SOURCE_OF_TRUTH_REVIEW comments documenting: (1) what invalid state is handled, (2) where that state is created, (3) why the source cannot be fixed in this PR, (4) what regression test proves the source cannot regress, (4) when the workaround can be removed.
  • Impact: Without SOURCE_OF_TRUTH_REVIEW, future maintainers cannot evaluate whether the diagnostic redaction workaround is still necessary or can be replaced by a source fix, leading to technical debt accumulation.
  • Required action: Add SOURCE_OF_TRUTH_REVIEW comment in docker-gpu-pre-rollback-diagnostics.ts and docker-gpu-diagnostic-redaction.ts documenting all five elements. The invalid state is secret leakage in diagnostic artifacts; source is docker inspect/openshell output; cannot be fixed at source because Docker/OpenShell don't redact; regression test is docker-gpu-diagnostic-redaction.test.ts; removable when OpenShell/Docker add native secret redaction.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: grep -n 'SOURCE_OF_TRUTH_REVIEW' src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts src/lib/onboard/docker-gpu-diagnostic-redaction.ts
  • Missing regression test: SOURCE_OF_TRUTH_REVIEW comment present in both files with all five elements documented.
  • Done when: The required change is committed and verification passes: grep -n 'SOURCE_OF_TRUTH_REVIEW' src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts src/lib/onboard/docker-gpu-diagnostic-redaction.ts.
  • Evidence: grep for SOURCE_OF_TRUTH_REVIEW in these files returns no matches; localizedPatchSignals identifies these as fallback/recovery paths

PRA-9 Required — OPENSHELL_TLS_KEY exact path allowance lacks OpenShell version citation

  • Location: agents/hermes/validate-env-secret-boundary.py:48
  • Category: security
  • Problem: OPENSHELL_TLS_KEY exact path allowance (/etc/openshell/tls/client/tls.key) lacks OpenShell version/commit citation. The comment states 'OpenShell's Docker/Podman supervisor owns this variable' but does not cite the specific OpenShell version or commit that establishes this contract.
  • Impact: Without version citation, future OpenShell upgrades could change the TLS key mount path, causing either false rejections (if path changes) or security gaps (if new paths are injected without review).
  • Required action: Add a comment citing the OpenShell version/commit that establishes this contract (e.g., 'OpenShell 0.0.71 Docker/Podman supervisor TLS mount path at /etc/openshell/tls/client/tls.key'). Verify no other TLS key paths are ever injected.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read agents/hermes/validate-env-secret-boundary.py lines 40-55 and verify OpenShell version citation present.
  • Missing regression test: Test in test/hermes-runtime-config-guard.test.ts or similar that OPENSHELL_TLS_KEY with the exact allowed path passes validation, while any other value fails.
  • Done when: The required change is committed and verification passes: Read agents/hermes/validate-env-secret-boundary.py lines 40-55 and verify OpenShell version citation present.
  • Evidence: validate-env-secret-boundary.py:48 defines RUNTIME_ALLOWED_PLATFORM_PATH_VALUES with exact path but no version citation
Review findings by urgency: 6 required fixes, 9 items to resolve/justify, 8 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: docker-gpu-pre-rollback-diagnostics.ts

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as missing.
  • 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: docker-gpu-diagnostic-redaction.test.ts redacts opaque conventional and custom-placeholder values from every shared collector sink
  • 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: No SOURCE_OF_TRUTH_REVIEW comment in docker-gpu-pre-rollback-diagnostics.ts or docker-gpu-diagnostic-redaction.ts

PRA-2 Resolve/justify — Source-of-truth review needed: docs/reference/commands-nemohermes.mdx:365

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as missing.
  • 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: Manual verification on WSL; docker-gpu-sandbox-create.test.ts suppresses openshell sandbox create --gpu flag on WSL when opt-out ignored
  • 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: localizedPatchSignals identifies line 365 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-3 Resolve/justify — Source-of-truth review needed: docs/reference/commands-nemohermes.mdx:367

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as missing.
  • 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: CI on Jetson hardware (not in this repo); docker-gpu-patch.test.ts uses Jetson NVIDIA runtime args without selecting generic --gpus or CDI candidates
  • 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: localizedPatchSignals identifies line 367 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-10 Resolve/justify — workflow_dispatch explicit-only jobs list not validated against generate-matrix inventory

  • Location: tools/e2e/workflow-boundary.mts:1
  • Category: architecture
  • Problem: workflow_dispatch explicit-only jobs list must stay in sync with generate-matrix inventory. This PR adds hermes-gpu-startup to explicit-only jobs but no automated validation ensures sync.
  • Impact: Divergence between workflow_dispatch description and generate-matrix output could cause jobs to be incorrectly skipped or run, breaking selective dispatch and PR result reporting.
  • Recommended action: Add a validation step in tools/e2e/workflow-boundary.mts or hermes-gpu-startup-workflow-boundary.mts that parses workflow_dispatch.jobs.description and asserts it matches generate-matrix explicit_only_jobs_csv output.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check tools/e2e/workflow-boundary.mts for validation logic comparing workflow_dispatch inputs with inventory output.
  • Missing regression test: Automated test that fails if workflow_dispatch.jobs.description explicit-only jobs list diverges from generate-matrix explicit_only_jobs_csv.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check tools/e2e/workflow-boundary.mts for validation logic comparing workflow_dispatch inputs with inventory output.
  • Evidence: e2e.yaml diff adds hermes-gpu-startup to explicit-only jobs; workflow-boundary.mts has no validation step

PRA-11 Resolve/justify — shouldSkipGpuBridgeProbe caller passes incomplete options

  • Location: src/lib/onboard.ts:1893
  • Category: security
  • Problem: shouldSkipGpuBridgeProbe caller in onboard.ts passes incomplete options. Call: shouldSkipGpuBridgeProbe(gpuPassthrough, _gpu?.platform) — only 2 args. Function signature expects (gpuPassthrough, hostGpuPlatform?, options?: Partial<DockerGpuLocalInferenceOptions>). The dockerDriverGateway: true is not passed, so resolveDockerDesktopWsl defaults to isDockerDesktopWslRuntime() which may be incorrect when called from Linux Docker-driver gateway context.
  • Impact: Incorrect host-network detection could cause the GPU bridge probe to be skipped when it should run (or vice versa), leading to false-positive inference reachability results on Linux Docker-driver gateways.
  • Recommended action: Fix the caller in onboard.ts:1893 to pass { dockerDriverGateway: true, dockerDesktopWsl: false } explicitly, or add a comment documenting that missing keys default to false safely. Verify resolveDockerDesktopWsl handles undefined correctly.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read src/lib/onboard.ts line 1893 and src/lib/onboard/docker-gpu-local-inference.ts lines 40-55 to verify the default behavior.
  • Missing regression test: Unit test for shouldSkipGpuBridgeProbe with dockerDriverGateway: true and dockerDesktopWsl: false to confirm correct host-network detection.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read src/lib/onboard.ts line 1893 and src/lib/onboard/docker-gpu-local-inference.ts lines 40-55 to verify the default behavior.
  • Evidence: onboard.ts:1893 calls shouldSkipGpuBridgeProbe(gpuPassthrough, _gpu?.platform); docker-gpu-local-inference.ts:40-55 shows resolveDockerDesktopWsl defaults to isDockerDesktopWslRuntime()

PRA-12 Resolve/justify — docker-gpu-patch.test.ts monolith growth +13 lines exceeds warning threshold

  • Location: src/lib/onboard/docker-gpu-patch.test.ts:1
  • Category: tests
  • Problem: docker-gpu-patch.test.ts grew from 1322 to 1335 lines (+13), exceeding the 1-19 warning threshold. Growth from [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix tests (validation-before-mutation, token validation, pre-rollback diagnostics).
  • Impact: Test file growth adds maintenance burden; mode-routing cases should be split on next growth.
  • Recommended action: Document as follow-up task in this PR. Current growth is from [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix tests. Split the mode-routing cases on the next growth.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read src/lib/onboard/docker-gpu-patch.test.ts and identify test suites added for validation-before-mutation, token validation, pre-rollback diagnostics.
  • Missing regression test: No immediate test needed; existing tests cover new behavior. Plan extraction on next growth cycle.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read src/lib/onboard/docker-gpu-patch.test.ts and identify test suites added for validation-before-mutation, token validation, pre-rollback diagnostics.
  • Evidence: monolithDeltas shows +13 lines warning severity; staticTestInventory shows 20 test blocks in this file

PRA-13 Resolve/justify — start.sh comment should clarify dual-mode authorization for future auditors

  • Location: agents/hermes/start.sh:1620
  • Category: correctness
  • Problem: start.sh comment updated from 'Keep the guard as PID 1's direct child: --startup-owner is authenticated by exact parent identity' to 'Keep the guard as the startup owner's direct child: --startup-owner is authenticated by exact parent identity'. The dual-mode authorization (PID 1 direct child vs. startup owner child) should be clarified for future auditors.
  • Impact: Future auditors may not understand the two authorization branches (cold start vs runtime), leading to incorrect security assessments.
  • Recommended action: Update the comment to explicitly mention both authorization branches: PID 1 direct child (cold start) and startup owner's direct child (runtime config guard calls from PID 1 lifecycle handler).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read agents/hermes/start.sh lines 1615-1630 and verify comment mentions both branches.
  • Missing regression test: No test needed; documentation clarity only.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read agents/hermes/start.sh lines 1615-1630 and verify comment mentions both branches.
  • Evidence: diff shows comment change at line 1620; dual-mode documented in runtime-config-guard.py SOURCE_OF_TRUTH_REVIEW

PRA-14 Resolve/justify — Proof assertion uses exact string match instead of parser-compatible split for OPENSHELL_SANDBOX_COMMAND transport format

  • Location: test/e2e/live/hermes-gpu-startup-proof.ts:135
  • Category: correctness
  • Problem: Proof assertion uses exact string match instead of parser-compatible split for OPENSHELL_SANDBOX_COMMAND transport format. The extraPlaceholderEnv check expects exact string 'NEMOCLAW_EXTRA_PLACEHOLDER_KEYS=TELEGRAM_BOT_TOKEN_AGENT_A,SLACK_BOT_TOKEN_AGENT_B' but the serializer uses /[\s\u0085]+/u split.
  • Impact: Proof could pass with malformed transport format (e.g., using U+0085 next-line characters) that the actual parser would reject, or fail on valid parser-compatible formats.
  • Recommended action: Update the proof to split on whitespace including U+0085 (using the same regex as the serializer: /[\s\u0085]+/u), then assert the expected keys are present.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/e2e/live/hermes-gpu-startup-proof.ts lines 130-145 and verify the assertion uses parser-compatible split.
  • Missing regression test: Test that OPENSHELL_SANDBOX_COMMAND with U+0085 next-line characters is correctly parsed by both the serializer and the proof assertion.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/e2e/live/hermes-gpu-startup-proof.ts lines 130-145 and verify the assertion uses parser-compatible split.
  • Evidence: hermes-gpu-startup-proof.ts extraPlaceholderEnv assertion uses exact string match; startup command serializer uses /[\s\u0085]+/u split

PRA-15 Resolve/justify — docker-gpu-local-inference.ts monolith growth +15 lines (warning threshold 1-19)

  • Location: src/lib/onboard/docker-gpu-local-inference.ts:1
  • Category: architecture
  • Problem: docker-gpu-local-inference.ts grew from 440 to 455 lines (+15), within 1-19 warning threshold. Growth from enforceDockerGpuPatchPreserveNetwork network downgrade logic.
  • Impact: Network downgrade logic adds complexity; could be extracted to separate module if it grows further.
  • Recommended action: Review whether extraction is feasible. The network downgrade logic could be extracted to a separate module if it grows further.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read src/lib/onboard/docker-gpu-local-inference.ts and identify logical sections.
  • Missing regression test: No immediate test needed.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read src/lib/onboard/docker-gpu-local-inference.ts and identify logical sections.
  • Evidence: monolithDeltas shows +15 lines warning severity

💡 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.

PRA-16 Improvement — No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route

  • Location: test/e2e/live/hermes-gpu-startup.test.ts:1
  • Category: tests
  • Problem: No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route. The test supports FORCE_LEGACY_GPU_PATCH env var but the workflow job hermes-gpu-startup does not include a matrix variant for it.
  • Impact: Legacy patch route (used on WSL/Jetson and as escape hatch) is not exercised in CI, risking regressions in the compatibility path.
  • Suggested action: Add a CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 in the hermes-gpu-startup job definition (or a separate job variant) to exercise the legacy patch route.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check .github/workflows/e2e.yaml hermes-gpu-startup job for matrix strategy or env var override.
  • Missing regression test: CI job variant with FORCE_LEGACY_GPU_PATCH=1 that runs hermes-gpu-startup.test.ts and asserts legacy patch route logs appear.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: e2e.yaml hermes-gpu-startup job has no matrix; FORCE_LEGACY_GPU_PATCH used in test but not in CI

PRA-17 Improvement — Behavior change: shouldApplyDockerGpuPatch defaults to native OpenShell GPU injection on Linux

  • Location: src/lib/onboard/docker-gpu-patch.ts:540
  • Category: architecture
  • Problem: Behavior change: shouldApplyDockerGpuPatch defaults to native OpenShell GPU injection on ordinary native Linux. The compatibility patch (Docker container swap) is now only used on Docker Desktop WSL and Jetson/Tegra by default. Operators need to know about NEMOCLAW_DOCKER_GPU_PATCH=1 escape hatch for legacy behavior.
  • Impact: Operators upgrading from older versions may be surprised by changed GPU routing behavior; escape hatch must be documented.
  • Suggested action: Document this behavior change in release notes/migration guide. Verify hermes-gpu-startup live test covers both routes (it does via FORCE_LEGACY_GPU_PATCH env var). Ensure operators know about NEMOCLAW_DOCKER_GPU_PATCH=1 escape hatch.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read docs/reference/commands-nemohermes.mdx lines 365-380 and verify documentation covers new defaults and escape hatches.
  • Missing regression test: Release note entry documenting the GPU routing behavior change.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: docker-gpu-patch.ts:540 shouldApplyDockerGpuPatch logic; commands-nemohermes.mdx updated with new defaults

PRA-18 Improvement — Docker Desktop WSL compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW

  • Location: docs/reference/commands-nemohermes.mdx:365
  • Category: scope
  • Problem: Docker Desktop WSL compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW. The docs state 'On Docker Desktop WSL, the compatibility path skips CDI and tries Docker --gpus all before the NVIDIA runtime' but this is a localized workaround for Docker Desktop WSL's lack of usable CDI specs.
  • Impact: Without SOURCE_OF_TRUTH_REVIEW, the workaround lacks formal documentation of its constraints, making future removal evaluation difficult.
  • Suggested action: Add SOURCE_OF_TRUTH_REVIEW comment in docs/reference/commands-nemohermes.mdx:365 documenting: (1) invalid state = Docker Desktop WSL advertises CDI dirs but --device nvidia.com/gpu=all unusable, (2) source = Docker Desktop WSL integration, (3) cannot fix in this PR = upstream Docker Desktop issue, (4) regression test = manual verification on WSL, (5) removable when Docker Desktop exposes usable nvidia.com/gpu CDI specs in WSL.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -n 'SOURCE_OF_TRUTH_REVIEW' docs/reference/commands-nemohermes.mdx
  • Missing regression test: SOURCE_OF_TRUTH_REVIEW comment present with all five elements.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: localizedPatchSignals identifies commands-nemohermes.mdx:365 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-19 Improvement — Jetson/Tegra compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW

  • Location: docs/reference/commands-nemohermes.mdx:367
  • Category: scope
  • Problem: Jetson/Tegra compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW. The docs state 'On Jetson/Tegra hosts, the compatibility path uses the NVIDIA runtime and adds the host group IDs that own /dev/nvmap and /dev/nvhost-*' but this is a localized workaround for Tegra device nodes owned by non-root group.
  • Impact: Without SOURCE_OF_TRUTH_REVIEW, the workaround lacks formal documentation of its constraints, making future removal evaluation difficult.
  • Suggested action: Add SOURCE_OF_TRUTH_REVIEW comment in docs/reference/commands-nemohermes.mdx:367 documenting: (1) invalid state = Tegra device nodes owned by non-root group, (2) source = Jetson/Tegra board support package, (3) cannot fix in this PR = hardware/BSP constraint, (4) regression test = CI on Jetson hardware, (5) removable when Tegra device nodes default to root:video or similar accessible group.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -n 'SOURCE_OF_TRUTH_REVIEW' docs/reference/commands-nemohermes.mdx
  • Missing regression test: SOURCE_OF_TRUTH_REVIEW comment present with all five elements.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: localizedPatchSignals identifies commands-nemohermes.mdx:367 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-20 Improvement — Documentation consistency: troubleshooting.mdx matches commands-nemohermes.mdx for GPU routing

  • Location: docs/reference/troubleshooting.mdx:1528
  • Category: correctness
  • Problem: Documentation consistency: troubleshooting.mdx matches commands-nemohermes.mdx for GPU routing. The troubleshooting section 'Docker GPU patch failed during sandbox create' has been updated to reflect new defaults (native injection on ordinary Linux, compatibility patch on WSL/Jetson).
  • Impact: Documentation is consistent — no action needed.
  • Suggested action: No action needed. The documentation is consistent.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read docs/reference/troubleshooting.mdx lines 1528-1580 and verify consistency with commands-nemohermes.mdx.
  • Missing regression test: None needed; documentation consistency verified.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: diff shows troubleshooting.mdx updated to match new GPU routing defaults

PRA-21 Improvement — New focused validation test file for #6110 security fix — well-scoped addition

  • Location: src/lib/onboard/docker-gpu-patch-validation.test.ts:1
  • Category: tests
  • Problem: New focused validation test file for [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix — well-scoped addition covering validation-before-mutation, token validation, and pre-rollback diagnostics integration.
  • Impact: Positive: focused test file improves security test coverage without monolith growth.
  • Suggested action: No action needed; this is a well-scoped addition.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read src/lib/onboard/docker-gpu-patch-validation.test.ts and verify it tests the three security fix areas.
  • Missing regression test: None needed; tests already present.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: staticTestInventory shows 1 test block for 'Docker GPU startup command validation ([DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110)'

PRA-22 Improvement — E2E_DEFAULT_ENABLED single-use config could be constant

  • Location: .github/workflows/e2e.yaml:1588
  • Category: scope
  • Problem: E2E_DEFAULT_ENABLED single-use config in hermes-gpu-startup job could be constant. The job sets E2E_DEFAULT_ENABLED: "0" but this env var is only used in this one job.
  • Impact: Minor: single-use config adds cognitive overhead without benefit.
  • Suggested action: Consider making E2E_DEFAULT_ENABLED a constant in workflow-inventory.mts or removing if unused elsewhere.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -r 'E2E_DEFAULT_ENABLED' .github/workflows/ tools/e2e/
  • Missing regression test: None needed; minor cleanup.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: e2e.yaml:1588 sets E2E_DEFAULT_ENABLED: "0" only in hermes-gpu-startup job; simplificationSignals identifies as single_use_config

PRA-23 Improvement — Simplify E2E_DEFAULT_ENABLED single-use config to constant

  • Location: .github/workflows/e2e.yaml:1588
  • Category: architecture
  • Problem: E2E_DEFAULT_ENABLED is set only in hermes-gpu-startup job and never referenced elsewhere in the workflow or tools.
  • Impact: Reduces workflow complexity by removing unused configuration variable.
  • Suggested action: Replace E2E_DEFAULT_ENABLED: "0" with a constant or remove if truly unused. This is a safe simplification within the current PR scope.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -r 'E2E_DEFAULT_ENABLED' .github/workflows/ tools/e2e/ confirms single use
  • Missing regression test: None needed.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: simplificationSignals identifies single_use_config at e2e.yaml:1588
Simplification opportunities: 1 possible cut, net -1 lines possible

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

  • PRA-23 delete (.github/workflows/e2e.yaml:1588): E2E_DEFAULT_ENABLED: "0" environment variable in hermes-gpu-startup job
    • Replacement: Remove the line entirely; the variable is not read anywhere
    • Net: -1 lines
    • Safety boundary: Must verify grep -r 'E2E_DEFAULT_ENABLED' returns no other references before removal
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 — primeSensitiveDiagnosticValues_injects_secrets_via_container_inspect_Env. Runtime/sandbox/infrastructure paths need behavioral runtime validation: .github/workflows/e2e.yaml, agents/hermes/Dockerfile, agents/hermes/runtime-config-guard.py, agents/hermes/start.sh, agents/hermes/validate-env-secret-boundary.py, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx. New test files cover integration but isolated unit tests for redaction logic and CI matrix for legacy route are missing.
  • PRA-T2 Runtime validation — primeSensitiveDiagnosticValues_injects_secrets_via_discovered_container_ids. Runtime/sandbox/infrastructure paths need behavioral runtime validation: .github/workflows/e2e.yaml, agents/hermes/Dockerfile, agents/hermes/runtime-config-guard.py, agents/hermes/start.sh, agents/hermes/validate-env-secret-boundary.py, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx. New test files cover integration but isolated unit tests for redaction logic and CI matrix for legacy route are missing.
  • PRA-T3 Runtime validation — primeSensitiveDiagnosticValues_injects_secrets_via_extra_placeholder_keys. Runtime/sandbox/infrastructure paths need behavioral runtime validation: .github/workflows/e2e.yaml, agents/hermes/Dockerfile, agents/hermes/runtime-config-guard.py, agents/hermes/start.sh, agents/hermes/validate-env-secret-boundary.py, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx. New test files cover integration but isolated unit tests for redaction logic and CI matrix for legacy route are missing.
  • PRA-T4 Runtime validation — createDockerGpuDiagnosticRedactor_redacts_all_six_sinks. Runtime/sandbox/infrastructure paths need behavioral runtime validation: .github/workflows/e2e.yaml, agents/hermes/Dockerfile, agents/hermes/runtime-config-guard.py, agents/hermes/start.sh, agents/hermes/validate-env-secret-boundary.py, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx. New test files cover integration but isolated unit tests for redaction logic and CI matrix for legacy route are missing.
  • PRA-T5 Runtime validation — hermes_gpu_startup_legacy_patch_route_CI. Runtime/sandbox/infrastructure paths need behavioral runtime validation: .github/workflows/e2e.yaml, agents/hermes/Dockerfile, agents/hermes/runtime-config-guard.py, agents/hermes/start.sh, agents/hermes/validate-env-secret-boundary.py, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx. New test files cover integration but isolated unit tests for redaction logic and CI matrix for legacy route are missing.
  • PRA-T6 Missing isolated unit tests for pre-rollback diagnostics redaction logic (3 injection vectors) — Add unit tests in docker-gpu-pre-rollback-diagnostics.test.ts that inject known secret canaries through all three vectors and verify redaction in all six output sinks (summary.txt, patched-container-state.json, docker-ps.txt, docker-inspect.json, docker-logs.txt, openshell-*.txt).
  • PRA-T7 docker-gpu-patch.test.ts monolith growth +13 lines exceeds warning threshold — Document as follow-up task in this PR. Current growth is from [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix tests. Split the mode-routing cases on the next growth.
  • PRA-T8 No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route — Add a CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 in the hermes-gpu-startup job definition (or a separate job variant) to exercise the legacy patch route.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: docker-gpu-pre-rollback-diagnostics.ts

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as missing.
  • 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: docker-gpu-diagnostic-redaction.test.ts redacts opaque conventional and custom-placeholder values from every shared collector sink
  • 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: No SOURCE_OF_TRUTH_REVIEW comment in docker-gpu-pre-rollback-diagnostics.ts or docker-gpu-diagnostic-redaction.ts

PRA-2 Resolve/justify — Source-of-truth review needed: docs/reference/commands-nemohermes.mdx:365

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as missing.
  • 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: Manual verification on WSL; docker-gpu-sandbox-create.test.ts suppresses openshell sandbox create --gpu flag on WSL when opt-out ignored
  • 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: localizedPatchSignals identifies line 365 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-3 Resolve/justify — Source-of-truth review needed: docs/reference/commands-nemohermes.mdx:367

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as missing.
  • 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: CI on Jetson hardware (not in this repo); docker-gpu-patch.test.ts uses Jetson NVIDIA runtime args without selecting generic --gpus or CDI candidates
  • 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: localizedPatchSignals identifies line 367 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-4 Required — docker-gpu-patch.ts monolith growth +58 lines exceeds blocker threshold

  • Location: src/lib/onboard/docker-gpu-patch.ts:1
  • Category: architecture
  • Problem: docker-gpu-patch.ts grew from 1840 to 1898 lines (+58), exceeding the 20-line blocker threshold. Growth stems from validation-before-mutation reordering, commandArgs logic change for empty Config.Cmd, new token validation, and pre-rollback diagnostics integration. GPU mode selection (selectDockerGpuPatchMode), clone args building (buildDockerGpuCloneRunArgs), and recreate orchestration (recreateOpenShellDockerSandboxWithGpu) remain coupled in one module.
  • Impact: Monolithic module couples security-critical token validation, container mutation ordering, and diagnostic capture — increases risk of regression when modifying any subsystem and blocks safe parallel development.
  • Required action: Extract GPU mode selection (selectDockerGpuPatchMode), clone args building (buildDockerGpuCloneRunArgs), and recreate orchestration (recreateOpenShellDockerSandboxWithGpu) into separate modules in a follow-up refactoring PR. Document as a follow-up task in this PR with a linked issue.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/onboard/docker-gpu-patch.ts lines 1-2000 and count logical sections that could be extracted. grep for 'export function' to see public surface.
  • Missing regression test: No test needed for extraction itself; existing docker-gpu-patch.test.ts covers behavior. Add test in follow-up PR verifying extracted modules integrate correctly.
  • Done when: The required change is committed and verification passes: Read src/lib/onboard/docker-gpu-patch.ts lines 1-2000 and count logical sections that could be extracted. grep for 'export function' to see public surface.
  • Evidence: diff shows +58 lines in docker-gpu-patch.ts; monolithDeltas in drift context confirms blocker severity

PRA-5 Required — docker-gpu-local-inference.test.ts monolith growth +32 lines exceeds blocker threshold

  • Location: src/lib/onboard/docker-gpu-local-inference.test.ts:1
  • Category: architecture
  • Problem: docker-gpu-local-inference.test.ts grew from 391 to 423 lines (+32), exceeding the 20-line blocker threshold. Growth from bridge probe skipping logic tests and GPU startup integrity tests.
  • Impact: Test file couples bridge probe skipping logic with GPU startup integrity tests, reducing maintainability and increasing review burden.
  • Required action: Extract bridge probe skipping logic and its tests into a separate module/test file (e.g., docker-gpu-bridge-probe.ts / docker-gpu-bridge-probe.test.ts). Document as follow-up task in this PR.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/onboard/docker-gpu-local-inference.test.ts and identify test suites for shouldSkipGpuBridgeProbe/enforceDockerGpuPatchPreserveNetwork that could be extracted.
  • Missing regression test: No test needed for extraction itself; existing tests cover behavior. Add test in follow-up PR verifying extracted modules integrate correctly.
  • Done when: The required change is committed and verification passes: Read src/lib/onboard/docker-gpu-local-inference.test.ts and identify test suites for shouldSkipGpuBridgeProbe/enforceDockerGpuPatchPreserveNetwork that could be extracted.
  • Evidence: diff shows +32 lines in docker-gpu-local-inference.test.ts; monolithDeltas in drift context confirms blocker severity

PRA-6 Required — Concurrent e2e.yaml modifications across 9 open PRs create merge conflict risk

  • Location: .github/workflows/e2e.yaml:15
  • Category: workflow
  • Problem: Concurrent e2e.yaml modifications across 9 open PRs (5876, 6020, 6053, 6153, 6164, 6165, 5595, 5812, 5963) create merge conflict risk. This PR adds hermes-gpu-startup job and modifies workflow_dispatch inputs.
  • Impact: Merge conflicts could delay integration, cause CI failures, or introduce silent workflow misconfiguration if resolved incorrectly.
  • Required action: Coordinate with overlapping PR authors to resolve merge conflicts. After merge, run workflow-inventory.mts and verify explicit_only_jobs_csv matches the workflow_dispatch.jobs.description text.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run `npx tsx tools/e2e/workflow-inventory.mts --shell` and verify explicit_only_jobs_csv includes hermes-gpu-startup, openshell-gateway-auth-contract, jetson-nvmap-gpu, sandbox-rlimits-connect.
  • Missing regression test: Add validation step in tools/e2e/workflow-boundary.mts or hermes-gpu-startup-workflow-boundary.mts that parses workflow_dispatch.jobs.description and asserts it matches generate-matrix explicit_only_jobs_csv output.
  • Done when: The required change is committed and verification passes: Run `npx tsx tools/e2e/workflow-inventory.mts --shell` and verify explicit_only_jobs_csv includes hermes-gpu-startup, openshell-gateway-auth-contract, jetson-nvmap-gpu, sandbox-rlimits-connect.
  • Evidence: openPrOverlaps shows 9 PRs modifying e2e.yaml; diff shows hermes-gpu-startup job added and workflow_dispatch inputs modified

PRA-7 Required — Missing isolated unit tests for pre-rollback diagnostics redaction logic (3 injection vectors)

  • Location: src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1
  • Category: tests
  • Problem: Missing isolated unit tests for pre-rollback diagnostics redaction logic covering 3 injection vectors: (1) OPENSHELL_SANDBOX_COMMAND env vars in container inspect, (2) extra placeholder keys from NEMOCLAW_EXTRA_PLACEHOLDER_KEYS, (3) discovered container IDs from label queries. The test file docker-gpu-pre-rollback-diagnostics.test.ts exists but focuses on integration capture flow, not isolated redaction logic.
  • Impact: Without isolated unit tests, redaction failures in any of the 3 vectors or 6 output sinks could go undetected until integration tests run, increasing risk of secret leakage in diagnostic artifacts.
  • Required action: Add unit tests in docker-gpu-pre-rollback-diagnostics.test.ts that inject known secret canaries through all three vectors and verify redaction in all six output sinks (summary.txt, patched-container-state.json, docker-ps.txt, docker-inspect.json, docker-logs.txt, openshell-*.txt).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts and verify test cases inject secrets via: (a) result.newContainerId inspect Env, (b) discovered container IDs from findOpenShellDockerSandboxContainerIds, (c) NEMOCLAW_EXTRA_PLACEHOLDER_KEYS in startup command. Check all output files for <REDACTED>.
  • Missing regression test: Unit tests for primeSensitiveDiagnosticValues and boundedDiagnosticsDeps covering the three injection vectors with assertions on all six output sinks.
  • Done when: The required change is committed and verification passes: Read src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts and verify test cases inject secrets via: (a) result.newContainerId inspect Env, (b) discovered container IDs from findOpenShellDockerSandboxContainerIds, (c) NEMOCLAW_EXTRA_PLACEHOLDER_KEYS in startup command. Check all output files for <REDACTED>.
  • Evidence: docker-gpu-pre-rollback-diagnostics.test.ts exists but tests integration capture flow; staticTestInventory shows no isolated unit tests for primeSensitiveDiagnosticValues

PRA-8 Required — Pre-rollback diagnostics redaction wrapper missing SOURCE_OF_TRUTH_REVIEW comment

  • Location: src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts:1
  • Category: architecture
  • Problem: Pre-rollback diagnostics redaction wrapper (captureDockerGpuPreRollbackDiagnostics) and the diagnostic redactor (createDockerGpuDiagnosticRedactor in docker-gpu-diagnostic-redaction.ts) lack SOURCE_OF_TRUTH_REVIEW comments documenting: (1) what invalid state is handled, (2) where that state is created, (3) why the source cannot be fixed in this PR, (4) what regression test proves the source cannot regress, (4) when the workaround can be removed.
  • Impact: Without SOURCE_OF_TRUTH_REVIEW, future maintainers cannot evaluate whether the diagnostic redaction workaround is still necessary or can be replaced by a source fix, leading to technical debt accumulation.
  • Required action: Add SOURCE_OF_TRUTH_REVIEW comment in docker-gpu-pre-rollback-diagnostics.ts and docker-gpu-diagnostic-redaction.ts documenting all five elements. The invalid state is secret leakage in diagnostic artifacts; source is docker inspect/openshell output; cannot be fixed at source because Docker/OpenShell don't redact; regression test is docker-gpu-diagnostic-redaction.test.ts; removable when OpenShell/Docker add native secret redaction.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: grep -n 'SOURCE_OF_TRUTH_REVIEW' src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts src/lib/onboard/docker-gpu-diagnostic-redaction.ts
  • Missing regression test: SOURCE_OF_TRUTH_REVIEW comment present in both files with all five elements documented.
  • Done when: The required change is committed and verification passes: grep -n 'SOURCE_OF_TRUTH_REVIEW' src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts src/lib/onboard/docker-gpu-diagnostic-redaction.ts.
  • Evidence: grep for SOURCE_OF_TRUTH_REVIEW in these files returns no matches; localizedPatchSignals identifies these as fallback/recovery paths

PRA-9 Required — OPENSHELL_TLS_KEY exact path allowance lacks OpenShell version citation

  • Location: agents/hermes/validate-env-secret-boundary.py:48
  • Category: security
  • Problem: OPENSHELL_TLS_KEY exact path allowance (/etc/openshell/tls/client/tls.key) lacks OpenShell version/commit citation. The comment states 'OpenShell's Docker/Podman supervisor owns this variable' but does not cite the specific OpenShell version or commit that establishes this contract.
  • Impact: Without version citation, future OpenShell upgrades could change the TLS key mount path, causing either false rejections (if path changes) or security gaps (if new paths are injected without review).
  • Required action: Add a comment citing the OpenShell version/commit that establishes this contract (e.g., 'OpenShell 0.0.71 Docker/Podman supervisor TLS mount path at /etc/openshell/tls/client/tls.key'). Verify no other TLS key paths are ever injected.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read agents/hermes/validate-env-secret-boundary.py lines 40-55 and verify OpenShell version citation present.
  • Missing regression test: Test in test/hermes-runtime-config-guard.test.ts or similar that OPENSHELL_TLS_KEY with the exact allowed path passes validation, while any other value fails.
  • Done when: The required change is committed and verification passes: Read agents/hermes/validate-env-secret-boundary.py lines 40-55 and verify OpenShell version citation present.
  • Evidence: validate-env-secret-boundary.py:48 defines RUNTIME_ALLOWED_PLATFORM_PATH_VALUES with exact path but no version citation

PRA-10 Resolve/justify — workflow_dispatch explicit-only jobs list not validated against generate-matrix inventory

  • Location: tools/e2e/workflow-boundary.mts:1
  • Category: architecture
  • Problem: workflow_dispatch explicit-only jobs list must stay in sync with generate-matrix inventory. This PR adds hermes-gpu-startup to explicit-only jobs but no automated validation ensures sync.
  • Impact: Divergence between workflow_dispatch description and generate-matrix output could cause jobs to be incorrectly skipped or run, breaking selective dispatch and PR result reporting.
  • Recommended action: Add a validation step in tools/e2e/workflow-boundary.mts or hermes-gpu-startup-workflow-boundary.mts that parses workflow_dispatch.jobs.description and asserts it matches generate-matrix explicit_only_jobs_csv output.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check tools/e2e/workflow-boundary.mts for validation logic comparing workflow_dispatch inputs with inventory output.
  • Missing regression test: Automated test that fails if workflow_dispatch.jobs.description explicit-only jobs list diverges from generate-matrix explicit_only_jobs_csv.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check tools/e2e/workflow-boundary.mts for validation logic comparing workflow_dispatch inputs with inventory output.
  • Evidence: e2e.yaml diff adds hermes-gpu-startup to explicit-only jobs; workflow-boundary.mts has no validation step

PRA-11 Resolve/justify — shouldSkipGpuBridgeProbe caller passes incomplete options

  • Location: src/lib/onboard.ts:1893
  • Category: security
  • Problem: shouldSkipGpuBridgeProbe caller in onboard.ts passes incomplete options. Call: shouldSkipGpuBridgeProbe(gpuPassthrough, _gpu?.platform) — only 2 args. Function signature expects (gpuPassthrough, hostGpuPlatform?, options?: Partial<DockerGpuLocalInferenceOptions>). The dockerDriverGateway: true is not passed, so resolveDockerDesktopWsl defaults to isDockerDesktopWslRuntime() which may be incorrect when called from Linux Docker-driver gateway context.
  • Impact: Incorrect host-network detection could cause the GPU bridge probe to be skipped when it should run (or vice versa), leading to false-positive inference reachability results on Linux Docker-driver gateways.
  • Recommended action: Fix the caller in onboard.ts:1893 to pass { dockerDriverGateway: true, dockerDesktopWsl: false } explicitly, or add a comment documenting that missing keys default to false safely. Verify resolveDockerDesktopWsl handles undefined correctly.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read src/lib/onboard.ts line 1893 and src/lib/onboard/docker-gpu-local-inference.ts lines 40-55 to verify the default behavior.
  • Missing regression test: Unit test for shouldSkipGpuBridgeProbe with dockerDriverGateway: true and dockerDesktopWsl: false to confirm correct host-network detection.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read src/lib/onboard.ts line 1893 and src/lib/onboard/docker-gpu-local-inference.ts lines 40-55 to verify the default behavior.
  • Evidence: onboard.ts:1893 calls shouldSkipGpuBridgeProbe(gpuPassthrough, _gpu?.platform); docker-gpu-local-inference.ts:40-55 shows resolveDockerDesktopWsl defaults to isDockerDesktopWslRuntime()

PRA-12 Resolve/justify — docker-gpu-patch.test.ts monolith growth +13 lines exceeds warning threshold

  • Location: src/lib/onboard/docker-gpu-patch.test.ts:1
  • Category: tests
  • Problem: docker-gpu-patch.test.ts grew from 1322 to 1335 lines (+13), exceeding the 1-19 warning threshold. Growth from [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix tests (validation-before-mutation, token validation, pre-rollback diagnostics).
  • Impact: Test file growth adds maintenance burden; mode-routing cases should be split on next growth.
  • Recommended action: Document as follow-up task in this PR. Current growth is from [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 security fix tests. Split the mode-routing cases on the next growth.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read src/lib/onboard/docker-gpu-patch.test.ts and identify test suites added for validation-before-mutation, token validation, pre-rollback diagnostics.
  • Missing regression test: No immediate test needed; existing tests cover new behavior. Plan extraction on next growth cycle.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read src/lib/onboard/docker-gpu-patch.test.ts and identify test suites added for validation-before-mutation, token validation, pre-rollback diagnostics.
  • Evidence: monolithDeltas shows +13 lines warning severity; staticTestInventory shows 20 test blocks in this file

PRA-13 Resolve/justify — start.sh comment should clarify dual-mode authorization for future auditors

  • Location: agents/hermes/start.sh:1620
  • Category: correctness
  • Problem: start.sh comment updated from 'Keep the guard as PID 1's direct child: --startup-owner is authenticated by exact parent identity' to 'Keep the guard as the startup owner's direct child: --startup-owner is authenticated by exact parent identity'. The dual-mode authorization (PID 1 direct child vs. startup owner child) should be clarified for future auditors.
  • Impact: Future auditors may not understand the two authorization branches (cold start vs runtime), leading to incorrect security assessments.
  • Recommended action: Update the comment to explicitly mention both authorization branches: PID 1 direct child (cold start) and startup owner's direct child (runtime config guard calls from PID 1 lifecycle handler).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read agents/hermes/start.sh lines 1615-1630 and verify comment mentions both branches.
  • Missing regression test: No test needed; documentation clarity only.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read agents/hermes/start.sh lines 1615-1630 and verify comment mentions both branches.
  • Evidence: diff shows comment change at line 1620; dual-mode documented in runtime-config-guard.py SOURCE_OF_TRUTH_REVIEW

PRA-14 Resolve/justify — Proof assertion uses exact string match instead of parser-compatible split for OPENSHELL_SANDBOX_COMMAND transport format

  • Location: test/e2e/live/hermes-gpu-startup-proof.ts:135
  • Category: correctness
  • Problem: Proof assertion uses exact string match instead of parser-compatible split for OPENSHELL_SANDBOX_COMMAND transport format. The extraPlaceholderEnv check expects exact string 'NEMOCLAW_EXTRA_PLACEHOLDER_KEYS=TELEGRAM_BOT_TOKEN_AGENT_A,SLACK_BOT_TOKEN_AGENT_B' but the serializer uses /[\s\u0085]+/u split.
  • Impact: Proof could pass with malformed transport format (e.g., using U+0085 next-line characters) that the actual parser would reject, or fail on valid parser-compatible formats.
  • Recommended action: Update the proof to split on whitespace including U+0085 (using the same regex as the serializer: /[\s\u0085]+/u), then assert the expected keys are present.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/e2e/live/hermes-gpu-startup-proof.ts lines 130-145 and verify the assertion uses parser-compatible split.
  • Missing regression test: Test that OPENSHELL_SANDBOX_COMMAND with U+0085 next-line characters is correctly parsed by both the serializer and the proof assertion.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/e2e/live/hermes-gpu-startup-proof.ts lines 130-145 and verify the assertion uses parser-compatible split.
  • Evidence: hermes-gpu-startup-proof.ts extraPlaceholderEnv assertion uses exact string match; startup command serializer uses /[\s\u0085]+/u split

PRA-15 Resolve/justify — docker-gpu-local-inference.ts monolith growth +15 lines (warning threshold 1-19)

  • Location: src/lib/onboard/docker-gpu-local-inference.ts:1
  • Category: architecture
  • Problem: docker-gpu-local-inference.ts grew from 440 to 455 lines (+15), within 1-19 warning threshold. Growth from enforceDockerGpuPatchPreserveNetwork network downgrade logic.
  • Impact: Network downgrade logic adds complexity; could be extracted to separate module if it grows further.
  • Recommended action: Review whether extraction is feasible. The network downgrade logic could be extracted to a separate module if it grows further.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read src/lib/onboard/docker-gpu-local-inference.ts and identify logical sections.
  • Missing regression test: No immediate test needed.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read src/lib/onboard/docker-gpu-local-inference.ts and identify logical sections.
  • Evidence: monolithDeltas shows +15 lines warning severity

PRA-16 Improvement — No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route

  • Location: test/e2e/live/hermes-gpu-startup.test.ts:1
  • Category: tests
  • Problem: No CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 to exercise legacy patch route. The test supports FORCE_LEGACY_GPU_PATCH env var but the workflow job hermes-gpu-startup does not include a matrix variant for it.
  • Impact: Legacy patch route (used on WSL/Jetson and as escape hatch) is not exercised in CI, risking regressions in the compatibility path.
  • Suggested action: Add a CI matrix entry for FORCE_LEGACY_GPU_PATCH=1 in the hermes-gpu-startup job definition (or a separate job variant) to exercise the legacy patch route.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check .github/workflows/e2e.yaml hermes-gpu-startup job for matrix strategy or env var override.
  • Missing regression test: CI job variant with FORCE_LEGACY_GPU_PATCH=1 that runs hermes-gpu-startup.test.ts and asserts legacy patch route logs appear.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: e2e.yaml hermes-gpu-startup job has no matrix; FORCE_LEGACY_GPU_PATCH used in test but not in CI

PRA-17 Improvement — Behavior change: shouldApplyDockerGpuPatch defaults to native OpenShell GPU injection on Linux

  • Location: src/lib/onboard/docker-gpu-patch.ts:540
  • Category: architecture
  • Problem: Behavior change: shouldApplyDockerGpuPatch defaults to native OpenShell GPU injection on ordinary native Linux. The compatibility patch (Docker container swap) is now only used on Docker Desktop WSL and Jetson/Tegra by default. Operators need to know about NEMOCLAW_DOCKER_GPU_PATCH=1 escape hatch for legacy behavior.
  • Impact: Operators upgrading from older versions may be surprised by changed GPU routing behavior; escape hatch must be documented.
  • Suggested action: Document this behavior change in release notes/migration guide. Verify hermes-gpu-startup live test covers both routes (it does via FORCE_LEGACY_GPU_PATCH env var). Ensure operators know about NEMOCLAW_DOCKER_GPU_PATCH=1 escape hatch.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read docs/reference/commands-nemohermes.mdx lines 365-380 and verify documentation covers new defaults and escape hatches.
  • Missing regression test: Release note entry documenting the GPU routing behavior change.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: docker-gpu-patch.ts:540 shouldApplyDockerGpuPatch logic; commands-nemohermes.mdx updated with new defaults

PRA-18 Improvement — Docker Desktop WSL compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW

  • Location: docs/reference/commands-nemohermes.mdx:365
  • Category: scope
  • Problem: Docker Desktop WSL compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW. The docs state 'On Docker Desktop WSL, the compatibility path skips CDI and tries Docker --gpus all before the NVIDIA runtime' but this is a localized workaround for Docker Desktop WSL's lack of usable CDI specs.
  • Impact: Without SOURCE_OF_TRUTH_REVIEW, the workaround lacks formal documentation of its constraints, making future removal evaluation difficult.
  • Suggested action: Add SOURCE_OF_TRUTH_REVIEW comment in docs/reference/commands-nemohermes.mdx:365 documenting: (1) invalid state = Docker Desktop WSL advertises CDI dirs but --device nvidia.com/gpu=all unusable, (2) source = Docker Desktop WSL integration, (3) cannot fix in this PR = upstream Docker Desktop issue, (4) regression test = manual verification on WSL, (5) removable when Docker Desktop exposes usable nvidia.com/gpu CDI specs in WSL.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -n 'SOURCE_OF_TRUTH_REVIEW' docs/reference/commands-nemohermes.mdx
  • Missing regression test: SOURCE_OF_TRUTH_REVIEW comment present with all five elements.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: localizedPatchSignals identifies commands-nemohermes.mdx:365 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-19 Improvement — Jetson/Tegra compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW

  • Location: docs/reference/commands-nemohermes.mdx:367
  • Category: scope
  • Problem: Jetson/Tegra compatibility path documentation needs SOURCE_OF_TRUTH_REVIEW. The docs state 'On Jetson/Tegra hosts, the compatibility path uses the NVIDIA runtime and adds the host group IDs that own /dev/nvmap and /dev/nvhost-*' but this is a localized workaround for Tegra device nodes owned by non-root group.
  • Impact: Without SOURCE_OF_TRUTH_REVIEW, the workaround lacks formal documentation of its constraints, making future removal evaluation difficult.
  • Suggested action: Add SOURCE_OF_TRUTH_REVIEW comment in docs/reference/commands-nemohermes.mdx:367 documenting: (1) invalid state = Tegra device nodes owned by non-root group, (2) source = Jetson/Tegra board support package, (3) cannot fix in this PR = hardware/BSP constraint, (4) regression test = CI on Jetson hardware, (5) removable when Tegra device nodes default to root:video or similar accessible group.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: grep -n 'SOURCE_OF_TRUTH_REVIEW' docs/reference/commands-nemohermes.mdx
  • Missing regression test: SOURCE_OF_TRUTH_REVIEW comment present with all five elements.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: localizedPatchSignals identifies commands-nemohermes.mdx:367 as fallback/recovery path; no SOURCE_OF_TRUTH_REVIEW in diff

PRA-20 Improvement — Documentation consistency: troubleshooting.mdx matches commands-nemohermes.mdx for GPU routing

  • Location: docs/reference/troubleshooting.mdx:1528
  • Category: correctness
  • Problem: Documentation consistency: troubleshooting.mdx matches commands-nemohermes.mdx for GPU routing. The troubleshooting section 'Docker GPU patch failed during sandbox create' has been updated to reflect new defaults (native injection on ordinary Linux, compatibility patch on WSL/Jetson).
  • Impact: Documentation is consistent — no action needed.
  • Suggested action: No action needed. The documentation is consistent.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read docs/reference/troubleshooting.mdx lines 1528-1580 and verify consistency with commands-nemohermes.mdx.
  • Missing regression test: None needed; documentation consistency verified.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: diff shows troubleshooting.mdx updated to match new GPU routing defaults

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

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ⚠️ Run cancelled — no signal

Run: 28548034088
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke
Summary: 0 passed, 0 failed, 2 cancelled, 0 skipped

Job Result
hermes-gpu-startup ⚠️ cancelled
hermes-root-entrypoint-smoke ⚠️ cancelled

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

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28548219046
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ❌ failure
hermes-root-entrypoint-smoke ✅ success

Failed jobs: hermes-gpu-startup. Check run artifacts for logs.

1 similar comment
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28548219046
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ❌ failure
hermes-root-entrypoint-smoke ✅ success

Failed jobs: hermes-gpu-startup. Check run artifacts for logs.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
test/e2e/live/hermes-gpu-startup-proof.ts (2)

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

Combined multi-assertion script obscures which invariant failed.

The startupConfig script chains four distinct checks (API-key format regex, two sha256sum -c hash validations, and a startup-guard log grep) into a single exit code / OK string. When it fails, the only signal is exit code and stdout — you can't tell from the assertion which specific invariant broke without manually digging into captured stderr/artifacts. Splitting these into separate execShell calls with individual expect assertions would make regressions immediately actionable.
[recommended_refactor: better failure diagnosability for a regression-proof test]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/live/hermes-gpu-startup-proof.ts` around lines 65 - 78, The
startupConfig check in hermes-gpu-startup-proof currently combines multiple
independent invariants into one shell command, making failures hard to diagnose.
Split the checks in trustedSandboxShellScript into separate sandbox.execShell
calls and add individual expect assertions for the API_SERVER_KEY regex,
/etc/nemoclaw/hermes.config-hash, /sandbox/.hermes/.config-hash, and the
/tmp/nemoclaw-start.log guard grep so each failure points to the exact invariant
that broke.

79-141: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Two sequential docker ps calls introduce a small TOCTOU window.

The running-containers check (lines 79-104) and the all-containers check (lines 118-140) query Docker separately; a container could theoretically stop/restart between the two calls, causing a spurious length mismatch. Low risk in this deterministic sandbox-lifecycle test, but worth noting if flakiness is observed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/live/hermes-gpu-startup-proof.ts` around lines 79 - 141, The test in
hermes-gpu-startup-proof.ts has a small TOCTOU window because it calls docker ps
twice, once for running containers and once for all containers, so the container
state can change between checks. Update the assertions around the host.command
docker queries to reuse a single snapshot of container listings, or otherwise
combine the checks so the container identity and state are validated from the
same point in time. Use the existing runningContainers, allContainers, and
containerState logic to keep the verification atomic.
tools/e2e/hermes-gpu-startup-workflow-boundary.mts (1)

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

Duplicated explicit-only selector format.

EXPECTED_SELECTOR hardcodes the same contains(format(...)) pattern that explicitOnlyFreeStandingJobIf already builds for other explicit-only jobs (used for jetson-nvmap-gpu, sandbox-rlimits-connect, etc. in workflow-boundary.mts). Duplicating the literal string risks drift if the shared helper's format ever changes.

♻️ Suggested refactor
-const EXPECTED_SELECTOR =
-  "${{ contains(format(',{0},', inputs.jobs), ',hermes-gpu-startup,') || contains(format(',{0},', inputs.targets), ',hermes-gpu-startup,') }}";
+const EXPECTED_SELECTOR = explicitOnlyFreeStandingJobIf(JOB_NAME, JOB_NAME);

(requires exporting explicitOnlyFreeStandingJobIf from workflow-boundary.mts and importing it 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 `@tools/e2e/hermes-gpu-startup-workflow-boundary.mts` around lines 22 - 23,
`EXPECTED_SELECTOR` is duplicating the explicit-only selector template instead
of reusing the shared builder. Export `explicitOnlyFreeStandingJobIf` from
`workflow-boundary.mts` and import it into
`hermes-gpu-startup-workflow-boundary.mts`, then construct the hermes selector
through that helper using the hermes job name. Keep the existing
`EXPECTED_SELECTOR` constant only as the derived result, not a hardcoded
`contains(format(...))` literal, so it stays aligned with the other
explicit-only job selectors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/e2e/live/hermes-gpu-startup-proof.ts`:
- Around line 65-78: The startupConfig check in hermes-gpu-startup-proof
currently combines multiple independent invariants into one shell command,
making failures hard to diagnose. Split the checks in trustedSandboxShellScript
into separate sandbox.execShell calls and add individual expect assertions for
the API_SERVER_KEY regex, /etc/nemoclaw/hermes.config-hash,
/sandbox/.hermes/.config-hash, and the /tmp/nemoclaw-start.log guard grep so
each failure points to the exact invariant that broke.
- Around line 79-141: The test in hermes-gpu-startup-proof.ts has a small TOCTOU
window because it calls docker ps twice, once for running containers and once
for all containers, so the container state can change between checks. Update the
assertions around the host.command docker queries to reuse a single snapshot of
container listings, or otherwise combine the checks so the container identity
and state are validated from the same point in time. Use the existing
runningContainers, allContainers, and containerState logic to keep the
verification atomic.

In `@tools/e2e/hermes-gpu-startup-workflow-boundary.mts`:
- Around line 22-23: `EXPECTED_SELECTOR` is duplicating the explicit-only
selector template instead of reusing the shared builder. Export
`explicitOnlyFreeStandingJobIf` from `workflow-boundary.mts` and import it into
`hermes-gpu-startup-workflow-boundary.mts`, then construct the hermes selector
through that helper using the hermes job name. Keep the existing
`EXPECTED_SELECTOR` constant only as the derived result, not a hardcoded
`contains(format(...))` literal, so it stays aligned with the other
explicit-only job selectors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ab4d5bbc-8aa6-4d72-adc3-c742e2b09674

📥 Commits

Reviewing files that changed from the base of the PR and between e0c7388 and 14c9a82.

📒 Files selected for processing (6)
  • .github/workflows/e2e.yaml
  • test/e2e/live/hermes-gpu-startup-proof.ts
  • test/e2e/live/hermes-gpu-startup.test.ts
  • test/e2e/support/hermes-workflow-boundary.test.ts
  • tools/e2e/hermes-gpu-startup-workflow-boundary.mts
  • tools/e2e/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/e2e.yaml

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28549714069
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ❌ failure
hermes-root-entrypoint-smoke ✅ success

Failed jobs: hermes-gpu-startup. Check run artifacts for logs.

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

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28550860758
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ❌ failure

Failed jobs: hermes-gpu-startup. Check run artifacts for logs.

prekshivyas and others added 2 commits July 1, 2026 15:29
…uardrail

codebase-growth-guardrails rejects new if statements in test files.
Replace the diagnostic capture if-branch with a ternary so the
guardrail passes without changing behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa changed the title fix(hermes): accept GPU-supervised startup owner fix(gpu): preserve OpenShell supervisor command boundary Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ⚠️ Some jobs cancelled — partial pass

Run: 28552460943
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke
Summary: 1 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
hermes-gpu-startup ⚠️ cancelled
hermes-root-entrypoint-smoke ✅ success

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

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28552985970
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ❌ failure
hermes-root-entrypoint-smoke ✅ success

Failed jobs: hermes-gpu-startup. Check run artifacts for logs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
test/e2e/live/hermes-gpu-startup-proof.ts (1)

76-76: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the PID 1 argv rejection catch embedded nemoclaw-start tokens.

Line 76 only rejects exact argv items, so a polluted supervisor argument such as --command=/usr/local/bin/nemoclaw-start would pass while still carrying the superseded startup path.

Proposed test hardening
-      String.raw`python3 -c 'import json; from pathlib import Path; argv=[item.decode("utf-8", "strict") for item in Path("/proc/1/cmdline").read_bytes().split(b"\0") if item]; print(json.dumps({"argv0": argv[0] if argv else "", "has_nemoclaw_start": any(item in ("nemoclaw-start", "/usr/local/bin/nemoclaw-start") for item in argv)}))'`,
+      String.raw`python3 - <<'PY'
+import json
+from pathlib import Path
+
+argv = [
+    item.decode("utf-8", "strict")
+    for item in Path("/proc/1/cmdline").read_bytes().split(b"\0")
+    if item
+]
+print(json.dumps({
+    "argv0": argv[0] if argv else "",
+    "has_nemoclaw_start": any("nemoclaw-start" in item for item in argv),
+}))
+PY`,

As per path instructions, migration tests must prove the superseded path is unreachable or removed, not merely prove that the new path also works.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/live/hermes-gpu-startup-proof.ts` at line 76, The PID 1 argv check
in hermes-gpu-startup-proof is too strict because it only matches exact argv
entries, so embedded superseded startup paths can slip through. Update the
command in the test to detect any argv item containing the legacy nemoclaw-start
path/token, and keep the check anchored around the existing /proc/1/cmdline
parsing and has_nemoclaw_start logic so the migration proof fails if the old
path is merely hidden inside another argument.

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 `@test/e2e/support/hermes-gpu-startup-integrity.test.ts`:
- Around line 70-87: runProof() currently inherits the full process.env, so bash
-c can pick up host-specific variables and make the proof behavior
non-deterministic. Update runProof to use a scrubbed environment instead of
process.env, then explicitly add only the variables each test case needs; keep
the PYTHONPATH override scoped to the shadowing scenario. Use the runProof
helper and its spawnSync/bash -c invocation as the place to apply the minimal
env.

In `@test/e2e/support/hosted-inference.test.ts`:
- Around line 429-444: The request assertions in hosted-inference.test.ts only
verify one forbidden-marker occurrence and can miss extra leaks because the fake
server records matches via forbiddenMarkerMatches rather than the raw marker
string. Tighten the test around fake.requests() by asserting the total
forbidden-marker count across all recorded requests, not just arrayContaining
entries or JSON text. Use the existing request shape fields such as auth, path,
stream, and forbiddenMarkerMatches to locate the relevant assertion block and
make the expectation fail if any authenticated request includes the marker.

---

Outside diff comments:
In `@test/e2e/live/hermes-gpu-startup-proof.ts`:
- Line 76: The PID 1 argv check in hermes-gpu-startup-proof is too strict
because it only matches exact argv entries, so embedded superseded startup paths
can slip through. Update the command in the test to detect any argv item
containing the legacy nemoclaw-start path/token, and keep the check anchored
around the existing /proc/1/cmdline parsing and has_nemoclaw_start logic so the
migration proof fails if the old path is merely hidden inside another argument.
🪄 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: 5d535b9e-e2e0-409c-a1a5-d19b3a3559fc

📥 Commits

Reviewing files that changed from the base of the PR and between 362a172 and 6ac4ebc.

📒 Files selected for processing (22)
  • agents/hermes/Dockerfile
  • agents/hermes/validate-env-secret-boundary.py
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • src/lib/onboard.ts
  • src/lib/onboard/docker-gpu-local-inference.test.ts
  • src/lib/onboard/docker-gpu-local-inference.ts
  • src/lib/onboard/docker-gpu-patch.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts
  • src/lib/onboard/docker-gpu-sandbox-create.test.ts
  • test/e2e/fixtures/fake-openai-compatible.ts
  • test/e2e/lib/fake-openai-compatible-api.mts
  • test/e2e/live/hermes-gpu-startup-integrity.ts
  • test/e2e/live/hermes-gpu-startup-proof.ts
  • test/e2e/live/hermes-gpu-startup.test.ts
  • test/e2e/support/hermes-gpu-startup-integrity.test.ts
  • test/e2e/support/hosted-inference.test.ts
  • test/e2e/support/jetson-workflow-boundary.test.ts
  • test/hermes-gateway-wrapper.test.ts
  • test/hermes-openshell-runtime-env-boundary.test.ts
✅ Files skipped from review due to trivial changes (2)
  • test/e2e/support/jetson-workflow-boundary.test.ts
  • docs/reference/commands-nemohermes.mdx
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/lib/onboard/docker-gpu-local-inference.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts
  • src/lib/onboard/docker-gpu-local-inference.test.ts
  • test/e2e/live/hermes-gpu-startup.test.ts
  • src/lib/onboard.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts
  • src/lib/onboard/docker-gpu-sandbox-create.test.ts
  • src/lib/onboard/docker-gpu-patch.ts

Comment thread test/e2e/support/hermes-gpu-startup-integrity.test.ts Outdated
Comment thread test/e2e/support/hosted-inference.test.ts Outdated
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All requested jobs passed

Run: 28568959028
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ✅ success

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28568490864
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,gpu-e2e,credential-sanitization,hermes-sandbox-secret-boundary,hermes-root-entrypoint-smoke,messaging-providers
Summary: 5 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
credential-sanitization ✅ success
gpu-e2e ✅ success
hermes-gpu-startup ❌ failure
hermes-root-entrypoint-smoke ✅ success
hermes-sandbox-secret-boundary ✅ success
messaging-providers ✅ success

Failed jobs: hermes-gpu-startup. Check run artifacts for logs.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28568069499
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,hermes-root-entrypoint-smoke,gpu-e2e,hermes-sandbox-secret-boundary,messaging-providers,credential-sanitization
Summary: 4 passed, 2 failed, 0 cancelled, 0 skipped

Job Result
credential-sanitization ✅ success
gpu-e2e ✅ success
hermes-gpu-startup ❌ failure
hermes-root-entrypoint-smoke ✅ success
hermes-sandbox-secret-boundary ✅ success
messaging-providers ❌ failure

Failed jobs: hermes-gpu-startup, messaging-providers. Check run artifacts for logs.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All requested jobs passed

Run: 28568954862
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,gpu-e2e,credential-sanitization,hermes-sandbox-secret-boundary,hermes-root-entrypoint-smoke,messaging-providers
Summary: 6 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
credential-sanitization ✅ success
gpu-e2e ✅ success
hermes-gpu-startup ✅ success
hermes-root-entrypoint-smoke ✅ success
hermes-sandbox-secret-boundary ✅ success
messaging-providers ✅ success

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

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All requested jobs passed

Run: 28597329591
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ✅ success

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
src/lib/onboard/docker-gpu-diagnostic-redaction.ts (2)

52-69: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

No minimum length on discovered sensitive values before blanket substring redaction.

discoverDockerGpuDiagnosticSensitiveValues only filters value.length > 0, and redactText does a global split(value).join("<REDACTED>") for every discovered value. A short env value (e.g. a 1–2 character token/flag matching SENSITIVE_ENV_KEY or an EXTRA_PLACEHOLDER_KEYS entry) would get replaced everywhere it appears in every diagnostic artifact, including inside unrelated timestamps, exit codes, or container-id fragments — degrading the usefulness of the whole bundle for a single short value.

♻️ Suggested guard
     .filter(
       ([key, value]) =>
-        (SENSITIVE_ENV_KEY.test(key) || extraPlaceholderKeys.has(key)) && value.length > 0,
+        (SENSITIVE_ENV_KEY.test(key) || extraPlaceholderKeys.has(key)) && value.length >= 6,
     )

Also applies to: 76-86

🤖 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-gpu-diagnostic-redaction.ts` around lines 52 - 69,
`discoverDockerGpuDiagnosticSensitiveValues` is collecting any non-empty matched
env value, which can cause `redactText` to blanket-replace very short strings
across unrelated diagnostics. Update the filtering in
`discoverDockerGpuDiagnosticSensitiveValues` (and keep it consistent with any
callers like `redactText`) to require a reasonable minimum length before
returning values for redaction, so short flags/tokens from `SENSITIVE_ENV_KEY`
or `EXTRA_PLACEHOLDER_KEYS_ENV` are not redacted globally.

7-9: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

SENSITIVE_ENV_KEY pattern misses generic *_KEY secrets.

The regex catches api_?key/private_?key but not a bare key suffix (e.g. ENCRYPTION_KEY, SIGNING_KEY, MASTER_KEY). Values under such names bypass both this heuristic and the NEMOCLAW_EXTRA_PLACEHOLDER_KEYS allowlist unless a caller explicitly opts them in, so they could be written to the on-disk diagnostics bundle unredacted.

🔒 Suggested widening
-const SENSITIVE_ENV_KEY =
-  /(?:api_?key|token|secret|password|credential|authorization|cookie|private_?key|proxy)/i;
+const SENSITIVE_ENV_KEY =
+  /(?:api_?key|_?key$|token|secret|password|credential|authorization|cookie|proxy)/i;
🤖 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-gpu-diagnostic-redaction.ts` around lines 7 - 9, The
redaction heuristic in SENSITIVE_ENV_KEY is too narrow and misses generic secret
names ending in KEY, so update the pattern in docker-gpu-diagnostic-redaction.ts
to also match bare *_KEY-style environment names such as ENCRYPTION_KEY,
SIGNING_KEY, and MASTER_KEY. Keep the existing handling around
EXTRA_PLACEHOLDER_KEYS, but widen the matcher used by the redaction logic so
these values are treated as sensitive by default and do not get written
unredacted by the diagnostics bundle.
src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts (1)

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

Clock stub hardcodes internal call count.

The fixed 8-element clock array ties the test to the exact number of Date.now() invocations made internally by boundedDiagnosticsDeps/priming/snapshot before collectDockerGpuPatchDiagnostics's own inspect loop runs. Any future change adding/removing one timing check would silently shift which call the test lands on, without a clear failure signal pointing at the real cause.

Consider driving elapsed time from the actual budget/timeout constants (e.g. mock Date.now to return a monotonically increasing value derived from PRE_ROLLBACK_DIAGNOSTICS_TOTAL_BUDGET_MS) rather than a fixed-length array, so the test communicates intent independent of internal call count.
As per path instructions, "Prefer observable outcomes ... 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-gpu-pre-rollback-diagnostics.test.ts` around lines 173
- 174, The test for collectDockerGpuPatchDiagnostics uses a fixed 8-value
Date.now() clock stub, which is tied to an internal call count in
boundedDiagnosticsDeps/priming/snapshot. Replace the array-based mock with a
monotonically increasing time source driven by the actual budget/timeout
constants (for example, based on PRE_ROLLBACK_DIAGNOSTICS_TOTAL_BUDGET_MS) so
the test asserts observable elapsed-time behavior rather than the exact number
of Date.now() calls. Keep the change localized to the Date.now spy setup in
docker-gpu-pre-rollback-diagnostics.test.ts and ensure the inspect loop still
exercises the intended timeout path.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/lib/onboard/docker-gpu-diagnostic-redaction.ts`:
- Around line 52-69: `discoverDockerGpuDiagnosticSensitiveValues` is collecting
any non-empty matched env value, which can cause `redactText` to blanket-replace
very short strings across unrelated diagnostics. Update the filtering in
`discoverDockerGpuDiagnosticSensitiveValues` (and keep it consistent with any
callers like `redactText`) to require a reasonable minimum length before
returning values for redaction, so short flags/tokens from `SENSITIVE_ENV_KEY`
or `EXTRA_PLACEHOLDER_KEYS_ENV` are not redacted globally.
- Around line 7-9: The redaction heuristic in SENSITIVE_ENV_KEY is too narrow
and misses generic secret names ending in KEY, so update the pattern in
docker-gpu-diagnostic-redaction.ts to also match bare *_KEY-style environment
names such as ENCRYPTION_KEY, SIGNING_KEY, and MASTER_KEY. Keep the existing
handling around EXTRA_PLACEHOLDER_KEYS, but widen the matcher used by the
redaction logic so these values are treated as sensitive by default and do not
get written unredacted by the diagnostics bundle.

In `@src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts`:
- Around line 173-174: The test for collectDockerGpuPatchDiagnostics uses a
fixed 8-value Date.now() clock stub, which is tied to an internal call count in
boundedDiagnosticsDeps/priming/snapshot. Replace the array-based mock with a
monotonically increasing time source driven by the actual budget/timeout
constants (for example, based on PRE_ROLLBACK_DIAGNOSTICS_TOTAL_BUDGET_MS) so
the test asserts observable elapsed-time behavior rather than the exact number
of Date.now() calls. Keep the change localized to the Date.now spy setup in
docker-gpu-pre-rollback-diagnostics.test.ts and ensure the inspect loop still
exercises the intended timeout path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d22ab199-ad6b-4e0c-9add-ffd77fdf44ad

📥 Commits

Reviewing files that changed from the base of the PR and between 65b06d6 and 5c87782.

📒 Files selected for processing (7)
  • src/lib/onboard/docker-gpu-diagnostic-redaction.test.ts
  • src/lib/onboard/docker-gpu-diagnostic-redaction.ts
  • src/lib/onboard/docker-gpu-patch.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.test.ts
  • src/lib/onboard/docker-gpu-pre-rollback-diagnostics.ts
  • test/e2e/support/hermes-gpu-startup-integrity.test.ts
  • test/e2e/support/hosted-inference.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e/support/hermes-gpu-startup-integrity.test.ts
  • test/e2e/support/hosted-inference.test.ts

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

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All requested jobs passed

Run: 28599180561
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ✅ success

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ❌ Some jobs failed

Run: 28597318221
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,gpu-e2e,credential-sanitization,hermes-sandbox-secret-boundary,hermes-root-entrypoint-smoke,messaging-providers
Summary: 5 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
credential-sanitization ✅ success
gpu-e2e ✅ success
hermes-gpu-startup ✅ success
hermes-root-entrypoint-smoke ✅ success
hermes-sandbox-secret-boundary ✅ success
messaging-providers ❌ failure

Failed jobs: messaging-providers. Check run artifacts for logs.

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

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ⚠️ Run cancelled — no signal

Run: 28599177758
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,gpu-e2e,credential-sanitization,hermes-sandbox-secret-boundary,hermes-root-entrypoint-smoke,messaging-providers
Summary: 0 passed, 0 failed, 6 cancelled, 0 skipped

Job Result
credential-sanitization ⚠️ cancelled
gpu-e2e ⚠️ cancelled
hermes-gpu-startup ⚠️ cancelled
hermes-root-entrypoint-smoke ⚠️ cancelled
hermes-sandbox-secret-boundary ⚠️ cancelled
messaging-providers ⚠️ cancelled

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All requested jobs passed

Run: 28601348023
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-gpu-startup ✅ success

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Target Results — ✅ All requested jobs passed

Run: 28601346031
Workflow ref: fix/hermes-gpu-startup-6110
Requested targets: (default — all supported)
Requested jobs: hermes-gpu-startup,gpu-e2e,credential-sanitization,hermes-sandbox-secret-boundary,hermes-root-entrypoint-smoke,messaging-providers
Summary: 6 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
credential-sanitization ✅ success
gpu-e2e ✅ success
hermes-gpu-startup ✅ success
hermes-root-entrypoint-smoke ✅ success
hermes-sandbox-secret-boundary ✅ success
messaging-providers ✅ success

@ericksoa ericksoa removed the v0.0.72 Release target label Jul 2, 2026
@ericksoa ericksoa self-assigned this Jul 2, 2026
@ericksoa

ericksoa commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Exact-head disposition for d76f1647a5f354ba04737a6a049b82bfbf6d5454:

Candidate and runtime evidence

  • The signed merge commit is GitHub Verified and contains current main through 9fe45362, including test(e2e): prevent process-token probe self-matches #6167's process-probe self-match correction. The PR is approved and mergeable/CLEAN. Exact-head PR checks are terminal: 48 successful, 3 expected skips, 0 failures or pending.
  • GPT-5.5 recommends merge_as_is with 0 required findings, warnings, or suggestions. Its runtime follow-ups are now covered: native Ready/CUDA, failed-clone capture before rollback, image/integrity validation, the [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110 startup boundary, and separate native/legacy command-boundary proof.
  • Full six-job run 28601346031 passed all requested targets. The corrected messaging scanner passed on its first attempt with all 21 raw-token env/process/filesystem probes ABSENT; all target cleanup records have zero failures.
  • Focused native run 28601348023 passed 9/9 assertions. Artifact 8043702467 (sha256:0ef929fa2478f5c9579ad2f282c46de8fe4d6eefb04acb062de1af29b4eb002c) proves Ready/CUDA, all three GPU probes, OpenShell PID 1, one container/no backup, integrity and negative guard checks, authenticated inference with zero forbidden-marker matches, and clean teardown.
  • Failed-clone run 28602166456 used a signed workflow-only child that explicitly checked out d76f1647. Artifact 8044114375 (sha256:b5cff9cc7e7cf361f55e074a265c8cfefd3e6dc21ad0d300b140d2a749cde00b) records clone exit 137, failure_kind=patched_container_failed, and rolled_back=no before finalize; afterward it records rolled_back=yes, exactly one running original container, no backup leak, guard-observed clone removal, clean canary scans, and clean teardown.
  • Forced-legacy success run 28603335692 used signed workflow-only child 078a372d whose exact parent is d76f1647, and passed 9/9 assertions. Artifact 8044550700 (sha256:56d97c5caa8536ebff735ff600399ac7fafa2fed71206de1f5470e7d15549f6f) proves the legacy route, --device nvidia.com/gpu=all, Ready/CUDA with all three GPU probes, correct PID 1/command envelope, one container/no backup, integrity and guard checks, two authenticated inference requests with zero forbidden-marker matches, a clean canary scan, and clean teardown.

Nemotron disposition

  • PRA-4, PRA-5, PRA-12, PRA-15, and PRA-T7 are size-threshold refactor requests, not uncovered behavior. Repository growth, test-size, source-shape, typecheck, and exact-head CI gates pass. The PR body records the accurate +58/+32/+13/+15 counts and defers extraction until the compatibility surface next grows or retires; maintainer acceptance of that narrow release-blocker scope is requested.
  • PRA-6 overcounts the overlap set. A refreshed audit finds five peer PRs touching e2e.yaml: pairwise clean with chore(openclaw): upgrade to 2026.6.10 and harden runtime integration #5595/perf(e2e): extend trace timing artifacts to Vitest targets #6153; feat(mcp): add OpenShell-managed MCP servers #5876 directly conflicts and must union both explicit-only jobs plus uploader validation; chore(openshell): upgrade supported version to 0.0.72 #6020 already conflicts with main and overlaps outside e2e.yaml; test(e2e): refactor messaging channel coverage #6053 is mergeable with main but conflicts pairwise in the uploader boundary. fix(gpu): prefer native OpenShell injection #6142 itself remains mergeable/CLEAN, and the body now carries the merge-order handoff.
  • PRA-7, PRA-T1PRA-T4, and PRA-T6 are covered. Exact-head tests inject conventional *_KEY, startup-command, extra-placeholder, and discovered-inspect canaries; prove inspect-before-write and exhausted-budget priming; scan all nine artifact sinks plus returned summaries; retain valid JSON; and prove collector-owned docker-top publication. The live failed-clone artifact additionally proves that boundary before rollback.
  • PRA-8/PRA-1: source states that the wrapper owns only the 10s/2s budget and the shared collector is the sole redaction/publication boundary; the body records the invalid state, source boundary, regression proof, and removal condition. Requiring a literal SOURCE_OF_TRUTH_REVIEW marker would not add a runtime invariant; maintainer acceptance of the existing documentation is requested.
  • PRA-9: provenance was verified against NVIDIA/OpenShell@v0.0.71 (a242f84bb367d6df7d4d133e95a93857406c67f7), where driver_utils.rs::TLS_KEY_MOUNT_PATH is exactly /etc/openshell/tls/client/tls.key and Docker/Podman inject it. NemoClaw accepts only that exact runtime pair; alternate, PEM, relative, near-miss, persisted-.env, and supervisor-identity values fail closed. The body now records this provenance; maintainer acceptance instead of integrity-pin churn for an in-source comment is requested.
  • PRA-2, PRA-3, PRA-18, and PRA-19: the body now records the Docker Desktop WSL CDI boundary and the Jetson/Tegra device-ownership/group-propagation boundary, their regression tests, and their removal conditions.
  • PRA-10: workflow-inventory.mts --shell returns the exact explicit-only set named by the dispatch description: openshell-gateway-auth-contract, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu. Existing workflow-boundary checks pass; a generalized description parser is outside [DGX Spark][Sandbox] NemoHermes sandbox PID 1 exits 1 at ensure-api-key on startup in v0.0.71 #6110.
  • PRA-11: shouldSkipGpuBridgeProbe() overlays dockerDriverGateway: true, resolves WSL internally when omitted, and tests partial options/overrides; the incomplete-options concern is not a live logic gap.
  • PRA-13: the current comment says “startup owner's direct child,” and --startup-owner is authenticated by exact parent identity. Both unauthorized-owner live probes fail closed.
  • PRA-14: the cited exact assertion intentionally proves canonical placeholder transport. Parser whitespace compatibility and PID 1 executable identity are tested separately; loosening the live canonical assertion would weaken the proof.
  • PRA-T5, PRA-T8, and PRA-16 are covered by the separate exact-parent forced-legacy run without permanently doubling scarce GPU CI. Native-default and force-legacy behavior is documented consistently. PRA-20/PRA-21 require no action, and PRA-22/PRA-23 would incorrectly remove inventory metadata used to classify the job as explicit-only.

CodeRabbit disposition

  • The valid generic *_KEY gap is fixed in e077aa6b and retained by d76f1647, with a bare-log canary regression.
  • The proposed six-character minimum is intentionally rejected because retaining a 1–5 byte secret to improve diagnostic readability violates fail-closed redaction.
  • The fixed clock sequence is a test-maintainability nit, not a production defect; current observable assertions prove fail-closed output, and the stub may need adjustment if timing-call structure changes.

All six inline GitHub review threads are marked resolved. The non-binding Nemotron findings above are dispositioned for maintainer acceptance; the PR has not been merged. Reporter-class DGX Spark aarch64 / DGX Station GB300 NVIDIA Endpoints validation is still unavailable in declared repository runners, so this PR does not claim issue #6110 resolved.

@ericksoa ericksoa merged commit 3a767fb into main Jul 2, 2026
205 checks passed
@ericksoa ericksoa deleted the fix/hermes-gpu-startup-6110 branch July 2, 2026 16:50
@cv cv mentioned this pull request Jul 2, 2026
21 tasks
cv added a commit that referenced this pull request Jul 2, 2026
<!-- markdownlint-disable MD041 -->
## Summary
This PR prepares the user-facing documentation for v0.0.73 before the
release plan is frozen.
It adds release notes for the merged runtime changes and closes
documentation gaps around DNS-backed HTTPS endpoint validation and
LangChain Deep Agents Code proxy recovery.

## Changes
- Add the `v0.0.73` release-note section with links to the detailed
command, inference, recovery, lifecycle, platform, and setup
documentation.
- Correct the custom endpoint guidance so DNS-backed HTTPS rejection and
the supported alternatives match the fail-closed runtime behavior.
- Document the managed `inference.local` proxy boundary and rebuild
requirement for existing LangChain Deep Agents Code sandboxes.
- Add troubleshooting guidance for the DNS-backed HTTPS validation
error.
- Validate with `npm run docs:sync-agent-variants` and `npm run docs`;
Fern completed with 0 errors and 2 existing warnings.
- Source summary:
- [#6139](#6139) ->
`docs/about/release-notes.mdx`, `docs/inference/inference-options.mdx`,
`docs/reference/commands.mdx`, `docs/reference/commands-nemohermes.mdx`,
and `docs/reference/troubleshooting.mdx`: Document fail-closed
DNS-backed HTTPS endpoint handling and recovery options.
- [#6142](#6142) ->
`docs/about/release-notes.mdx`: Summarize native OpenShell GPU injection
and compatibility-path diagnostics.
- [#6197](#6197) ->
`docs/about/release-notes.mdx`: Summarize agent-aware messaging preset
rejection.
- [#6199](#6199) ->
`docs/about/release-notes.mdx`: Summarize the unreachable-sandbox backup
opt-in, restore behavior, and data-loss boundary.
- [#6204](#6204) and
[#6206](#6206) ->
`docs/about/release-notes.mdx` and
`docs/get-started/quickstart-langchain-deepagents-code.mdx`: Document
the corrected managed proxy contract and required sandbox rebuild.
- [#6213](#6213) ->
`docs/about/release-notes.mdx`: Summarize the merged setup, recovery,
and host-state documentation.

## Type of Change

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

## Quality Gates
<!-- 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: documentation-only release
preparation; the Fern docs build validates the changed pages and routes.
- [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)
- [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: Carlos Villela <cvillela@nvidia.com>


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

* **Documentation**
* Added a new **v0.0.73** release notes section with six highlights at
the top of the changelog.
* Expanded **Custom Endpoint URL Validation** guidance in inference
option docs, including explicit acceptance/rejection rules for HTTP vs
DNS-backed HTTPS and how validated IPs are stored.
* Updated command references (`nemohermes inference set`, `$$nemoclaw
inference set`) to match the new validation behavior.
* Added troubleshooting documentation for unsupported **DNS-backed HTTPS
endpoints**, plus clarified Deep Agents Code routing and post-upgrade
sandbox rebuild guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@hulynn

hulynn commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Hi @ericksoa @cv
The #6110 root-cause fix (supervisor command boundary in buildDockerGpuCloneRunArgs) is a genuine fix, but the headline change — flipping native CDI Linux to OpenShell's native --gpu injection by default and repurposing NEMOCLAW_DOCKER_GPU_PATCH semantics (0=opt-out → 1=force-legacy) — is a behavior-changing feature, not a fix.
Suggest retitling to feat(gpu): — that way it gets picked up by our feature-test triage, so QA adds coverage for both the new native-injection default and the =1 legacy path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression integration: hermes Hermes integration behavior v0.0.73 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants