Skip to content

fix(hermes): use OpenAI frontend for custom Anthropic#6335

Merged
cv merged 3 commits into
mainfrom
fix/6289-hermes-openai-frontend
Jul 6, 2026
Merged

fix(hermes): use OpenAI frontend for custom Anthropic#6335
cv merged 3 commits into
mainfrom
fix/6289-hermes-openai-frontend

Conversation

@apurvvkumaria

@apurvvkumaria apurvvkumaria commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fix Hermes custom Anthropic routing by using the endpoint's verified OpenAI Chat Completions surface end to end. NemoClaw selects https://inference.local/v1, verifies /v1/chat/completions, and aligns the OpenShell provider to type=openai with OPENAI_BASE_URL, avoiding the duplicate Anthropic SSE message_start sequence that caused hermes -z to finish with no final response.

The core managed-frontend direction was first proposed by @chengjiew in #6295, and Chengjie Wang is included as a commit co-author. @TonyLuo-NV's #6297 contributed streaming-failure investigation and regression analysis. Thanks to @hulynn for the reproducible managed-proxy report.

Related Issue

Fixes #6289

Changes

  • Resolve Hermes compatible-anthropic-endpoint routes to the managed openai-completions frontend and reuse fix(inference): keep /v1 base URL for OpenAI-only agents on Anthropic-compatible endpoints #6298's verified OpenAI-surface provider registration while retaining COMPATIBLE_ANTHROPIC_API_KEY as the credential binding.
  • Persist the normalized frontend during fresh onboarding; repair stale provider identity, registry metadata, and sandbox configuration during rebuild or resume.
  • Reject conflicting explicit API choices and legacy type=anthropic runtime switches before mutating OpenShell, registry, or in-sandbox state.
  • Preserve native Anthropic Messages routing for OpenClaw custom endpoints and first-party Anthropic routes; preserve the existing AWS Bedrock adapter behavior.
  • Extend unit, integration, command-shape, and live E2E coverage, including the reported hermes -z path; document the verified-surface requirement and rebuild migration.

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 final review found no blockers. Endpoint probing and provider replacement reuse the fail-closed fix(inference): keep /v1 base URL for OpenAI-only agents on Anthropic-compatible endpoints #6298 boundary; this PR adds exact non-secret provider identity checks and introduces no credential values. Human maintainer approval remains required.
  • 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
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — 289 CLI tests, 7 OpenAI-surface onboarding integration tests, 1 focused Hermes config integration test, and 18 E2E support tests passed
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — required GitHub Actions checks pending
  • 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) — completed with 0 errors and 2 existing Fern warnings
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Additional local verification:

  • npm run build:cli
  • npm run typecheck:cli
  • npm run checks
  • npm run test-size:check
  • npm run test:titles:check
  • npm run source-shape:check
  • npm run test:projects:check
  • npm run test:imports:check
  • npm run docs (0 errors; 2 existing warnings)

Signed-off-by: Apurv Kumaria akumaria@nvidia.com

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Chengjie Wang <chengjiew@nvidia.com>
Signed-off-by: Chengjie Wang <chengjiew@nvidia.com>
@apurvvkumaria

apurvvkumaria commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

Authorship and contributor credit:

Thank you all for the original diagnosis and investigation that informed this fix.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Hermes-specific inference routing for compatible Anthropic endpoints to use the managed OpenAI frontend, then threads that behavior through inference-set, onboarding, rebuild/resume, sandbox resume drift detection, docs, and end-to-end tests.

Changes

Hermes Anthropic-compatible route mapping

Layer / File(s) Summary
Core resolver and routing integration
src/lib/inference/config.ts, src/lib/inference/config.test.ts, src/lib/actions/inference-route-api.ts, src/lib/actions/inference-route-api.test.ts
Adds resolveAgentInferenceApi and uses it in runtime route resolution, with tests covering Hermes, OpenClaw, and custom-route cases.
inference-set validation and registry sync
src/lib/actions/inference-set.ts, src/lib/actions/inference-set-hermes-run.test.ts, docs/inference/inference-options.mdx, docs/inference/switch-inference-providers.mdx, src/lib/onboard/inference-providers/remote.ts, src/lib/onboard/providers.test.ts
Validates Hermes compatible Anthropic setup against the managed OpenAI surface, preserves the agent-aware preferred API in registry updates, and updates the related docs and provider mapping tests.
Onboarding provider selection and rebuild/resume config
src/lib/onboard/machine/handlers/provider-inference.ts, src/lib/onboard/machine/handlers/provider-inference.test.ts, src/lib/actions/sandbox/rebuild-resume-config.ts, src/lib/actions/sandbox/rebuild-resume-config.test.ts, src/lib/onboard/resume-provider-shim.ts, src/lib/onboard.ts, src/lib/onboard/gateway-provider-metadata.ts, src/lib/onboard/gateway-provider-metadata.test.ts, src/lib/onboard/machine/core-flow-phases.test.ts
Recomputes preferred inference APIs during onboarding and rebuild flows, adds resume-provider surface checks, and introduces strict gateway provider binding matching helpers and coverage.
Sandbox resume inference-route drift detection
src/lib/onboard/machine/handlers/sandbox-resume.ts, src/lib/onboard/machine/handlers/sandbox-resume.test.ts, src/lib/onboard/machine/handlers/sandbox.ts, src/lib/onboard/machine/handlers/sandbox.test.ts
Adds inference-route drift detection for Hermes compatible Anthropic routes and uses it to recreate sandboxes when the recorded route no longer matches.
E2E and support test helpers
test/e2e/live/hermes-inference-switch-helpers.ts, test/e2e/live/hermes-inference-switch.test.ts, test/e2e/support/hermes-inference-switch-command-shape.test.ts, test/generate-hermes-config.test.ts
Extends Hermes live-switch helpers for OpenAI-compatible endpoint handling and updates live switch, command-shape, and config-generation tests to match the managed frontend behavior.

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

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant runInferenceSetWithoutHostLock
  participant resolveAgentInferenceApi
  participant OpenShell
  participant Registry

  Operator->>runInferenceSetWithoutHostLock: set inference for Hermes compatible-anthropic-endpoint
  runInferenceSetWithoutHostLock->>runInferenceSetWithoutHostLock: reject explicit non-openai-completions requests
  runInferenceSetWithoutHostLock->>OpenShell: provider get / verify binding
  OpenShell-->>runInferenceSetWithoutHostLock: gateway metadata
  runInferenceSetWithoutHostLock->>resolveAgentInferenceApi: resolve preferredInferenceApi
  resolveAgentInferenceApi-->>runInferenceSetWithoutHostLock: openai-completions
  runInferenceSetWithoutHostLock->>Registry: persist updated preferredInferenceApi
Loading
sequenceDiagram
  participant sandbox.ts
  participant hasHermesCompatibleAnthropicInferenceRouteDrift
  participant decideSandboxResume
  participant Sandbox

  sandbox.ts->>hasHermesCompatibleAnthropicInferenceRouteDrift: compare registryEntry and requested route
  hasHermesCompatibleAnthropicInferenceRouteDrift-->>sandbox.ts: inferenceRouteConfigChanged
  sandbox.ts->>decideSandboxResume: signals include inferenceRouteConfigChanged
  decideSandboxResume-->>sandbox.ts: recreate sandbox
  Sandbox-->>sandbox.ts: resume uses recreated sandbox path
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#3354: Both PRs touch Hermes inference-set routing and provider configuration in src/lib/actions/inference-set.ts.
  • NVIDIA/NemoClaw#4471: Both PRs modify handleProviderInferenceState in src/lib/onboard/machine/handlers/provider-inference.ts.

Suggested labels: bug-fix, area: onboarding

Suggested reviewers: jyaunches, ericksoa

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code and docs implement the OpenAI-surface routing, /v1 preservation, and Hermes resume fixes requested in #6289 and #6298.
Out of Scope Changes check ✅ Passed The added docs, tests, and resume/metadata helpers all support the linked Hermes and inference-routing fixes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: Hermes custom Anthropic routes now use the OpenAI frontend.
✨ 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/6289-hermes-openai-frontend

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

@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

🧹 Nitpick comments (2)
src/lib/actions/inference-set.ts (1)

712-739: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant double resolveAgentInferenceApi application.

The fallback branch (explicitPreferredInferenceApi ?? resolveRuntimeInferenceApi(...)) is wrapped again in resolveAgentInferenceApi, but resolveRuntimeInferenceApi already applies the same resolver internally at its start. This is idempotent so no functional bug, just a redundant call.

🤖 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/actions/inference-set.ts` around lines 712 - 739, Remove the
redundant outer resolveAgentInferenceApi call in inference-set’s
preferredInferenceApi assignment: resolveRuntimeInferenceApi already normalizes
the fallback path internally, so keep resolveAgentInferenceApi only where needed
for the registry update and use the explicitPreferredInferenceApi ??
resolveRuntimeInferenceApi(...) result directly when computing
preferredInferenceApi.
src/lib/onboard/machine/handlers/sandbox-resume.test.ts (1)

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

Add direct guard-clause coverage for hasHermesCompatibleAnthropicInferenceRouteDrift.

Only the positive-drift path is exercised directly. Since this function gates a destructive sandbox recreate decision, consider adding cases for: non-Hermes agent, non-compatible-anthropic-endpoint provider, preferredInferenceApi already "openai-completions", and missing model — each should return false early.

As per path instructions, tests should provide "behavioral confidence rather than implementation lock-in" by covering observable outcomes at the public boundary.

🤖 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/machine/handlers/sandbox-resume.test.ts` around lines 58 -
77, Add direct behavioral test coverage for the guard clauses in
hasHermesCompatibleAnthropicInferenceRouteDrift: create cases for a non-hermes
agent, a provider other than compatible-anthropic-endpoint,
preferredInferenceApi already set to openai-completions, and a missing model,
and assert each returns false. Keep the tests at the public boundary by
exercising the function through observable inputs rather than internal
implementation details.

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/live/hermes-inference-switch-helpers.ts`:
- Around line 42-45: The helper in hermesRuntimeSwitchApi is duplicating
production API-mapping logic instead of reusing the real resolver, which can
drift from resolveAgentInferenceApi over time. Update this test helper to
delegate to or import resolveAgentInferenceApi from the inference config module,
and keep RUNTIME_SWITCH_API based on that shared source so both
hermes-inference-switch.test and hermes-inference-switch-command-shape.test
validate the same production behavior.

In `@test/e2e/support/hermes-inference-switch-command-shape.test.ts`:
- Around line 42-50: The new Hermes tests are verifying a duplicated helper
instead of the real command-shape behavior. Update the assertions in
hermes-inference-switch-command-shape.test.ts to exercise the production path by
calling resolveAgentInferenceApi directly, or the real command-argument builder
that consumes it, rather than hermesRuntimeSwitchApi from the test-only helper.
Keep the test focused on the actual boundary so it fails if the real resolver or
CLI shape regresses.

---

Nitpick comments:
In `@src/lib/actions/inference-set.ts`:
- Around line 712-739: Remove the redundant outer resolveAgentInferenceApi call
in inference-set’s preferredInferenceApi assignment: resolveRuntimeInferenceApi
already normalizes the fallback path internally, so keep
resolveAgentInferenceApi only where needed for the registry update and use the
explicitPreferredInferenceApi ?? resolveRuntimeInferenceApi(...) result directly
when computing preferredInferenceApi.

In `@src/lib/onboard/machine/handlers/sandbox-resume.test.ts`:
- Around line 58-77: Add direct behavioral test coverage for the guard clauses
in hasHermesCompatibleAnthropicInferenceRouteDrift: create cases for a
non-hermes agent, a provider other than compatible-anthropic-endpoint,
preferredInferenceApi already set to openai-completions, and a missing model,
and assert each returns false. Keep the tests at the public boundary by
exercising the function through observable inputs rather than internal
implementation details.
🪄 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: 9f357f4d-4a19-4201-9eca-e913f8a59127

📥 Commits

Reviewing files that changed from the base of the PR and between 748a788 and f5f8707.

📒 Files selected for processing (21)
  • docs/inference/inference-options.mdx
  • docs/inference/switch-inference-providers.mdx
  • src/lib/actions/inference-route-api.test.ts
  • src/lib/actions/inference-route-api.ts
  • src/lib/actions/inference-set-hermes-run.test.ts
  • src/lib/actions/inference-set.ts
  • src/lib/actions/sandbox/rebuild-resume-config.test.ts
  • src/lib/actions/sandbox/rebuild-resume-config.ts
  • src/lib/inference/config.test.ts
  • src/lib/inference/config.ts
  • src/lib/onboard/machine/handlers/provider-inference.test.ts
  • src/lib/onboard/machine/handlers/provider-inference.ts
  • src/lib/onboard/machine/handlers/sandbox-resume.test.ts
  • src/lib/onboard/machine/handlers/sandbox-resume.ts
  • src/lib/onboard/machine/handlers/sandbox.test.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/providers.test.ts
  • test/e2e/live/hermes-inference-switch-helpers.ts
  • test/e2e/live/hermes-inference-switch.test.ts
  • test/e2e/support/hermes-inference-switch-command-shape.test.ts
  • test/generate-hermes-config.test.ts

Comment thread test/e2e/live/hermes-inference-switch-helpers.ts Outdated
Comment thread test/e2e/support/hermes-inference-switch-command-shape.test.ts
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@github-code-quality

github-code-quality Bot commented Jul 6, 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 b200b5a +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/li...bprocess-env.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/bl...print/runner.ts 95%
nemoclaw/src/co...ration-state.ts 94%
nemoclaw/src/bl...ate-networks.ts 94%
nemoclaw/src/index.ts 94%

TypeScript / code-coverage/cli

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

Show a code coverage summary of the most covered files.
File b200b5a +/-
src/lib/shields...nsition-lock.ts 87%
src/lib/onboard/preflight.ts 83%
src/lib/actions...all/run-plan.ts 81%
src/lib/state/o...oard-session.ts 81%
src/lib/state/sandbox.ts 71%
src/lib/onboard...er-gpu-patch.ts 69%
src/lib/shields/index.ts 68%
src/lib/policy/index.ts 66%
src/lib/actions...licy-channel.ts 63%
src/lib/onboard.ts 24%

Updated July 06, 2026 18:45 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: onboard-resume, onboard-repair, cloud-onboard, hermes-inference-switch, openclaw-inference-switch, inference-routing, rebuild-hermes
Optional E2E: rebuild-hermes-stale-base, cloud-inference, model-router-provider-routed-inference-e2e

Dispatch hint: onboard-resume,onboard-repair,cloud-onboard,hermes-inference-switch,openclaw-inference-switch,inference-routing,rebuild-hermes

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • onboard-resume (medium): Mandatory under the onboarding resume rule: live onboarding machine handlers, resume provider shim wiring, and src/lib/onboard.ts core flow orchestration changed.
  • onboard-repair (medium): Mandatory under the onboarding resume rule: repair-sensitive provider and sandbox resume state paths changed and must be validated beyond unit/runtime-boundary tests.
  • cloud-onboard (high): Provider setup and onboarding flow changes can affect full hosted onboarding, including provider inference selection and gateway registration.
  • hermes-inference-switch (high): Directly covers the changed Hermes inference set path, including compatible Anthropic endpoint switching, managed OpenAI frontend selection, route/config sync, and live Hermes runtime health/chat checks.
  • openclaw-inference-switch (high): Shared inference route API and sandbox inference config changes also affect OpenClaw custom Anthropic/OpenAI route preservation and inference set behavior.
  • inference-routing (medium): The PR changes inference routing decisions, gateway provider metadata validation, provider protocol type assumptions, and credential/config binding checks.
  • rebuild-hermes (high): Rebuild resume configuration and Hermes stale-route migration behavior changed; the Hermes rebuild lifecycle should be validated end to end.

Optional E2E

  • rebuild-hermes-stale-base (high): Adjacent confidence for Hermes rebuild behavior on stale bases; useful because this PR changes rebuild handoff metadata but not strictly required if rebuild-hermes passes.
  • cloud-inference (medium): Additional live hosted inference confidence through the installed sandbox inference.local path after routing/config changes.
  • model-router-provider-routed-inference-e2e (medium): Adjacent routed-provider coverage for inference.local provider routing and gateway behavior.

New E2E recommendations

  • Hermes compatible Anthropic legacy migration (high): Existing Hermes inference-switch coverage validates a fresh compatible-anthropic provider registered on the OpenAI surface, but this PR also adds pre-mutation rejection/repair behavior for legacy providers registered as type=anthropic. A live regression should seed or simulate a stale Hermes compatible-anthropic registration, verify inference set refuses mutation with the rebuild guidance, then run rebuild/resume and assert the provider is repaired to type=openai with OPENAI_BASE_URL and COMPATIBLE_ANTHROPIC_API_KEY.
    • Suggested test: test/e2e/live/hermes-compatible-anthropic-legacy-repair.test.ts

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: onboard-resume,onboard-repair,cloud-onboard,hermes-inference-switch,openclaw-inference-switch,inference-routing,rebuild-hermes

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: hermes-inference-switch, onboard-resume, onboard-repair
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-inference-switch
  • 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-inference-switch: Focused free-standing E2E job wired for changed live test test/e2e/live/hermes-inference-switch.test.ts.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-inference-switch
  • onboard-resume: Changes touch src/lib/onboard/machine live slice handlers, resume-provider shim wiring, provider inference state, sandbox resume handling, and rebuild resume config. Per the onboarding resume rule, state-machine resume paths must run the onboard-resume live E2E job.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • onboard-repair: The same onboarding state-machine and rebuild-resume changes can affect repair/backstop execution from persisted sessions, including stale route metadata repair. Per the onboarding resume rule, onboard-repair is required and not optional for these paths.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair

Optional E2E targets

  • None.

Relevant changed files

  • src/lib/actions/inference-route-api.ts
  • src/lib/actions/inference-set.ts
  • src/lib/actions/sandbox/rebuild-resume-config.ts
  • src/lib/inference/config.ts
  • src/lib/onboard.ts
  • src/lib/onboard/gateway-provider-metadata.ts
  • src/lib/onboard/inference-providers/remote.ts
  • src/lib/onboard/machine/handlers/provider-inference.ts
  • src/lib/onboard/machine/handlers/sandbox-resume.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/resume-provider-shim.ts
  • test/e2e/live/hermes-inference-switch-helpers.ts
  • test/e2e/live/hermes-inference-switch.test.ts
  • test/e2e/support/hermes-inference-switch-command-shape.test.ts

@github-actions

github-actions Bot commented Jul 6, 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 · 6 test follow-ups
Since last review: 6 prior items resolved · 1 still applies · 0 new items found

Action checklist

  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Acceptance clause
  • PRA-T3 Add or justify test follow-up: Acceptance clause
  • PRA-T4 Add or justify test follow-up: Acceptance clause
  • PRA-T5 Add or justify test follow-up: Acceptance clause
  • PRA-T6 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 — Fresh Hermes custom Anthropic onboarding against an endpoint serving both `/v1/messages` and `/v1/chat/completions` registers `compatible-anthropic-endpoint` as `type=openai` with `OPENAI_BASE_URL` and `COMPATIBLE_ANTHROPIC_API_KEY`, writes `https://inference.local/v1\` with no Hermes `api_mode`, and `hermes -z` exits 0 over the OpenAI frontend.. Static and E2E-support coverage is broad and behavior-specific, including provider binding, fail-before-mutation, rebuild/resume repair, config sync, and live switch/runtime probes. Because the changed code crosses OpenShell provider registration, sandbox lifecycle, registry/session metadata, and Hermes runtime behavior, one full fresh-onboarding runtime path would still provide the highest confidence.
  • PRA-T2 Acceptance clause — **Regression:** Unknown — earlier versions not tested on this route. — add test evidence or identify existing coverage. The diff does not establish historical version behavior; it adds forward regression coverage for the changed routing path.
  • PRA-T3 Acceptance clause — 1. Onboard a NemoHermes sandbox on the Custom Anthropic-compatible provider (the Inference Hub endpoint, model `nvidia/nvidia/nemotron-3-super-v3`). — add test evidence or identify existing coverage. Unit/integration tests cover fresh Hermes custom Anthropic provider selection and setup with `preferredInferenceApi: openai-completions`. The changed live E2E covers switching an installed Hermes sandbox onto a compatible Anthropic provider, not a full fresh custom-Anthropic initial onboard as the first provider.
  • PRA-T4 Acceptance clause — 3. (Evidence) From inside the sandbox, curl the managed proxy with `stream:true` and count `message_start` events. — add test evidence or identify existing coverage. The PR adds in-sandbox curl coverage for the selected OpenAI frontend, but does not add a direct Anthropic SSE `message_start` counter. This is consistent with the chosen mitigation because Hermes custom Anthropic routes no longer use the managed Anthropic SSE frontend.
  • PRA-T5 Acceptance clause — `hermes -z` produces a final response and exits 0; the SSE stream contains exactly one `message_start` event followed by content and one `message_stop`. — add test evidence or identify existing coverage. `hermes -z` final response/exit 0 is covered by the live E2E. The exact Anthropic SSE event-count assertion is intentionally bypassed by routing this Hermes provider through OpenAI Chat Completions.
  • PRA-T6 Acceptance clause — let me take a look — add test evidence or identify existing coverage. Issue comment contains no testable acceptance requirement.

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 6, 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: Monolith growth: provider-inference.test.ts grew 121 lines (999→1120) — hotspot exceeds threshold; then add or justify PRA-T1.
Open items: 7 required · 9 warnings · 2 suggestions · 8 test follow-ups
Since last review: 0 prior items resolved · 15 still apply · 1 new item found

Action checklist

  • PRA-4 Fix: Monolith growth: provider-inference.test.ts grew 121 lines (999→1120) — hotspot exceeds threshold in src/lib/onboard/machine/handlers/provider-inference.test.ts:1
  • PRA-5 Fix: Monolith growth: inference-set.ts grew 81 lines (842→923) — hotspot exceeds threshold in src/lib/actions/inference-set.ts:1
  • PRA-6 Fix: Monolith growth: sandbox.test.ts grew 53 lines (808→861) — hotspot exceeds threshold in src/lib/onboard/machine/handlers/sandbox.test.ts:1
  • PRA-7 Fix: Monolith growth: rebuild-resume-config.test.ts grew 47 lines (604→651) — hotspot exceeds threshold in src/lib/actions/sandbox/rebuild-resume-config.test.ts:1
  • PRA-8 Fix: Monolith growth: providers.test.ts grew 30 lines (701→731) — hotspot exceeds threshold in src/lib/onboard/providers.test.ts:1
  • PRA-9 Fix: Monolith growth: provider-inference.ts grew 27 lines (629→656) — hotspot exceeds threshold in src/lib/onboard/machine/handlers/provider-inference.ts:1
  • PRA-10 Fix: Monolith growth: config.test.ts grew 21 lines (534→555) — hotspot exceeds threshold in src/lib/inference/config.test.ts:1
  • PRA-1 Resolve or justify: Source-of-truth review needed: remote.ts:210 (replaceStaleAnthropicProviderForOpenAiSurface)
  • PRA-2 Resolve or justify: Source-of-truth review needed: provider-inference.ts:150 (healAdjustedInferenceApi failure path)
  • PRA-3 Resolve or justify: Source-of-truth review needed: config.ts:53 (resolveAgentInferenceApi) + config.ts:205 (coerceAgentInferenceApi)
  • PRA-11 Resolve or justify: E2E helper file grew 100 lines — review for unnecessary framework abstraction in test/e2e/live/hermes-inference-switch-helpers.ts:1
  • PRA-12 Resolve or justify: Missing test for concurrent replaceStaleAnthropicProviderForOpenAiSurface race condition in src/lib/onboard/inference-providers/remote.ts:185
  • PRA-13 Resolve or justify: Missing test: failed provider inference heal leaves stale preferredInferenceApi armed for next resume in src/lib/onboard/machine/handlers/provider-inference.ts:150
  • PRA-14 Resolve or justify: Missing defensive test: agent with both provider_type=custom AND openai_compatible in src/lib/inference/config.test.ts:50
  • PRA-15 Resolve or justify: Missing E2E test: rebuild migration of legacy Hermes custom Anthropic sandbox in test/e2e/live/hermes-inference-switch.test.ts:1
  • PRA-16 Resolve or justify: Missing test: HTTPS on host.openshell.internal should be rejected in src/lib/actions/inference-set.ts:410
  • 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: E2E helper file grew 100 lines — review for unnecessary framework abstraction
  • PRA-T7 Add or justify test follow-up: Missing defensive test: agent with both provider_type=custom AND openai_compatible
  • PRA-T8 Add or justify test follow-up: remote.ts:210 (replaceStaleAnthropicProviderForOpenAiSurface)
  • PRA-17 In-scope improvement: Duplicate Bedrock behavior note in two doc files — centralize in docs/inference/inference-options.mdx:358
  • PRA-18 In-scope improvement: Improve error message clarity for failed OpenAI surface probe in src/lib/onboard/inference-providers/remote.ts:220

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/machine/handlers/provider-inference.test.ts:1 Extract new #6289 test cases into separate file (e.g., provider-inference-hermes-anthropic.test.ts) or refactor suite to reduce file size below 20-line growth threshold.
PRA-5 Required architecture src/lib/actions/inference-set.ts:1 Extract Hermes-specific assertion into separate module (e.g., inference-set-hermes-validate.ts) and import it.
PRA-6 Required architecture src/lib/onboard/machine/handlers/sandbox.test.ts:1 Extract new tests or refactor to offset growth. Identify which tests were added in this PR and move to appropriate feature test file.
PRA-7 Required architecture src/lib/actions/sandbox/rebuild-resume-config.test.ts:1 Extract #6289 rebuild tests into separate file (e.g., rebuild-resume-config-hermes-anthropic.test.ts).
PRA-8 Required architecture src/lib/onboard/providers.test.ts:1 Extract or offset growth. Identify which tests were added in this PR and move to appropriate feature test file.
PRA-9 Required architecture src/lib/onboard/machine/handlers/provider-inference.ts:1 Consider extracting resume provider surface readiness check into separate module (e.g., onboard/resume-provider-surface.ts).
PRA-10 Required architecture src/lib/inference/config.test.ts:1 Extract new describe block into separate test file (e.g., inference-config-agent-api.test.ts) or accept as minor growth for new pure function.
PRA-11 Resolve/justify tests test/e2e/live/hermes-inference-switch-helpers.ts:1 Review helper diff — if new abstractions exist (registries, matrix abstractions, generalized fixture APIs, workflow validators), justify or remove. Keep only direct test support.
PRA-12 Resolve/justify correctness src/lib/onboard/inference-providers/remote.ts:185 Add unit test for concurrent replaceStaleAnthropicProviderForOpenAiSurface calls; verify idempotency or add locking.
PRA-13 Resolve/justify correctness src/lib/onboard/machine/handlers/provider-inference.ts:150 Add test: provider inference setup fails after healAdjustedInferenceApi=true; verify session still has stale preferredInferenceApi and error surfaces clearly.
PRA-14 Resolve/justify tests src/lib/inference/config.test.ts:50 Add test: agent { inference: { provider_type: 'custom' } } with openai_compatible also set — verify deterministic fallback (which function wins).
PRA-15 Resolve/justify acceptance test/e2e/live/hermes-inference-switch.test.ts:1 Add E2E test: create Hermes sandbox with legacy Anthropic registration, run rebuild, verify OpenAI frontend registration and successful inference (hermes -z works).
PRA-16 Resolve/justify security src/lib/actions/inference-set.ts:410 Add test: normalizeCustomEndpointUrl rejects 'https://host.openshell.internal:8000/v1' with InferenceSetError.
PRA-17 Improvement docs docs/inference/inference-options.mdx:358 Centralize Bedrock behavior note in one location (e.g., inference-options.mdx) and reference from switch-inference-providers.mdx, or keep both but ensure single source of truth via shared include.
PRA-18 Improvement correctness src/lib/onboard/inference-providers/remote.ts:220 Change to: 'or onboard an agent that natively supports the Anthropic Messages API (e.g., OpenClaw via `nemoclaw onboard`).'

🚨 Required before merge

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

PRA-4 Required — Monolith growth: provider-inference.test.ts grew 121 lines (999→1120) — hotspot exceeds threshold

  • Location: src/lib/onboard/machine/handlers/provider-inference.test.ts:1
  • Category: architecture
  • Problem: Three new [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 test cases added to already-large test file (baseLines 999). Per rubric, must extract or offset growth before merge.
  • Impact: Large test files reduce maintainability, slow CI, and concentrate risk. Growth on a hotspot file compounds existing technical debt.
  • Required action: Extract new [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 test cases into separate file (e.g., provider-inference-hermes-anthropic.test.ts) or refactor suite to reduce file size below 20-line growth threshold.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run `git diff --stat src/lib/onboard/machine/handlers/provider-inference.test.ts` to confirm line count; after extraction, verify file shrinks by ≥100 lines.
  • Missing regression test: N/A — architecture finding; existing tests must pass after extraction.
  • Done when: The required change is committed and verification passes: Run `git diff --stat src/lib/onboard/machine/handlers/provider-inference.test.ts` to confirm line count; after extraction, verify file shrinks by ≥100 lines.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 999, headLines: 1120, delta: 121, severity: blocker

PRA-5 Required — Monolith growth: inference-set.ts grew 81 lines (842→923) — hotspot exceeds threshold

  • Location: src/lib/actions/inference-set.ts:1
  • Category: architecture
  • Problem: Added assertHermesCompatibleAnthropicOpenAiProvider and explicit inference API validation for Hermes to already large source file (baseLines 842). This is a critical inference mutation path.
  • Impact: Large source files reduce readability, increase coupling, and make security auditing harder.
  • Required action: Extract Hermes-specific assertion into separate module (e.g., inference-set-hermes-validate.ts) and import it.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run `git diff --stat src/lib/actions/inference-set.ts`; after extraction, verify file shrinks by ≥60 lines and new module is <50 lines.
  • Missing regression test: N/A — architecture finding; existing tests must pass after extraction.
  • Done when: The required change is committed and verification passes: Run `git diff --stat src/lib/actions/inference-set.ts`; after extraction, verify file shrinks by ≥60 lines and new module is <50 lines.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 842, headLines: 923, delta: 81, severity: blocker

PRA-6 Required — Monolith growth: sandbox.test.ts grew 53 lines (808→861) — hotspot exceeds threshold

  • Location: src/lib/onboard/machine/handlers/sandbox.test.ts:1
  • Category: architecture
  • Problem: Test file growth on hotspot (baseLines 808). Need to extract or offset.
  • Impact: Compounds existing test file bloat; reduces test maintainability.
  • Required action: Extract new tests or refactor to offset growth. Identify which tests were added in this PR and move to appropriate feature test file.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/onboard/machine/handlers/sandbox.test.ts` for added test blocks; extract them.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/onboard/machine/handlers/sandbox.test.ts` for added test blocks; extract them.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 808, headLines: 861, delta: 53, severity: blocker

PRA-7 Required — Monolith growth: rebuild-resume-config.test.ts grew 47 lines (604→651) — hotspot exceeds threshold

PRA-8 Required — Monolith growth: providers.test.ts grew 30 lines (701→731) — hotspot exceeds threshold

  • Location: src/lib/onboard/providers.test.ts:1
  • Category: architecture
  • Problem: Test file growth on hotspot (baseLines 701). Need to extract or offset.
  • Impact: Compounds existing test file bloat; reduces test maintainability.
  • Required action: Extract or offset growth. Identify which tests were added in this PR and move to appropriate feature test file.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/onboard/providers.test.ts` for added test blocks; extract them.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/onboard/providers.test.ts` for added test blocks; extract them.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 701, headLines: 731, delta: 30, severity: blocker

PRA-9 Required — Monolith growth: provider-inference.ts grew 27 lines (629→656) — hotspot exceeds threshold

  • Location: src/lib/onboard/machine/handlers/provider-inference.ts:1
  • Category: architecture
  • Problem: Source file growth on hotspot (baseLines 629). Added isResumeProviderSurfaceReady dep and Hermes OpenAI frontend logic.
  • Impact: Large source files reduce readability and increase coupling in core onboarding flow.
  • Required action: Consider extracting resume provider surface readiness check into separate module (e.g., onboard/resume-provider-surface.ts).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/onboard/machine/handlers/provider-inference.ts` for added logic; extract if cohesive.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/onboard/machine/handlers/provider-inference.ts` for added logic; extract if cohesive.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 629, headLines: 656, delta: 27, severity: blocker

PRA-10 Required — Monolith growth: config.test.ts grew 21 lines (534→555) — hotspot exceeds threshold

  • Location: src/lib/inference/config.test.ts:1
  • Category: architecture
  • Problem: Added resolveAgentInferenceApi describe block (3 tests) to hotspot file (baseLines 534).
  • Impact: Test file growth on inference config hotspot.
  • Required action: Extract new describe block into separate test file (e.g., inference-config-agent-api.test.ts) or accept as minor growth for new pure function.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/inference/config.test.ts` for added describe block; extract it.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/inference/config.test.ts` for added describe block; extract it.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 534, headLines: 555, delta: 21, severity: blocker
Review findings by urgency: 7 required fixes, 9 items to resolve/justify, 2 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: remote.ts:210 (replaceStaleAnthropicProviderForOpenAiSurface)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: MISSING — no test for concurrent replacement race (PRA-9)
  • 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: Function deletes provider then upserts as openai; concurrent calls could race

PRA-2 Resolve/justify — Source-of-truth review needed: provider-inference.ts:150 (healAdjustedInferenceApi failure path)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: MISSING — no test for failed heal leaving stale api (PRA-10)
  • 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: isResumeProviderSurfaceReady triggers heal; setupInference failure not tested negatively

PRA-3 Resolve/justify — Source-of-truth review needed: config.ts:53 (resolveAgentInferenceApi) + config.ts:205 (coerceAgentInferenceApi)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: MISSING — no test for dual provider_type (PRA-11)
  • 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: resolveAgentInferenceApi checks agentName===hermes first; coerceAgentInferenceApi checks provider_type===openai_compatible. Interaction untested.

PRA-11 Resolve/justify — E2E helper file grew 100 lines — review for unnecessary framework abstraction

PRA-12 Resolve/justify — Missing test for concurrent replaceStaleAnthropicProviderForOpenAiSurface race condition

  • Location: src/lib/onboard/inference-providers/remote.ts:185
  • Category: correctness
  • Problem: The replaceStaleAnthropicProviderForOpenAiSurface function deletes and re-registers a gateway provider. Concurrent calls could leave the provider in an inconsistent state (deleted but not re-created, or double-created).
  • Impact: Race condition could cause onboarding/rebuild to fail with confusing errors or leave gateway in broken state requiring manual cleanup.
  • Recommended action: Add unit test for concurrent replaceStaleAnthropicProviderForOpenAiSurface calls; verify idempotency or add locking.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Search for existing tests of replaceStaleAnthropicProviderForOpenAiSurface in remote.test.ts or provider-inference.test.ts; none exist for concurrency.
  • Missing regression test: Add test: concurrent calls to replaceStaleAnthropicProviderForOpenAiSurface for same provider — verify exactly one succeeds and provider ends up as type=openai with correct bindings.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Search for existing tests of replaceStaleAnthropicProviderForOpenAiSurface in remote.test.ts or provider-inference.test.ts; none exist for concurrency.
  • Evidence: remote.ts:185-250 implements replacement logic with delete+upsert; no locking or idempotency key. Prior advisor PRA-9.

PRA-13 Resolve/justify — Missing test: failed provider inference heal leaves stale preferredInferenceApi armed for next resume

  • Location: src/lib/onboard/machine/handlers/provider-inference.ts:150
  • Category: correctness
  • Problem: When healAdjustedInferenceApi=true but provider setup fails, the session may retain stale preferredInferenceApi that gets re-used on next resume, causing repeated failures.
  • Impact: Silent degradation — user sees repeated failures without clear indication that registry metadata is stale.
  • Recommended action: Add test: provider inference setup fails after healAdjustedInferenceApi=true; verify session still has stale preferredInferenceApi and error surfaces clearly.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check provider-inference.test.ts for tests covering failed setupInference after surface-ready check triggers heal; none found.
  • Missing regression test: Add test: resume flow with healAdjustedInferenceApi=true where setupInference fails — verify session.preferredInferenceApi remains stale value and error message guides user to rebuild.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check provider-inference.test.ts for tests covering failed setupInference after surface-ready check triggers heal; none found.
  • Evidence: provider-inference.ts uses isResumeProviderSurfaceReady to detect stale gateway; if false, calls setupInference with openai-completions. Failure path not tested negatively. Prior advisor PRA-10.

PRA-14 Resolve/justify — Missing defensive test: agent with both provider_type=custom AND openai_compatible

  • Location: src/lib/inference/config.test.ts:50
  • Category: tests
  • Problem: coerceAgentInferenceApi handles openai_compatible agents; resolveAgentInferenceApi handles Hermes (custom). An agent declaring both provider_types creates ambiguous routing priority.
  • Impact: Undefined behavior — could route to wrong frontend (Anthropic vs OpenAI) causing inference failures.
  • Recommended action: Add test: agent { inference: { provider_type: 'custom' } } with openai_compatible also set — verify deterministic fallback (which function wins).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check config.test.ts describe coerceAgentInferenceApi and resolveAgentInferenceApi — no test covers dual provider_type.
  • Missing regression test: Add test: agent.inference.provider_type = ['custom', 'openai_compatible'] (or object with both keys) — verify resolveAgentInferenceApi takes precedence for Hermes, coerceAgentInferenceApi for OpenClaw, and behavior is documented.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check config.test.ts describe coerceAgentInferenceApi and resolveAgentInferenceApi — no test covers dual provider_type.
  • Evidence: config.ts: resolveAgentInferenceApi checks agentName===hermes first; coerceAgentInferenceApi checks provider_type===openai_compatible. Interaction untested. Prior advisor PRA-11.

PRA-15 Resolve/justify — Missing E2E test: rebuild migration of legacy Hermes custom Anthropic sandbox

  • Location: test/e2e/live/hermes-inference-switch.test.ts:1
  • Category: acceptance
  • Problem: Issue [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 requires that legacy Hermes sandboxes with type=anthropic provider can be migrated via rebuild. No E2E test covers this end-to-end path.
  • Impact: Migration path unverified in real environment; users may hit undocumented failures during rebuild.
  • Recommended action: Add E2E test: create Hermes sandbox with legacy Anthropic registration, run rebuild, verify OpenAI frontend registration and successful inference (hermes -z works).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check test/e2e/live/hermes-inference-switch.test.ts for rebuild migration test; none exists for legacy Anthropic → OpenAI migration.
  • Missing regression test: Add E2E test: onboard Hermes with compatible-anthropic-endpoint (simulate legacy type=anthropic), run nemoclaw <sandbox> rebuild, verify gateway provider type=openai, verify hermes -z produces final response.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check test/e2e/live/hermes-inference-switch.test.ts for rebuild migration test; none exists for legacy Anthropic → OpenAI migration.
  • Evidence: Issue [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 acceptance requires rebuild migration; docs mention it (switch-inference-providers.mdx:121) but no E2E test. Prior advisor PRA-12.

PRA-16 Resolve/justify — Missing test: HTTPS on host.openshell.internal should be rejected

  • Location: src/lib/actions/inference-set.ts:410
  • Category: security
  • Problem: normalizeCustomEndpointUrl allows only HTTP for host.openshell.internal (ALLOWED_PRIVATE_CUSTOM_ENDPOINT_HOSTS). HTTPS should be rejected to prevent TLS bypass of sandbox network policy, but no test verifies this.
  • Impact: Trust boundary gap — if HTTPS were accidentally allowed, it could enable SSRF or credential leakage via spoofed internal endpoints.
  • Recommended action: Add test: normalizeCustomEndpointUrl rejects 'https://host.openshell.internal:8000/v1' with InferenceSetError.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run normalizeCustomEndpointUrl('https://host.openshell.internal:8000/v1', mockRewrite) and expect InferenceSetError; no such test exists in inference-set.test.ts or config.test.ts.
  • Missing regression test: Add test in inference-set.test.ts or config.test.ts: normalizeCustomEndpointUrl with https://host.openshell.internal throws 'endpoint-url is not allowed'.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run normalizeCustomEndpointUrl('https://host.openshell.internal:8000/v1', mockRewrite) and expect InferenceSetError; no such test exists in inference-set.test.ts or config.test.ts.
  • Evidence: inference-set.ts:410 enforces protocol === 'http:' for host.openshell.internal; security review Category 2 PASS but test missing. Prior advisor PRA-13.

💡 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-17 Improvement — Duplicate Bedrock behavior note in two doc files — centralize

  • Location: docs/inference/inference-options.mdx:358
  • Category: docs
  • Problem: Both inference-options.mdx:358 and switch-inference-providers.mdx:119 contain 'AWS Bedrock routes retain their existing OpenAI-compatible adapter behavior.'
  • Impact: Documentation drift risk — if behavior changes, one location may be updated but not the other.
  • Suggested action: Centralize Bedrock behavior note in one location (e.g., inference-options.mdx) and reference from switch-inference-providers.mdx, or keep both but ensure single source of truth via shared include.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Search both files for 'AWS Bedrock routes retain' — appears twice with identical wording.
  • Missing regression test: N/A — doc finding; add doc-validate rule or manual check in release process.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: diff shows both files added same sentence. Prior advisor PRA-14.

PRA-18 Improvement — Improve error message clarity for failed OpenAI surface probe

  • Location: src/lib/onboard/inference-providers/remote.ts:220
  • Category: correctness
  • Problem: Error message says 'or onboard an agent that uses the native Anthropic Messages route (for example, OpenClaw).' but should explicitly mention `nemoclaw onboard` command.
  • Impact: User confusion — error suggests OpenClaw as alternative but doesn't give actionable command.
  • Suggested action: Change to: 'or onboard an agent that natively supports the Anthropic Messages API (e.g., OpenClaw via `nemoclaw onboard`).'
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check remote.ts:220 error message string; verify it matches suggested wording.
  • Missing regression test: N/A — UX improvement; no regression test needed.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: remote.ts:220 current message: 'or onboard an agent that uses the native Anthropic Messages route (for example, OpenClaw).' Prior advisor PRA-15.
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 — Hermes custom Anthropic fresh onboard → verify gateway provider type=openai, route works end-to-end. Runtime/sandbox/infrastructure paths need behavioral runtime validation: inference-set.ts, remote.ts, rebuild-resume-config.ts, config.ts, onboard.ts, gateway-provider-metadata.ts all touch sandbox/gateway mutation paths. Unit/integration coverage is strong for new logic but E2E gaps remain for legacy migration and concurrent operations.
  • PRA-T2 Runtime validation — Hermes legacy Anthropic sandbox rebuild → verify OpenAI frontend registration, hermes -z succeeds. Runtime/sandbox/infrastructure paths need behavioral runtime validation: inference-set.ts, remote.ts, rebuild-resume-config.ts, config.ts, onboard.ts, gateway-provider-metadata.ts all touch sandbox/gateway mutation paths. Unit/integration coverage is strong for new logic but E2E gaps remain for legacy migration and concurrent operations.
  • PRA-T3 Runtime validation — Concurrent inference set on same Hermes sandbox → no registry corruption. Runtime/sandbox/infrastructure paths need behavioral runtime validation: inference-set.ts, remote.ts, rebuild-resume-config.ts, config.ts, onboard.ts, gateway-provider-metadata.ts all touch sandbox/gateway mutation paths. Unit/integration coverage is strong for new logic but E2E gaps remain for legacy migration and concurrent operations.
  • PRA-T4 Runtime validation — HTTPS host.openshell.internal rejected at normalizeCustomEndpointUrl. Runtime/sandbox/infrastructure paths need behavioral runtime validation: inference-set.ts, remote.ts, rebuild-resume-config.ts, config.ts, onboard.ts, gateway-provider-metadata.ts all touch sandbox/gateway mutation paths. Unit/integration coverage is strong for new logic but E2E gaps remain for legacy migration and concurrent operations.
  • PRA-T5 Runtime validation — Concurrent replaceStaleAnthropicProviderForOpenAiSurface calls → verify idempotency. Runtime/sandbox/infrastructure paths need behavioral runtime validation: inference-set.ts, remote.ts, rebuild-resume-config.ts, config.ts, onboard.ts, gateway-provider-metadata.ts all touch sandbox/gateway mutation paths. Unit/integration coverage is strong for new logic but E2E gaps remain for legacy migration and concurrent operations.
  • PRA-T6 E2E helper file grew 100 lines — review for unnecessary framework abstraction — Review helper diff — if new abstractions exist (registries, matrix abstractions, generalized fixture APIs, workflow validators), justify or remove. Keep only direct test support.
  • PRA-T7 Missing defensive test: agent with both provider_type=custom AND openai_compatible — Add test: agent { inference: { provider_type: 'custom' } } with openai_compatible also set — verify deterministic fallback (which function wins).
  • PRA-T8 remote.ts:210 (replaceStaleAnthropicProviderForOpenAiSurface) — MISSING — no test for concurrent replacement race (PRA-9). Function deletes provider then upserts as openai; concurrent calls could race
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: remote.ts:210 (replaceStaleAnthropicProviderForOpenAiSurface)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: MISSING — no test for concurrent replacement race (PRA-9)
  • 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: Function deletes provider then upserts as openai; concurrent calls could race

PRA-2 Resolve/justify — Source-of-truth review needed: provider-inference.ts:150 (healAdjustedInferenceApi failure path)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: MISSING — no test for failed heal leaving stale api (PRA-10)
  • 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: isResumeProviderSurfaceReady triggers heal; setupInference failure not tested negatively

PRA-3 Resolve/justify — Source-of-truth review needed: config.ts:53 (resolveAgentInferenceApi) + config.ts:205 (coerceAgentInferenceApi)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: MISSING — no test for dual provider_type (PRA-11)
  • 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: resolveAgentInferenceApi checks agentName===hermes first; coerceAgentInferenceApi checks provider_type===openai_compatible. Interaction untested.

PRA-4 Required — Monolith growth: provider-inference.test.ts grew 121 lines (999→1120) — hotspot exceeds threshold

  • Location: src/lib/onboard/machine/handlers/provider-inference.test.ts:1
  • Category: architecture
  • Problem: Three new [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 test cases added to already-large test file (baseLines 999). Per rubric, must extract or offset growth before merge.
  • Impact: Large test files reduce maintainability, slow CI, and concentrate risk. Growth on a hotspot file compounds existing technical debt.
  • Required action: Extract new [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 test cases into separate file (e.g., provider-inference-hermes-anthropic.test.ts) or refactor suite to reduce file size below 20-line growth threshold.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run `git diff --stat src/lib/onboard/machine/handlers/provider-inference.test.ts` to confirm line count; after extraction, verify file shrinks by ≥100 lines.
  • Missing regression test: N/A — architecture finding; existing tests must pass after extraction.
  • Done when: The required change is committed and verification passes: Run `git diff --stat src/lib/onboard/machine/handlers/provider-inference.test.ts` to confirm line count; after extraction, verify file shrinks by ≥100 lines.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 999, headLines: 1120, delta: 121, severity: blocker

PRA-5 Required — Monolith growth: inference-set.ts grew 81 lines (842→923) — hotspot exceeds threshold

  • Location: src/lib/actions/inference-set.ts:1
  • Category: architecture
  • Problem: Added assertHermesCompatibleAnthropicOpenAiProvider and explicit inference API validation for Hermes to already large source file (baseLines 842). This is a critical inference mutation path.
  • Impact: Large source files reduce readability, increase coupling, and make security auditing harder.
  • Required action: Extract Hermes-specific assertion into separate module (e.g., inference-set-hermes-validate.ts) and import it.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run `git diff --stat src/lib/actions/inference-set.ts`; after extraction, verify file shrinks by ≥60 lines and new module is <50 lines.
  • Missing regression test: N/A — architecture finding; existing tests must pass after extraction.
  • Done when: The required change is committed and verification passes: Run `git diff --stat src/lib/actions/inference-set.ts`; after extraction, verify file shrinks by ≥60 lines and new module is <50 lines.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 842, headLines: 923, delta: 81, severity: blocker

PRA-6 Required — Monolith growth: sandbox.test.ts grew 53 lines (808→861) — hotspot exceeds threshold

  • Location: src/lib/onboard/machine/handlers/sandbox.test.ts:1
  • Category: architecture
  • Problem: Test file growth on hotspot (baseLines 808). Need to extract or offset.
  • Impact: Compounds existing test file bloat; reduces test maintainability.
  • Required action: Extract new tests or refactor to offset growth. Identify which tests were added in this PR and move to appropriate feature test file.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/onboard/machine/handlers/sandbox.test.ts` for added test blocks; extract them.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/onboard/machine/handlers/sandbox.test.ts` for added test blocks; extract them.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 808, headLines: 861, delta: 53, severity: blocker

PRA-7 Required — Monolith growth: rebuild-resume-config.test.ts grew 47 lines (604→651) — hotspot exceeds threshold

PRA-8 Required — Monolith growth: providers.test.ts grew 30 lines (701→731) — hotspot exceeds threshold

  • Location: src/lib/onboard/providers.test.ts:1
  • Category: architecture
  • Problem: Test file growth on hotspot (baseLines 701). Need to extract or offset.
  • Impact: Compounds existing test file bloat; reduces test maintainability.
  • Required action: Extract or offset growth. Identify which tests were added in this PR and move to appropriate feature test file.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/onboard/providers.test.ts` for added test blocks; extract them.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/onboard/providers.test.ts` for added test blocks; extract them.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 701, headLines: 731, delta: 30, severity: blocker

PRA-9 Required — Monolith growth: provider-inference.ts grew 27 lines (629→656) — hotspot exceeds threshold

  • Location: src/lib/onboard/machine/handlers/provider-inference.ts:1
  • Category: architecture
  • Problem: Source file growth on hotspot (baseLines 629). Added isResumeProviderSurfaceReady dep and Hermes OpenAI frontend logic.
  • Impact: Large source files reduce readability and increase coupling in core onboarding flow.
  • Required action: Consider extracting resume provider surface readiness check into separate module (e.g., onboard/resume-provider-surface.ts).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/onboard/machine/handlers/provider-inference.ts` for added logic; extract if cohesive.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/onboard/machine/handlers/provider-inference.ts` for added logic; extract if cohesive.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 629, headLines: 656, delta: 27, severity: blocker

PRA-10 Required — Monolith growth: config.test.ts grew 21 lines (534→555) — hotspot exceeds threshold

  • Location: src/lib/inference/config.test.ts:1
  • Category: architecture
  • Problem: Added resolveAgentInferenceApi describe block (3 tests) to hotspot file (baseLines 534).
  • Impact: Test file growth on inference config hotspot.
  • Required action: Extract new describe block into separate test file (e.g., inference-config-agent-api.test.ts) or accept as minor growth for new pure function.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check `git diff src/lib/inference/config.test.ts` for added describe block; extract it.
  • Missing regression test: N/A — architecture finding.
  • Done when: The required change is committed and verification passes: Check `git diff src/lib/inference/config.test.ts` for added describe block; extract it.
  • Evidence: pr_review_drift_context.monolithDeltas shows baseLines: 534, headLines: 555, delta: 21, severity: blocker

PRA-11 Resolve/justify — E2E helper file grew 100 lines — review for unnecessary framework abstraction

PRA-12 Resolve/justify — Missing test for concurrent replaceStaleAnthropicProviderForOpenAiSurface race condition

  • Location: src/lib/onboard/inference-providers/remote.ts:185
  • Category: correctness
  • Problem: The replaceStaleAnthropicProviderForOpenAiSurface function deletes and re-registers a gateway provider. Concurrent calls could leave the provider in an inconsistent state (deleted but not re-created, or double-created).
  • Impact: Race condition could cause onboarding/rebuild to fail with confusing errors or leave gateway in broken state requiring manual cleanup.
  • Recommended action: Add unit test for concurrent replaceStaleAnthropicProviderForOpenAiSurface calls; verify idempotency or add locking.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Search for existing tests of replaceStaleAnthropicProviderForOpenAiSurface in remote.test.ts or provider-inference.test.ts; none exist for concurrency.
  • Missing regression test: Add test: concurrent calls to replaceStaleAnthropicProviderForOpenAiSurface for same provider — verify exactly one succeeds and provider ends up as type=openai with correct bindings.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Search for existing tests of replaceStaleAnthropicProviderForOpenAiSurface in remote.test.ts or provider-inference.test.ts; none exist for concurrency.
  • Evidence: remote.ts:185-250 implements replacement logic with delete+upsert; no locking or idempotency key. Prior advisor PRA-9.

PRA-13 Resolve/justify — Missing test: failed provider inference heal leaves stale preferredInferenceApi armed for next resume

  • Location: src/lib/onboard/machine/handlers/provider-inference.ts:150
  • Category: correctness
  • Problem: When healAdjustedInferenceApi=true but provider setup fails, the session may retain stale preferredInferenceApi that gets re-used on next resume, causing repeated failures.
  • Impact: Silent degradation — user sees repeated failures without clear indication that registry metadata is stale.
  • Recommended action: Add test: provider inference setup fails after healAdjustedInferenceApi=true; verify session still has stale preferredInferenceApi and error surfaces clearly.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check provider-inference.test.ts for tests covering failed setupInference after surface-ready check triggers heal; none found.
  • Missing regression test: Add test: resume flow with healAdjustedInferenceApi=true where setupInference fails — verify session.preferredInferenceApi remains stale value and error message guides user to rebuild.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check provider-inference.test.ts for tests covering failed setupInference after surface-ready check triggers heal; none found.
  • Evidence: provider-inference.ts uses isResumeProviderSurfaceReady to detect stale gateway; if false, calls setupInference with openai-completions. Failure path not tested negatively. Prior advisor PRA-10.

PRA-14 Resolve/justify — Missing defensive test: agent with both provider_type=custom AND openai_compatible

  • Location: src/lib/inference/config.test.ts:50
  • Category: tests
  • Problem: coerceAgentInferenceApi handles openai_compatible agents; resolveAgentInferenceApi handles Hermes (custom). An agent declaring both provider_types creates ambiguous routing priority.
  • Impact: Undefined behavior — could route to wrong frontend (Anthropic vs OpenAI) causing inference failures.
  • Recommended action: Add test: agent { inference: { provider_type: 'custom' } } with openai_compatible also set — verify deterministic fallback (which function wins).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check config.test.ts describe coerceAgentInferenceApi and resolveAgentInferenceApi — no test covers dual provider_type.
  • Missing regression test: Add test: agent.inference.provider_type = ['custom', 'openai_compatible'] (or object with both keys) — verify resolveAgentInferenceApi takes precedence for Hermes, coerceAgentInferenceApi for OpenClaw, and behavior is documented.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check config.test.ts describe coerceAgentInferenceApi and resolveAgentInferenceApi — no test covers dual provider_type.
  • Evidence: config.ts: resolveAgentInferenceApi checks agentName===hermes first; coerceAgentInferenceApi checks provider_type===openai_compatible. Interaction untested. Prior advisor PRA-11.

PRA-15 Resolve/justify — Missing E2E test: rebuild migration of legacy Hermes custom Anthropic sandbox

  • Location: test/e2e/live/hermes-inference-switch.test.ts:1
  • Category: acceptance
  • Problem: Issue [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 requires that legacy Hermes sandboxes with type=anthropic provider can be migrated via rebuild. No E2E test covers this end-to-end path.
  • Impact: Migration path unverified in real environment; users may hit undocumented failures during rebuild.
  • Recommended action: Add E2E test: create Hermes sandbox with legacy Anthropic registration, run rebuild, verify OpenAI frontend registration and successful inference (hermes -z works).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check test/e2e/live/hermes-inference-switch.test.ts for rebuild migration test; none exists for legacy Anthropic → OpenAI migration.
  • Missing regression test: Add E2E test: onboard Hermes with compatible-anthropic-endpoint (simulate legacy type=anthropic), run nemoclaw <sandbox> rebuild, verify gateway provider type=openai, verify hermes -z produces final response.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check test/e2e/live/hermes-inference-switch.test.ts for rebuild migration test; none exists for legacy Anthropic → OpenAI migration.
  • Evidence: Issue [DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start #6289 acceptance requires rebuild migration; docs mention it (switch-inference-providers.mdx:121) but no E2E test. Prior advisor PRA-12.

PRA-16 Resolve/justify — Missing test: HTTPS on host.openshell.internal should be rejected

  • Location: src/lib/actions/inference-set.ts:410
  • Category: security
  • Problem: normalizeCustomEndpointUrl allows only HTTP for host.openshell.internal (ALLOWED_PRIVATE_CUSTOM_ENDPOINT_HOSTS). HTTPS should be rejected to prevent TLS bypass of sandbox network policy, but no test verifies this.
  • Impact: Trust boundary gap — if HTTPS were accidentally allowed, it could enable SSRF or credential leakage via spoofed internal endpoints.
  • Recommended action: Add test: normalizeCustomEndpointUrl rejects 'https://host.openshell.internal:8000/v1' with InferenceSetError.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run normalizeCustomEndpointUrl('https://host.openshell.internal:8000/v1', mockRewrite) and expect InferenceSetError; no such test exists in inference-set.test.ts or config.test.ts.
  • Missing regression test: Add test in inference-set.test.ts or config.test.ts: normalizeCustomEndpointUrl with https://host.openshell.internal throws 'endpoint-url is not allowed'.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run normalizeCustomEndpointUrl('https://host.openshell.internal:8000/v1', mockRewrite) and expect InferenceSetError; no such test exists in inference-set.test.ts or config.test.ts.
  • Evidence: inference-set.ts:410 enforces protocol === 'http:' for host.openshell.internal; security review Category 2 PASS but test missing. Prior advisor PRA-13.

PRA-17 Improvement — Duplicate Bedrock behavior note in two doc files — centralize

  • Location: docs/inference/inference-options.mdx:358
  • Category: docs
  • Problem: Both inference-options.mdx:358 and switch-inference-providers.mdx:119 contain 'AWS Bedrock routes retain their existing OpenAI-compatible adapter behavior.'
  • Impact: Documentation drift risk — if behavior changes, one location may be updated but not the other.
  • Suggested action: Centralize Bedrock behavior note in one location (e.g., inference-options.mdx) and reference from switch-inference-providers.mdx, or keep both but ensure single source of truth via shared include.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Search both files for 'AWS Bedrock routes retain' — appears twice with identical wording.
  • Missing regression test: N/A — doc finding; add doc-validate rule or manual check in release process.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: diff shows both files added same sentence. Prior advisor PRA-14.

PRA-18 Improvement — Improve error message clarity for failed OpenAI surface probe

  • Location: src/lib/onboard/inference-providers/remote.ts:220
  • Category: correctness
  • Problem: Error message says 'or onboard an agent that uses the native Anthropic Messages route (for example, OpenClaw).' but should explicitly mention `nemoclaw onboard` command.
  • Impact: User confusion — error suggests OpenClaw as alternative but doesn't give actionable command.
  • Suggested action: Change to: 'or onboard an agent that natively supports the Anthropic Messages API (e.g., OpenClaw via `nemoclaw onboard`).'
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check remote.ts:220 error message string; verify it matches suggested wording.
  • Missing regression test: N/A — UX improvement; no regression test needed.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: remote.ts:220 current message: 'or onboard an agent that uses the native Anthropic Messages route (for example, OpenClaw).' Prior advisor PRA-15.

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: Apurv Kumaria <akumaria@nvidia.com>
@cv
cv merged commit 5443538 into main Jul 6, 2026
55 checks passed
@cv
cv deleted the fix/6289-hermes-openai-frontend branch July 6, 2026 19:07
@github-actions github-actions Bot added the v0.0.88 Release target label Jul 6, 2026
@prekshivyas

Copy link
Copy Markdown
Contributor

Heads-up: the hermes-inference-switch live suite added here fails deterministically in the full E2E dispatch on main (run 28823033668, both matrix variants, ~37s, reproduced on rerun). It's not flaky — the suite never runs a test:

FAIL  e2e-live  test/e2e/live/hermes-inference-switch.test.ts (0 test)
Error: Cannot find module '../runner'
  ❯ src/lib/inference/ollama-runtime-context.ts:15:24
     const { runCapture } = require("../runner");

Root cause: this is the first e2e-live suite to import a deep src graph — its helpers import "../../../src/lib/inference/config.ts", which transitively loads ollama-runtime-context.ts and its runtime require("../runner"). The e2e-live Vitest project never registered the typed-source .ts require hook (test/helpers/onboard-script-mocks.cjs) that the cli and integration projects load via setupFiles, so Node's native CJS resolver can't resolve the extensionless .ts and the suite throws at collection. Other live suites don't hit it because they drive the CLI as a subprocess and import only fixtures.

The suite change here is fine — this exposed a pre-existing gap in the e2e-live project config.

Fix: #6343 adds setupFiles: ["test/helpers/onboard-script-mocks.cjs"] to e2e-live (registers the hook in-process; deliberately not via NODE_OPTIONS, to avoid leaking --require into the real CLI subprocesses). Verified locally: before → Cannot find module '../runner'; after → the suite collects and all e2e-live suites report 0 collection errors.

Worth noting the PR/E2E advisors run a different matrix than the full dispatch, which is why this passed pre-merge.

cv pushed a commit that referenced this pull request Jul 6, 2026
…board dcode identity failure (#6343)

## Summary
Fixes two E2E-harness problems surfaced by the E2E dispatch on `main`:

1. **e2e-live source require hook** — the `hermes-inference-switch` live
suite (added in #6335) failed at collection with `Cannot find module
'../runner'` because the `e2e-live` Vitest project never loaded the
typed-source require hook.
2. **cloud-onboard observability** — the cloud-experimental check-04
(added in #6332) fails on `main` with `could not read initial dcode
identity`, but the real `dcode identity` error is captured into a shell
var and discarded, so it can't be diagnosed.

## Changes
- `vitest.config.ts`: add `setupFiles:
["test/helpers/onboard-script-mocks.cjs"]` to the `e2e-live` project
(mirrors `cli`). Registers the typed-source `.ts` require hook
**in-process** — deliberately not via `env.NODE_OPTIONS`, so `--require`
never leaks into the real CLI subprocesses live tests spawn.
-
`test/e2e/e2e-cloud-experimental/checks/04-deepagents-code-fresh-reonboard.sh`:
on both `dcode identity` reads, print the captured stdout+stderr to
stdout (so it lands in `result.json`) before `fail`. No change to
pass/fail logic — only makes the existing failure observable.

### Root cause — #1 (fixed here)
`hermes-inference-switch` is the first `e2e-live` suite to import a deep
`src` graph — its helpers import `src/lib/inference/config.ts`, which
transitively loads `ollama-runtime-context.ts`'s runtime
`require("../runner")`. Without the require hook, Node's native CJS
resolver can't resolve the extensionless `.ts` → suite throws at
collection (`0 tests`, ~37s). Only this suite hit it; others drive the
CLI as a subprocess and import only fixtures. `runner.ts` has no
circular dependency on the inference graph, so the in-process hook
resolves it fully.

### Root cause — #2 (observability only; product root cause pending)
`cloud-onboard` was green on `main` through 2026-07-06 00:56 UTC and
failed on the first main E2E after #6332 landed (19:50 UTC) — #6332
added check-04, which has never passed on main. `dcode identity` is the
NemoClaw wrapper (`agents/langchain-deepagents-code/dcode-wrapper.sh`);
its identity path returns 0 in isolation and #6332 did not modify it, so
the non-zero exit is a runtime condition in #6332's new "recreate/verify
live identity" onboarding flow. That can't be pinned without the
swallowed stderr — which this change surfaces. Product root cause is for
the #6332 author to fix once the next run shows the real error.

## Type of Change
- [x] Code change (feature, bug fix, or refactor)

## Quality Gates
- [x] Existing tests cover changed behavior — justification: both
changes are E2E-harness config/diagnostics. #1: the `e2e-live` suites
exercise the hook — verified the previously-failing
`hermes-inference-switch` suite now collects and all `e2e-live` suites
report 0 collection errors, and the full `e2e-all` dispatch ran the
switch job (hosted) green. #2: pure diagnostic output; no pass/fail
change.
- [x] Docs not applicable — justification: internal test-harness
config/diagnostics; no user-facing behavior.
- [x] Sensitive paths changed (onboarding/inference/runner adjacent via
test config)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — justification: changes are confined to Vitest test-runner
setup (`vitest.config.ts`) and an E2E diagnostic print; no product
runtime code path is altered. The require hook is in-process only and
does not touch product CLI subprocesses.

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed —
note: `pre-push` `tsc-cli` skipped for a pre-existing local-only
`noImplicitAny` false-positive in
`test/helpers/mcp-lifecycle-lock-properties.ts` and
`src/lib/state/mcp-lifecycle-lock-identity.test.ts` (unrelated to this
diff); CI `tsc-cli` covers it. Check-04 passed `bash -n` and the
`shellcheck`/`shfmt` pre-commit hooks.
- [x] Targeted behavior tests pass — command/result:
`NEMOCLAW_RUN_LIVE_E2E=1 npx vitest list --project e2e-live` → switch
suite collects; whole project 0 collection errors (before the fix it
reproduced `Cannot find module '../runner'`). Full `e2e-all` dispatch on
this branch ran `hermes-inference-switch (hosted)` green.
- [x] No secrets, API keys, or credentials committed

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


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

* **Bug Fixes**
* Improved reliability of live end-to-end test runs by loading the
required hook inside the test process, avoiding leakage into real CLI
subprocesses.
* Made identity checks in sandboxed cloud experimental flows more
robust, with clearer diagnostics when identity lookup fails.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cv pushed a commit that referenced this pull request Jul 7, 2026
## Summary
Add the v0.0.75 release-notes entry for the release train, summarizing
the user-facing fixes merged since v0.0.74. Release-prep docs for the
`nemoclaw-maintainer-cut-release-tag` gate.

## Related Issue
Release prep for v0.0.75. Remove this section if none.

## Changes
- `docs/about/release-notes.mdx`: add the `## v0.0.75` section (themed
intro + grouped bullets with source-page links), matching the existing
v0.0.74 style.

### Source summary (doc-impacting PRs → doc page)
- #6370 -> `docs/about/release-notes.mdx`: prepared-backup recovery
restores gateway state and defers the live route check to onboarding, so
upgrade recovery no longer fails on an unset gateway route.
- #6305 -> `docs/about/release-notes.mdx`: in-place upgrades recover
gateway-orphaned sandboxes.
- #6332 -> `docs/about/release-notes.mdx`: same-name `--fresh`
re-onboard preserves fresh LangChain Deep Agents Code routing.
- #6335 -> `docs/about/release-notes.mdx`: custom Anthropic-compatible
inference uses the OpenAI frontend.
- #6298 -> `docs/about/release-notes.mdx`: OpenAI-only agents keep the
`/v1` base URL on Anthropic-compatible endpoints.
- #6304 -> `docs/about/release-notes.mdx`: local docker-driver gateway
credentials no longer expire.
- #6261 -> `docs/about/release-notes.mdx`: Hermes runtime and managed
MCP state reconcile after a runtime change.
- #6318 -> `docs/about/release-notes.mdx`: Hermes installs accept a
pinned base platform digest.
- #6291 -> `docs/about/release-notes.mdx`: OpenClaw local CLI pairing
restores its previous connection path.

Test-performance, CI, and chore commits since v0.0.74 are excluded as
non-user-facing.

## Type of Change
- [x] Doc only (prose changes, no code sample modifications)

## Quality Gates
- [x] Tests not applicable — justification: documentation-only change
(release notes prose).
- [x] Docs updated for user-facing behavior changes

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] `npm run docs` builds without warnings introduced by this change —
command/result: "Found 0 errors and 2 warnings" (the 2 warnings
pre-exist this change).
- [x] Doc pages follow the style guide (active voice, no numbered/colon
titles, correct NVIDIA/NemoClaw/OpenShell capitalization; skip-terms
avoided).
- [x] No secrets, API keys, or credentials committed

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


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

* **Documentation**
* Added a new **v0.0.75** section to the release notes, highlighting
improved sandbox upgrade hardening and prepared-backup recovery, updated
inference routing for Anthropic-compatible endpoints, longer-lasting
local gateway credential handling, and restored CLI pairing reconnection
without re-pairing. Also includes cross-links to related NemoClaw CLI
and documentation pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ericksoa added a commit that referenced this pull request Jul 7, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->
Correct the v0.0.75 release-note entry merged in #6371 before the
release tag is cut.
This follow-up restores the omitted OpenClaw `2026.6.10` upgrade and
narrows three claims to the runtime contracts that actually shipped.

## Changes
<!-- Bullet list of key changes. -->
- #5595 -> `docs/about/release-notes.mdx`: add the bundled OpenClaw
`2026.6.10` upgrade and its reviewed package, pairing, and recovery
boundaries.
- #6370 -> `docs/about/release-notes.mdx`: state that authoritative
onboarding restores the gateway provider and inference route during
rebuild, before sandbox recreation.
- #6335 and #6298 -> `docs/about/release-notes.mdx`: scope the OpenAI
frontend to Hermes while retaining the separate OpenAI-only-agent
behavior.
- #6304 -> `docs/about/release-notes.mdx`: name the non-expiring local
Docker-driver sandbox JWT contract precisely and link its gateway-auth
review.

## 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 exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: prose-only release-note
corrections with no runtime behavior or code samples.
- [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 applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: tests
are not applicable; `npm run docs` passed with 0 errors and 2
pre-existing warnings.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [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) —
result: 0 errors and 2 pre-existing warnings (missing authenticated
redirects check and existing light-theme accent contrast).
- [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: Aaron Erickson <aerickson@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
* Updated the `v0.0.75` release notes with clearer wording and expanded
details.
* Added more specific notes about the runtime upgrade, sandbox recovery
behavior, and routing safeguards.
* Refined the description of inference routing behavior and local
Docker-driver sandbox authentication handling.
* Adjusted the linked references and final release-note wording for
consistency.

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

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
## Summary

Fix Hermes custom Anthropic routing by using the endpoint's verified
OpenAI Chat Completions surface end to end. NemoClaw selects
`https://inference.local/v1`, verifies `/v1/chat/completions`, and
aligns the OpenShell provider to `type=openai` with `OPENAI_BASE_URL`,
avoiding the duplicate Anthropic SSE `message_start` sequence that
caused `hermes -z` to finish with `no final response`.

The core managed-frontend direction was first proposed by @chengjiew in
NVIDIA#6295, and Chengjie Wang is included as a commit co-author.
@TonyLuo-NV's NVIDIA#6297 contributed streaming-failure investigation and
regression analysis. Thanks to @hulynn for the reproducible
managed-proxy report.

## Related Issue

Fixes NVIDIA#6289

## Changes

- Resolve Hermes `compatible-anthropic-endpoint` routes to the managed
`openai-completions` frontend and reuse NVIDIA#6298's verified OpenAI-surface
provider registration while retaining `COMPATIBLE_ANTHROPIC_API_KEY` as
the credential binding.
- Persist the normalized frontend during fresh onboarding; repair stale
provider identity, registry metadata, and sandbox configuration during
rebuild or resume.
- Reject conflicting explicit API choices and legacy `type=anthropic`
runtime switches before mutating OpenShell, registry, or in-sandbox
state.
- Preserve native Anthropic Messages routing for OpenClaw custom
endpoints and first-party Anthropic routes; preserve the existing AWS
Bedrock adapter behavior.
- Extend unit, integration, command-shape, and live E2E coverage,
including the reported `hermes -z` path; document the verified-surface
requirement and rebuild migration.

## Type of Change

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

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: independent final
review found no blockers. Endpoint probing and provider replacement
reuse the fail-closed NVIDIA#6298 boundary; this PR adds exact non-secret
provider identity checks and introduces no credential values. Human
maintainer approval remains required.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — 289 CLI tests, 7 OpenAI-surface
onboarding integration tests, 1 focused Hermes config integration test,
and 18 E2E support tests passed
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — required GitHub Actions checks pending
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors and 2 existing Fern warnings
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Additional local verification:

- `npm run build:cli`
- `npm run typecheck:cli`
- `npm run checks`
- `npm run test-size:check`
- `npm run test:titles:check`
- `npm run source-shape:check`
- `npm run test:projects:check`
- `npm run test:imports:check`
- `npm run docs` (0 errors; 2 existing warnings)

---
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Chengjie Wang <chengjiew@nvidia.com>
Co-authored-by: Chengjie Wang <chengjiew@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…board dcode identity failure (NVIDIA#6343)

## Summary
Fixes two E2E-harness problems surfaced by the E2E dispatch on `main`:

1. **e2e-live source require hook** — the `hermes-inference-switch` live
suite (added in NVIDIA#6335) failed at collection with `Cannot find module
'../runner'` because the `e2e-live` Vitest project never loaded the
typed-source require hook.
2. **cloud-onboard observability** — the cloud-experimental check-04
(added in NVIDIA#6332) fails on `main` with `could not read initial dcode
identity`, but the real `dcode identity` error is captured into a shell
var and discarded, so it can't be diagnosed.

## Changes
- `vitest.config.ts`: add `setupFiles:
["test/helpers/onboard-script-mocks.cjs"]` to the `e2e-live` project
(mirrors `cli`). Registers the typed-source `.ts` require hook
**in-process** — deliberately not via `env.NODE_OPTIONS`, so `--require`
never leaks into the real CLI subprocesses live tests spawn.
-
`test/e2e/e2e-cloud-experimental/checks/04-deepagents-code-fresh-reonboard.sh`:
on both `dcode identity` reads, print the captured stdout+stderr to
stdout (so it lands in `result.json`) before `fail`. No change to
pass/fail logic — only makes the existing failure observable.

### Root cause — rh-ai-quickstart#1 (fixed here)
`hermes-inference-switch` is the first `e2e-live` suite to import a deep
`src` graph — its helpers import `src/lib/inference/config.ts`, which
transitively loads `ollama-runtime-context.ts`'s runtime
`require("../runner")`. Without the require hook, Node's native CJS
resolver can't resolve the extensionless `.ts` → suite throws at
collection (`0 tests`, ~37s). Only this suite hit it; others drive the
CLI as a subprocess and import only fixtures. `runner.ts` has no
circular dependency on the inference graph, so the in-process hook
resolves it fully.

### Root cause — NVIDIA#2 (observability only; product root cause pending)
`cloud-onboard` was green on `main` through 2026-07-06 00:56 UTC and
failed on the first main E2E after NVIDIA#6332 landed (19:50 UTC) — NVIDIA#6332
added check-04, which has never passed on main. `dcode identity` is the
NemoClaw wrapper (`agents/langchain-deepagents-code/dcode-wrapper.sh`);
its identity path returns 0 in isolation and NVIDIA#6332 did not modify it, so
the non-zero exit is a runtime condition in NVIDIA#6332's new "recreate/verify
live identity" onboarding flow. That can't be pinned without the
swallowed stderr — which this change surfaces. Product root cause is for
the NVIDIA#6332 author to fix once the next run shows the real error.

## Type of Change
- [x] Code change (feature, bug fix, or refactor)

## Quality Gates
- [x] Existing tests cover changed behavior — justification: both
changes are E2E-harness config/diagnostics. rh-ai-quickstart#1: the `e2e-live` suites
exercise the hook — verified the previously-failing
`hermes-inference-switch` suite now collects and all `e2e-live` suites
report 0 collection errors, and the full `e2e-all` dispatch ran the
switch job (hosted) green. NVIDIA#2: pure diagnostic output; no pass/fail
change.
- [x] Docs not applicable — justification: internal test-harness
config/diagnostics; no user-facing behavior.
- [x] Sensitive paths changed (onboarding/inference/runner adjacent via
test config)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — justification: changes are confined to Vitest test-runner
setup (`vitest.config.ts`) and an E2E diagnostic print; no product
runtime code path is altered. The require hook is in-process only and
does not touch product CLI subprocesses.

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed —
note: `pre-push` `tsc-cli` skipped for a pre-existing local-only
`noImplicitAny` false-positive in
`test/helpers/mcp-lifecycle-lock-properties.ts` and
`src/lib/state/mcp-lifecycle-lock-identity.test.ts` (unrelated to this
diff); CI `tsc-cli` covers it. Check-04 passed `bash -n` and the
`shellcheck`/`shfmt` pre-commit hooks.
- [x] Targeted behavior tests pass — command/result:
`NEMOCLAW_RUN_LIVE_E2E=1 npx vitest list --project e2e-live` → switch
suite collects; whole project 0 collection errors (before the fix it
reproduced `Cannot find module '../runner'`). Full `e2e-all` dispatch on
this branch ran `hermes-inference-switch (hosted)` green.
- [x] No secrets, API keys, or credentials committed

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


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

* **Bug Fixes**
* Improved reliability of live end-to-end test runs by loading the
required hook inside the test process, avoiding leakage into real CLI
subprocesses.
* Made identity checks in sandboxed cloud experimental flows more
robust, with clearer diagnostics when identity lookup fails.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
## Summary
Add the v0.0.75 release-notes entry for the release train, summarizing
the user-facing fixes merged since v0.0.74. Release-prep docs for the
`nemoclaw-maintainer-cut-release-tag` gate.

## Related Issue
Release prep for v0.0.75. Remove this section if none.

## Changes
- `docs/about/release-notes.mdx`: add the `## v0.0.75` section (themed
intro + grouped bullets with source-page links), matching the existing
v0.0.74 style.

### Source summary (doc-impacting PRs → doc page)
- NVIDIA#6370 -> `docs/about/release-notes.mdx`: prepared-backup recovery
restores gateway state and defers the live route check to onboarding, so
upgrade recovery no longer fails on an unset gateway route.
- NVIDIA#6305 -> `docs/about/release-notes.mdx`: in-place upgrades recover
gateway-orphaned sandboxes.
- NVIDIA#6332 -> `docs/about/release-notes.mdx`: same-name `--fresh`
re-onboard preserves fresh LangChain Deep Agents Code routing.
- NVIDIA#6335 -> `docs/about/release-notes.mdx`: custom Anthropic-compatible
inference uses the OpenAI frontend.
- NVIDIA#6298 -> `docs/about/release-notes.mdx`: OpenAI-only agents keep the
`/v1` base URL on Anthropic-compatible endpoints.
- NVIDIA#6304 -> `docs/about/release-notes.mdx`: local docker-driver gateway
credentials no longer expire.
- NVIDIA#6261 -> `docs/about/release-notes.mdx`: Hermes runtime and managed
MCP state reconcile after a runtime change.
- NVIDIA#6318 -> `docs/about/release-notes.mdx`: Hermes installs accept a
pinned base platform digest.
- NVIDIA#6291 -> `docs/about/release-notes.mdx`: OpenClaw local CLI pairing
restores its previous connection path.

Test-performance, CI, and chore commits since v0.0.74 are excluded as
non-user-facing.

## Type of Change
- [x] Doc only (prose changes, no code sample modifications)

## Quality Gates
- [x] Tests not applicable — justification: documentation-only change
(release notes prose).
- [x] Docs updated for user-facing behavior changes

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] `npm run docs` builds without warnings introduced by this change —
command/result: "Found 0 errors and 2 warnings" (the 2 warnings
pre-exist this change).
- [x] Doc pages follow the style guide (active voice, no numbered/colon
titles, correct NVIDIA/NemoClaw/OpenShell capitalization; skip-terms
avoided).
- [x] No secrets, API keys, or credentials committed

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


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

* **Documentation**
* Added a new **v0.0.75** section to the release notes, highlighting
improved sandbox upgrade hardening and prepared-backup recovery, updated
inference routing for Anthropic-compatible endpoints, longer-lasting
local gateway credential handling, and restored CLI pairing reconnection
without re-pairing. Also includes cross-links to related NemoClaw CLI
and documentation pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->
Correct the v0.0.75 release-note entry merged in NVIDIA#6371 before the
release tag is cut.
This follow-up restores the omitted OpenClaw `2026.6.10` upgrade and
narrows three claims to the runtime contracts that actually shipped.

## Changes
<!-- Bullet list of key changes. -->
- NVIDIA#5595 -> `docs/about/release-notes.mdx`: add the bundled OpenClaw
`2026.6.10` upgrade and its reviewed package, pairing, and recovery
boundaries.
- NVIDIA#6370 -> `docs/about/release-notes.mdx`: state that authoritative
onboarding restores the gateway provider and inference route during
rebuild, before sandbox recreation.
- NVIDIA#6335 and NVIDIA#6298 -> `docs/about/release-notes.mdx`: scope the OpenAI
frontend to Hermes while retaining the separate OpenAI-only-agent
behavior.
- NVIDIA#6304 -> `docs/about/release-notes.mdx`: name the non-expiring local
Docker-driver sandbox JWT contract precisely and link its gateway-auth
review.

## 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 exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: prose-only release-note
corrections with no runtime behavior or code samples.
- [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 applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: tests
are not applicable; `npm run docs` passed with 0 errors and 2
pre-existing warnings.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [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) —
result: 0 errors and 2 pre-existing warnings (missing authenticated
redirects check and existing light-theme accent contrast).
- [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: Aaron Erickson <aerickson@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
* Updated the `v0.0.75` release notes with clearer wording and expanded
details.
* Added more specific notes about the runtime upgrade, sandbox recovery
behavior, and routing safeguards.
* Refined the description of inference routing behavior and local
Docker-driver sandbox authentication handling.
* Adjusted the linked references and final release-note wording for
consistency.

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

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

Labels

v0.0.88 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DGX Station][Inference] NemoHermes -z fails "no final response" on Anthropic-compatible route — managed proxy emits duplicate SSE message_start

4 participants