Skip to content

fix(inference): route local compatible endpoints through gateway#6649

Merged
cv merged 10 commits into
mainfrom
fix/5744-local-inference-gateway-verified
Jul 11, 2026
Merged

fix(inference): route local compatible endpoints through gateway#6649
cv merged 10 commits into
mainfrom
fix/5744-local-inference-gateway-verified

Conversation

@sandl99

@sandl99 sandl99 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replaces PR #6331 with a clean, GitHub-verified branch for the local compatible-endpoint gateway fix.
The change keeps host-side validation on the user-entered loopback URL, registers eligible sandbox routes through host.openshell.internal, and documents the exposure risk of 0.0.0.0 binds.

Related Issue

Fixes #5744.
Replaces #6331.

Changes

  • Rewrite only compatible-endpoint HTTP URLs with exact loopback hosts and explicit bundled policy ports (11434, 11435, or 8000) when registering the OpenShell provider route.
  • Keep host validation on the user-entered URL; on credential reuse, update an existing provider to the gateway alias without exporting or replacing its credential, then configure inference with --no-verify.
  • Extract the focused transformation and recovery logic from remote.ts, and document the exact supported URL shapes, bundled ports, bridge reachability, and 0.0.0.0 exposure mitigations.
  • Add unit, recovery-integration, docs, fast E2E-support, and hermetic live inference-routing coverage for the gateway registration contract.

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: This is the clean-history replacement for fix(inference): route local compatible endpoints through gateway #6331 after the maintainer sweep at fix(inference): route local compatible endpoints through gateway #6331 (review). The replacement preserves the reviewed gateway-routing change and adds the requested adjacent 0.0.0.0 exposure warning instead of accepting the risk silently.
  • 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 — command/result or justification: focused CLI, integration, docs, E2E-support, mock-parity, project-membership, title, size, and build checks passed; npm run docs reported 0 errors and 2 existing warnings; live run 29129492764 passed inference-routing, network-policy, onboard-repair, onboard-resume, and cloud-onboard.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: env -u SSH_CONNECTION -u SSH_CLIENT -u SSH_TTY npm test passed 1,383 test files and 15,864 tests (39 skipped, 1 todo).
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: San Dang sdang@nvidia.com
Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • New Features

    • Compatible inference endpoints using supported loopback addresses and ports can now be automatically routed through the sandbox gateway.
    • Rebuilds can restore compatible endpoint routing without requiring stored host credentials.
    • Endpoint paths, query strings, and fragments are preserved during automatic routing.
  • Documentation

    • Expanded guidance explains supported endpoints, routing behavior, validation limits, and runtime status checks.
    • Clarified credential handling during gateway recovery.

Signed-off-by: San Dang <sdang@nvidia.com>
@sandl99 sandl99 added area: docs Documentation, examples, guides, or docs build area: security Security controls, permissions, secrets, or hardening labels Jul 10, 2026
@sandl99 sandl99 self-assigned this Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0e8d1588-1153-479b-862a-98c92ea47c72

📥 Commits

Reviewing files that changed from the base of the PR and between e332453 and 619e0a8.

📒 Files selected for processing (7)
  • docs/inference/how-inference-routing-works.mdx
  • docs/inference/set-up-openai-compatible-endpoint.mdx
  • docs/security/openclaw-2026.6.10-dependency-review.md
  • test/e2e/lib/fake-openai-compatible-api.mts
  • test/e2e/live/inference-routing.test.ts
  • test/e2e/mock-parity.json
  • test/inference-options-docs.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/inference/how-inference-routing-works.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e/mock-parity.json
  • test/e2e/live/inference-routing.test.ts

📝 Walkthrough

Walkthrough

The change adds gateway-aware routing for compatible loopback inference endpoints, updates provider onboarding and recovery, adds onboarding and E2E coverage, expands documentation assertions, and enforces Docker authentication handling for the inference-routing workflow.

Changes

Inference gateway routing

Layer / File(s) Summary
Gateway endpoint normalization
src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts, src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.test.ts
Bundled gateway ports and strict loopback URL rewriting are implemented and tested, including suffix preservation and unchanged unsupported inputs.
Gateway-scoped onboarding integration
src/lib/onboard/inference-providers/remote.ts, test/onboard-inference-gateway-scope.test.ts
Provider reuse, registration, verification bypass, and sandbox updates use gateway-compatible endpoints and credential-free recovery behavior.
End-to-end routing validation
test/e2e/fixtures/fake-openai-compatible.ts, test/e2e/lib/fake-openai-compatible-api.mts, test/e2e/live/inference-routing.test.ts, test/e2e/support/hosted-inference.test.ts, test/e2e/mock-parity.json
Fake-server request metadata and responses support assertions that onboarding starts locally and sandbox inference routes through host.openshell.internal.
Routing documentation and regression assertions
docs/inference/*, docs/security/*, test/inference-options-docs.test.ts
Documentation and tests describe bundled ports, endpoint rewriting, bridge availability, runtime checks, and recovery without host credentials.
Inference-routing workflow validation
.github/workflows/e2e.yaml, test/e2e/support/dockerhub-auth-workflow-boundary.test.ts, tools/e2e/workflow-boundary.mts
The inference-routing job authenticates and cleans up Docker credentials, and workflow boundary checks require that coverage.

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

Sequence Diagram(s)

sequenceDiagram
  participant HostEndpoint
  participant NemoClawOnboarding
  participant OpenShellGateway
  participant Sandbox
  HostEndpoint->>NemoClawOnboarding: provide loopback compatible endpoint
  NemoClawOnboarding->>NemoClawOnboarding: rewrite eligible URL to host.openshell.internal
  NemoClawOnboarding->>OpenShellGateway: register or reuse provider with gateway URL
  Sandbox->>OpenShellGateway: send inference request through inference.local
  OpenShellGateway->>HostEndpoint: proxy request to host.openshell.internal
  HostEndpoint-->>OpenShellGateway: return model response
  OpenShellGateway-->>Sandbox: return inference response
Loading

Suggested labels: area: e2e, area: providers

Suggested reviewers: ericksoa, cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: routing local compatible endpoints through the gateway.
Linked Issues check ✅ Passed The changes address #5744 by rewriting eligible loopback endpoints through host.openshell.internal, preserving validation, and adding matching tests/docs.
Out of Scope Changes check ✅ Passed The workflow, E2E, and docs updates appear tied to the new gateway-routing behavior and its test coverage, with no clear unrelated scope creep.
✨ 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/5744-local-inference-gateway-verified

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

@github-code-quality

github-code-quality Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage remains at 96%, unchanged from the branch.

TypeScript / code-coverage/cli

The overall coverage in the branch is 77%. The coverage in the branch is 78%.

Show a code coverage summary of the most impacted files.
File 41b40d1 619e0a8 +/-
src/lib/actions...de-preflight.ts 78% 51% -27%
src/lib/onboard...eway-cleanup.ts 82% 55% -27%
src/lib/onboard...er-gpu-patch.ts 85% 69% -16%
src/lib/adapter...ateway-drift.ts 54% 39% -15%
src/lib/agent/onboard.ts 81% 71% -10%
src/lib/sandbox/config.ts 62% 53% -9%
src/lib/inference/nim.ts 77% 71% -6%
src/lib/state/sandbox.ts 82% 77% -5%
src/lib/actions...dbox/connect.ts 70% 76% +6%
src/lib/onboard...ateway-route.ts 0% 74% +74%

Updated July 11, 2026 01:59 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: cloud-onboard, inference-routing, network-policy, onboard-repair, onboard-resume
Optional E2E: docs-validation, cloud-inference

Dispatch hint: cloud-onboard,inference-routing,network-policy,onboard-repair,onboard-resume

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • cloud-onboard: Required by the deterministic risk plan for platform-install risk from .github/workflows/e2e.yaml changes; validates clean hosted onboarding with the pinned runtime dependencies.
  • inference-routing: Required by the deterministic risk plan for inference-policy risk; validates the selected provider is reachable through the advertised sandbox inference route, including the changed compatible-endpoint gateway path.
  • network-policy: Required by the deterministic risk plan for inference-policy risk; validates the real host-to-sandbox policy allows the intended host-gateway inference route and denies unintended egress.
  • onboard-repair: Required by the deterministic risk plan for lifecycle-state risk; validates repair convergence for provider recovery and sandbox recreation paths affected by recovered compatible-endpoint gateway rewriting.
  • onboard-resume: Required by the deterministic risk plan for lifecycle-state risk; validates resume convergence for onboarding/rebuild state involving recovered provider reuse and sandbox route registration.

Optional E2E

  • docs-validation: Optional confidence for the changed inference docs and docs-related tests; useful but not merge-blocking relative to the runtime inference and lifecycle gates.
  • cloud-inference: Optional adjacent runtime confidence that a hosted provider still works through sandbox inference.local after remote provider setup changes; not required by the deterministic floor because inference-routing and cloud-onboard cover the primary affected boundaries.

New E2E recommendations

  • recovered compatible-endpoint bridge rewrite (medium): The PR adds credential-preserving recovery behavior that can perform a config-only OpenShell provider update from a recovered loopback compatible endpoint to host.openshell.internal. Existing required resume/repair jobs should be run, but a focused live assertion would make this exact keyless rebuild bridge-rewrite contract explicit.
    • Suggested test: Add a live E2E slice that onboards a local compatible endpoint on a bundled port, rebuilds without a host COMPATIBLE_API_KEY, and proves the recovered provider receives only a config endpoint rewrite to host.openshell.internal with no credential flag while sandbox inference.local still responds.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: cloud-onboard,inference-routing,network-policy,onboard-repair,onboard-resume

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: cloud-onboard, inference-routing, network-policy, onboard-repair, onboard-resume
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=inference-routing
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=network-policy
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • cloud-onboard: Installer and platform changes must work on a clean supported host with the pinned runtime dependencies.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard
  • inference-routing: Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=inference-routing
  • network-policy: Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=network-policy
  • onboard-repair: Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair
  • onboard-resume: Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume

Optional E2E targets

  • None.

Relevant changed files

  • .github/workflows/e2e.yaml
  • src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts
  • src/lib/onboard/inference-providers/remote.ts
  • test/e2e/fixtures/fake-openai-compatible.ts
  • test/e2e/lib/fake-openai-compatible-api.mts
  • test/e2e/live/inference-routing.test.ts
  • test/e2e/mock-parity.json
  • test/e2e/support/dockerhub-auth-workflow-boundary.test.ts
  • test/e2e/support/hosted-inference.test.ts
  • tools/e2e/workflow-boundary.mts

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

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

Inline comments:
In `@src/lib/onboard/inference-providers/remote.ts`:
- Around line 53-56: Update the loopback endpoint rewriting logic to preserve
query strings and fragments. In the URL reconstruction after assigning
parsed.hostname and normalizing parsed.pathname, include parsed.search and
parsed.hash in both the root-path and non-root return values so parameters and
fragments are retained.
🪄 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: e04c2002-9807-4a51-a12a-56139f42bfb3

📥 Commits

Reviewing files that changed from the base of the PR and between a7bca71 and ab67617.

📒 Files selected for processing (4)
  • docs/inference/local-compatible-inference-setup.mdx
  • src/lib/onboard/inference-providers/remote.ts
  • test/inference-options-docs.test.ts
  • test/onboard-inference-gateway-scope.test.ts

Comment thread src/lib/onboard/inference-providers/remote.ts Outdated
@sandl99 sandl99 added area: inference Inference routing, serving, model selection, or outputs area: local-models Local model providers, downloads, launch, or connectivity area: routing Request routing, policy routing, model selection, or fallback logic area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression v0.0.80 Release target labels Jul 10, 2026
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

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

Action checklist

  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
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 — Run the `cloud-onboard` E2E job for Installer and platform changes must work on a clean supported host with the pinned runtime dependencies. Matched files: `.github/workflows/e2e.yaml`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Checked-in unit, support, docs, workflow-boundary, and live-test code covers the changed behavior and deterministic invariants, but the risk plan still names lifecycle-state, inference-policy, and platform-install families whose required jobs are runtime validation floors. Required job execution status was not evaluated.
  • PRA-T2 Runtime validation — Run or account for the `cloud-onboard` E2E job to validate clean-host installer/platform behavior with pinned runtime dependencies after the workflow Docker auth classification change.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Checked-in unit, support, docs, workflow-boundary, and live-test code covers the changed behavior and deterministic invariants, but the risk plan still names lifecycle-state, inference-policy, and platform-install families whose required jobs are runtime validation floors. Required job execution status was not evaluated.
  • PRA-T3 Runtime validation — Run the `inference-routing` E2E job for Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary. Matched files: `src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts`, `src/lib/onboard/inference-providers/remote.ts`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Checked-in unit, support, docs, workflow-boundary, and live-test code covers the changed behavior and deterministic invariants, but the risk plan still names lifecycle-state, inference-policy, and platform-install families whose required jobs are runtime validation floors. Required job execution status was not evaluated.
  • PRA-T4 Runtime validation — Run or account for the `inference-routing` E2E job to validate the real host-to-sandbox local compatible endpoint route, including dcode traffic through `inference.local` and `host.openshell.internal:8000`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Checked-in unit, support, docs, workflow-boundary, and live-test code covers the changed behavior and deterministic invariants, but the risk plan still names lifecycle-state, inference-policy, and platform-install families whose required jobs are runtime validation floors. Required job execution status was not evaluated.
  • PRA-T5 Runtime validation — Run the `network-policy` E2E job for Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary. Matched files: `src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts`, `src/lib/onboard/inference-providers/remote.ts`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Checked-in unit, support, docs, workflow-boundary, and live-test code covers the changed behavior and deterministic invariants, but the risk plan still names lifecycle-state, inference-policy, and platform-install families whose required jobs are runtime validation floors. Required job execution status was not evaluated.

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: San Dang <sdang@nvidia.com>
@sandl99
sandl99 requested a review from cv July 10, 2026 17:54
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 29112366528
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: inference-routing,network-policy,onboard-repair,onboard-resume,cloud-onboard
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-1: Gateway rewrite depends on OpenShell bridge DNS without health check or fail-closed behavior; then add or justify PRA-T1.
Open items: 12 required · 8 warnings · 2 suggestions · 8 test follow-ups
Since last review: 0 prior items resolved · 19 still apply · 8 new items found

Action checklist

  • PRA-1 Fix: Gateway rewrite depends on OpenShell bridge DNS without health check or fail-closed behavior in src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:27
  • PRA-2 Fix: reuseRegisteredProviderWithGatewayEndpoint fetches provider then updates without atomic compare-and-set in src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:61
  • PRA-6 Fix: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 fix only works on specific OpenShell versions/topologies — no version guard in src/lib/onboard/inference-providers/remote.ts:167
  • PRA-7 Fix: Gateway routes use --no-verify skipping inference verification with no runtime probe in src/lib/onboard/inference-providers/remote.ts:222
  • PRA-13 Fix: Broad private CIDR allowlist in local-inference network policy permits unintended egress in nemoclaw-blueprint/policies/presets/local-inference.yaml:1
  • PRA-14 Fix: Missing negative security tests for network policy denial, private IP egress, DNS failure, and loopback-only bind in test/e2e/live/inference-routing.test.ts:123
  • PRA-16 Fix: Missing negative test: network policy denial for non-policy port (TC-INF-11) in test/e2e/live/inference-routing.test.ts:123
  • PRA-17 Fix: Missing negative test: private IP egress denial (TC-INF-12) in test/e2e/live/inference-routing.test.ts:123
  • PRA-18 Fix: Missing negative test: bridge DNS failure for host.openshell.internal (TC-INF-13) in test/e2e/live/inference-routing.test.ts:123
  • PRA-19 Fix: Missing negative test: loopback-only bind causes 503 with bind guidance (TC-INF-14) in test/e2e/live/inference-routing.test.ts:123
  • PRA-3 Resolve or justify: Silent URL parse catch returns original endpoint on malformed input without error propagation in src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:33
  • PRA-4 Resolve or justify: Workflow trusted-code boundary expanded: dockerhub-auth added to inference-routing job in .github/workflows/e2e.yaml:1039
  • PRA-5 Resolve or justify: Mock parity mapping for inference-routing live test expanded without clear justification in test/e2e/mock-parity.json:7
  • PRA-8 Resolve or justify: Test/implementation mismatch: double provider get in recovery path test but implementation makes single call in test/onboard-inference-gateway-scope.test.ts:70
  • PRA-9 Resolve or justify: Bridge rewrite workaround in recovery path missing regression test and removal trigger in docs/security/openclaw-2026.6.10-dependency-review.md:195
  • PRA-10 Resolve or justify: Documentation weakens bind guidance to 0.0.0.0 with warning but no enforcement in docs/inference/set-up-openai-compatible-endpoint.mdx:25
  • PRA-15 Resolve or justify: Documentation warns about 0.0.0.0 bind requirement but onboarding does not enforce or validate in docs/inference/set-up-openai-compatible-endpoint.mdx:25
  • PRA-22 Resolve or justify: Missing test: concurrent provider modification between get and update in test/onboard-inference-gateway-scope.test.ts:70
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Missing negative test: network policy denial for non-policy port (TC-INF-11)
  • PRA-T7 Add or justify test follow-up: Missing negative test: private IP egress denial (TC-INF-12)
  • PRA-T8 Add or justify test follow-up: Missing negative test: bridge DNS failure for host.openshell.internal (TC-INF-13)
  • PRA-11 In-scope improvement: Dual-source inconsistency: gatewayEndpointUrl computed twice in recovery path in src/lib/onboard/inference-providers/remote.ts:173
  • PRA-12 In-scope improvement: BUNDLED_LOCAL_INFERENCE_GATEWAY_PORTS duplicated in code and policy YAML in src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:7

Findings index

ID Severity Category Location Required action
PRA-1 Required architecture src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:27 Add lightweight bridge reachability check (DNS resolution + TCP probe to host.openshell.internal:port) during gateway registration with actionable error, or add regression test simulating DNS failure proving fail-closed behavior and document removal condition (when OpenShell exposes bridge health endpoint).
PRA-2 Required architecture src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:61 Add retry logic with exponential backoff for provider update, or accept that upsertProvider handles missing provider gracefully. Add test for concurrent modification.
PRA-3 Resolve/justify architecture src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:33 Add structured error return (Result type) or at minimum a debug log in catch block. Caller remote.ts should handle parse error with actionable feedback rather than proceeding with potentially invalid URL.
PRA-4 Resolve/justify architecture .github/workflows/e2e.yaml:1039 Remove dockerhub-auth from inference-routing job unless tests actually require Docker Hub images. If kept, add justification comment and verify dockerhub-auth-workflow-boundary.test.ts asserts minimal required scope.
PRA-5 Resolve/justify scope test/e2e/mock-parity.json:7 Document in PR or code comment why each of the three fast tests is necessary for inference-routing parity. Verify each covers distinct, non-overlapping invariants that the live test exercises.
PRA-6 Required acceptance src/lib/onboard/inference-providers/remote.ts:167 Add OpenShell version detection and conditional rewrite, or document minimum OpenShell version requirement and validate server bind address during onboarding. Add regression test for version-gated behavior.
PRA-7 Required correctness src/lib/onboard/inference-providers/remote.ts:222 Add post-onboarding sandbox verification probe for gateway routes (e.g., lightweight inference.local call) before reporting onboarding success, or document that --no-verify means user must run $$nemoclaw status.
PRA-8 Resolve/justify correctness test/onboard-inference-gateway-scope.test.ts:70 Align test expectation with implementation (single provider get) or update implementation to match test's idempotency pattern with clear rationale. Add test for concurrent provider modification between get and update.
PRA-9 Resolve/justify acceptance docs/security/openclaw-2026.6.10-dependency-review.md:195 Add regression test simulating host.openshell.internal DNS failure during provider recovery. Add version-check test that flags when OpenShell bridge health endpoint becomes available. Document removal condition in code, not just docs.
PRA-10 Resolve/justify docs docs/inference/set-up-openai-compatible-endpoint.mdx:25 Add onboarding-time validation that local server is reachable from sandbox network context, or at minimum validate binding address is not 0.0.0.0 without explicit firewall confirmation. Document removal condition for bridge DNS dependency.
PRA-11 Improvement correctness src/lib/onboard/inference-providers/remote.ts:173 Centralize rewrite logic: have reuseRegisteredProviderWithGatewayEndpoint compute gatewayEndpointUrl internally, or pass only resolvedEndpointUrl and let it derive both. Ensure single source of truth.
PRA-12 Improvement architecture src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:7 Consider single source of truth: generate TypeScript constant from policy YAML at build time, or import policy YAML in test only. Keep as-is if build complexity not justified.
PRA-13 Required security nemoclaw-blueprint/policies/presets/local-inference.yaml:1 Narrow allowed_ips to OpenShell bridge subnet only (e.g., 172.17.0.0/16 for Docker bridge). Add negative test: attempt egress to 10.0.0.5:8000, assert denial. Document rationale for CIDR breadth if narrowing not feasible.
PRA-14 Required security test/e2e/live/inference-routing.test.ts:123 Add four negative test cases to inference-routing.test.ts covering the above scenarios. Verify network-policy job exercises these denials.
PRA-15 Resolve/justify security docs/inference/set-up-openai-compatible-endpoint.mdx:25 Add onboarding-time validation that local server is reachable from sandbox network context (e.g., probe from container network), or at minimum validate binding address is not 127.0.0.1 without explicit confirmation. Document removal condition for bridge DNS dependency.
PRA-16 Required tests test/e2e/live/inference-routing.test.ts:123 Add TC-INF-11 test: onboard with endpoint on port 9000, assert onboarding fails with actionable error about port not in policy.
PRA-17 Required tests test/e2e/live/inference-routing.test.ts:123 Add TC-INF-12 test: start fake server on 10.0.0.5:8000, onboard with localhost:8000, assert sandbox inference fails with network policy denial.
PRA-18 Required tests test/e2e/live/inference-routing.test.ts:123 Add TC-INF-13 test: mock DNS failure for host.openshell.internal during onboarding, assert actionable error or fail-closed behavior. Also test recovery path with reuseGatewayCredentialWithoutLocalKey.
PRA-19 Required tests test/e2e/live/inference-routing.test.ts:123 Add TC-INF-14 test: start fake server on 127.0.0.1:8000 only, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
PRA-20 Required tests src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.test.ts:1 Add unit test: mock OpenShell version <0.0.72, call setupRemoteProviderInference with localhost endpoint, assert rewrite skipped or actionable error. Add integration test for older OpenShell version.

🚨 Required before merge

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

PRA-1 Required — Gateway rewrite depends on OpenShell bridge DNS without health check or fail-closed behavior

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:27
  • Category: architecture
  • Problem: Function gatewayReachableCompatibleEndpointUrl() rewrites loopback URLs to host.openshell.internal:<port> but performs no DNS resolution check, TCP probe, or reachability validation before registering the gateway route. Onboarding validates the host URL and succeeds, yet sandbox inference fails silently until $$nemoclaw status is run.
  • Impact: Users complete onboarding with apparently working config but have non-functional inference. DNS poisoning or bridge unavailability leads to silent sandbox inference failure with no actionable error at onboarding time.
  • Required action: Add lightweight bridge reachability check (DNS resolution + TCP probe to host.openshell.internal:port) during gateway registration with actionable error, or add regression test simulating DNS failure proving fail-closed behavior and document removal condition (when OpenShell exposes bridge health endpoint).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read compatible-endpoint-gateway-route.ts lines 27-55; confirm no DNS/TCP probe before rewrite. Check test/compatible-endpoint-gateway-route.test.ts for DNS failure test case.
  • Missing regression test: Unit test: mock DNS resolution failure for host.openshell.internal, call gatewayReachableCompatibleEndpointUrl, assert actionable error or fail-closed behavior. Integration test: simulate bridge DNS failure during onboarding, assert onboarding fails with clear error.
  • Done when: The required change is committed and verification passes: Read compatible-endpoint-gateway-route.ts lines 27-55; confirm no DNS/TCP probe before rewrite. Check test/compatible-endpoint-gateway-route.test.ts for DNS failure test case.
  • Evidence: compatible-endpoint-gateway-route.ts:27-55 shows rewrite without reachability check test/compatible-endpoint-gateway-route.test.ts has no DNS failure test case Previous advisor PRA-1 identified same issue at same location

PRA-2 Required — reuseRegisteredProviderWithGatewayEndpoint fetches provider then updates without atomic compare-and-set

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:61
  • Category: architecture
  • Problem: Function calls runOpenshell(['provider', 'get']) then upsertProvider() without atomic compare-and-set or retry logic. Concurrent modification between get and update can lose updates or corrupt provider config.
  • Impact: Concurrent onboarding/recovery operations can cause lost updates, stale gateway endpoints, or provider config corruption. No test covers concurrent modification scenario.
  • Required action: Add retry logic with exponential backoff for provider update, or accept that upsertProvider handles missing provider gracefully. Add test for concurrent modification.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read compatible-endpoint-gateway-route.ts lines 61-80; confirm get-then-update pattern without CAS. Check test/onboard-inference-gateway-scope.test.ts for concurrent modification test.
  • Missing regression test: Unit test: simulate concurrent provider get/update calls, assert idempotent result or proper retry. Integration test: run parallel onboarding for same provider, assert no lost updates.
  • Done when: The required change is committed and verification passes: Read compatible-endpoint-gateway-route.ts lines 61-80; confirm get-then-update pattern without CAS. Check test/onboard-inference-gateway-scope.test.ts for concurrent modification test.
  • Evidence: compatible-endpoint-gateway-route.ts:61-80 shows get-then-update without CAS Previous advisor PRA-2 identified same issue at same location

PRA-6 Required — Issue #5744 fix only works on specific OpenShell versions/topologies — no version guard

  • Location: src/lib/onboard/inference-providers/remote.ts:167
  • Category: acceptance
  • Problem: Issue comment confirms the localhost→host.openshell.internal rewrite only changes reachability on OpenShell ≥0.0.72 (docker-driver topology change). The code applies rewrite unconditionally without OpenShell version detection or conditional logic. On older versions, rewrite is inert but onboarding still succeeds, leaving user with non-functional inference.
  • Impact: Users on OpenShell <0.0.72 complete onboarding successfully but sandbox inference fails with 503. No actionable error or version check guides them to upgrade OpenShell or use host.openshell.internal directly.
  • Required action: Add OpenShell version detection and conditional rewrite, or document minimum OpenShell version requirement and validate server bind address during onboarding. Add regression test for version-gated behavior.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read remote.ts and compatible-endpoint-gateway-route.ts; confirm no OpenShell version check before rewrite. Check test/onboard-inference-gateway-scope.test.ts for version-gated test case.
  • Missing regression test: Unit test: mock OpenShell version <0.0.72, call setupRemoteProviderInference with localhost endpoint, assert rewrite skipped or actionable error. Integration test: onboard on older OpenShell, assert clear version requirement error.
  • Done when: The required change is committed and verification passes: Read remote.ts and compatible-endpoint-gateway-route.ts; confirm no OpenShell version check before rewrite. Check test/onboard-inference-gateway-scope.test.ts for version-gated test case.
  • Evidence: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment: rewrite inert on OpenShell 0.0.44, works on 0.0.72 compatible-endpoint-gateway-route.ts:27-55 applies rewrite unconditionally remote.ts:167 uses gatewayReachableCompatibleEndpointUrl without version check Previous advisor PRA-6 identified same issue at remote.ts:167

PRA-7 Required — Gateway routes use --no-verify skipping inference verification with no runtime probe

  • Location: src/lib/onboard/inference-providers/remote.ts:222
  • Category: correctness
  • Problem: When gatewayEndpointUrl !== resolvedEndpointUrl (i.e., rewrite occurred), onboarding adds --no-verify flag and skips host-side verification. No post-onboarding sandbox verification probe confirms the rewritten route actually works.
  • Impact: Onboarding reports success even if sandbox cannot reach host.openshell.internal (DNS failure, bridge down, wrong port). User discovers broken inference only when running agent.
  • Required action: Add post-onboarding sandbox verification probe for gateway routes (e.g., lightweight inference.local call) before reporting onboarding success, or document that --no-verify means user must run $$nemoclaw status.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read remote.ts lines 205-210; confirm --no-verify when rewrite occurs. Check test/e2e/live/inference-routing.test.ts for post-onboarding sandbox probe test.
  • Missing regression test: Integration test: onboard with gateway rewrite, mock bridge DNS failure, assert onboarding fails or reports sandbox unreachability before success. Or document that --no-verify requires user to run $$nemoclaw status.
  • Done when: The required change is committed and verification passes: Read remote.ts lines 205-210; confirm --no-verify when rewrite occurs. Check test/e2e/live/inference-routing.test.ts for post-onboarding sandbox probe test.
  • Evidence: remote.ts:205-210 adds --no-verify when gatewayEndpointUrl !== resolvedEndpointUrl Comment acknowledges 'Host-side verification cannot resolve the sandbox-only bridge URL' No sandbox probe after onboarding success Previous advisor PRA-8 and PRA-19 identified same issue

PRA-13 Required — Broad private CIDR allowlist in local-inference network policy permits unintended egress

  • Location: nemoclaw-blueprint/policies/presets/local-inference.yaml:1
  • Category: security
  • Problem: The local-inference policy preset allows egress to 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 for host.openshell.internal endpoints on ports 11434, 11435, 8000. This permits sandbox access to any private IP in those ranges if DNS resolves host.openshell.internal to an unexpected address, enabling SSRF bypass and unintended private network access.
  • Impact: Sandbox can reach arbitrary private IPs on allowed ports if DNS is poisoned or OpenShell bridge misconfigured. Violates least-privilege network policy. No negative test verifies denial of non-loopback private IP egress.
  • Required action: Narrow allowed_ips to OpenShell bridge subnet only (e.g., 172.17.0.0/16 for Docker bridge). Add negative test: attempt egress to 10.0.0.5:8000, assert denial. Document rationale for CIDR breadth if narrowing not feasible.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read nemoclaw-blueprint/policies/presets/local-inference.yaml lines 10-12, 21-23, 32-34. Check test/e2e/live/inference-routing.test.ts for negative network policy test.
  • Missing regression test: Integration test: configure fake server on non-loopback private IP (10.0.0.5:8000), onboard with localhost rewrite, assert sandbox inference fails with network policy denial.
  • Done when: The required change is committed and verification passes: Read nemoclaw-blueprint/policies/presets/local-inference.yaml lines 10-12, 21-23, 32-34. Check test/e2e/live/inference-routing.test.ts for negative network policy test.
  • Evidence: local-inference.yaml allows 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 for host.openshell.internal endpoints No negative test in inference-routing.test.ts for non-loopback private IP egress Previous advisor PRA-14 identified same issue

PRA-14 Required — Missing negative security tests for network policy denial, private IP egress, DNS failure, and loopback-only bind

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: security
  • Problem: E2E test suite validates happy-path gateway routing but lacks negative test cases for: (TC-INF-11) non-policy port 9000 → onboarding failure, (TC-INF-12) non-loopback private IP 10.0.0.5:8000 → no rewrite/denial, (TC-INF-13) mock DNS failure for host.openshell.internal → actionable error, (TC-INF-14) 127.0.0.1-only bind → 503 with bind guidance. Security invariants untested.
  • Impact: Network policy enforcement, SSRF defenses, DNS failure handling, and bind-address requirements have no automated regression coverage. Regressions in these critical trust boundaries will not be caught.
  • Required action: Add four negative test cases to inference-routing.test.ts covering the above scenarios. Verify network-policy job exercises these denials.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read test/e2e/live/inference-routing.test.ts around line 123 (TC-INF-10). Search for TC-INF-11 through TC-INF-14. Check test/e2e/support/ for network policy test helpers.
  • Missing regression test: TC-INF-11: onboard with endpoint on port 9000, assert failure. TC-INF-12: fake server on 10.0.0.5:8000, onboard with localhost, assert denial. TC-INF-13: mock DNS failure for host.openshell.internal, assert actionable error. TC-INF-14: fake server on 127.0.0.1:8000 only, onboard, assert 503 with bind guidance.
  • Done when: The required change is committed and verification passes: Read test/e2e/live/inference-routing.test.ts around line 123 (TC-INF-10). Search for TC-INF-11 through TC-INF-14. Check test/e2e/support/ for network policy test helpers.
  • Evidence: test/e2e/live/inference-routing.test.ts has TC-INF-10 (DNS-backed HTTPS fail-closed) but no TC-INF-11 through TC-INF-14 Previous advisor PRA-12 and PRA-16 required these negative tests Risk plan inference-policy invariant: 'network policy permits intended route and denies unintended egress' untested

PRA-16 Required — Missing negative test: network policy denial for non-policy port (TC-INF-11)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Risk-plan inference-policy invariant requires 'network policy permits the intended route and denies unintended egress'. No test validates onboarding failure when endpoint uses non-policy port (e.g., 9000).
  • Impact: Regression in network policy enforcement for gateway routes would not be caught. Users could onboard endpoints on arbitrary ports bypassing policy.
  • Required action: Add TC-INF-11 test: onboard with endpoint on port 9000, assert onboarding fails with actionable error about port not in policy.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-11. Verify network-policy job exercises port denial.
  • Missing regression test: TC-INF-11: onboard with NEMOCLAW_ENDPOINT_URL=http://localhost:9000/v1, assert onboarding fails with port policy error.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-11. Verify network-policy job exercises port denial.
  • Evidence: Risk plan inference-policy invariant 3: 'network policy permits the intended route and denies unintended egress' test/e2e/live/inference-routing.test.ts has TC-INF-10 but no TC-INF-11 through TC-INF-14 Previous advisor PRA-12 and PRA-16 required this test

PRA-17 Required — Missing negative test: private IP egress denial (TC-INF-12)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Risk-plan inference-policy invariant requires 'network policy denies unintended egress'. No test validates denial when fake server runs on non-loopback private IP (10.0.0.5:8000) and onboarding attempts localhost rewrite.
  • Impact: Combined with broad CIDR allowlist (security F-014), SSRF to private networks would not be caught by regression tests.
  • Required action: Add TC-INF-12 test: start fake server on 10.0.0.5:8000, onboard with localhost:8000, assert sandbox inference fails with network policy denial.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-12. Verify network-policy job exercises private IP egress denial.
  • Missing regression test: TC-INF-12: fake server on 10.0.0.5:8000, onboard with localhost:8000, assert denial.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-12. Verify network-policy job exercises private IP egress denial.
  • Evidence: local-inference.yaml allows 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 No test for non-loopback private IP egress denial Security finding F-014: broad CIDR allowlist amplifies risk

PRA-18 Required — Missing negative test: bridge DNS failure for host.openshell.internal (TC-INF-13)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Gateway rewrite depends on host.openshell.internal DNS resolution without verification. No test simulates DNS failure during onboarding or recovery, despite risk-plan invariant 'the selected provider is reachable through the route advertised to the agent' and security findings F-001, F-015.
  • Impact: DNS poisoning or bridge unavailability leads to silent onboarding success but runtime inference failure. No regression coverage for this critical trust boundary.
  • Required action: Add TC-INF-13 test: mock DNS failure for host.openshell.internal during onboarding, assert actionable error or fail-closed behavior. Also test recovery path with reuseGatewayCredentialWithoutLocalKey.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-13. Check test/onboard-inference-gateway-scope.test.ts for recovery DNS failure test.
  • Missing regression test: TC-INF-13: mock DNS resolution failure for host.openshell.internal, onboard with localhost endpoint, assert actionable error. Recovery variant: simulate DNS failure during provider recovery with reuseGatewayCredentialWithoutLocalKey.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-13. Check test/onboard-inference-gateway-scope.test.ts for recovery DNS failure test.
  • Evidence: compatible-endpoint-gateway-route.ts:27-55 rewrites to host.openshell.internal without DNS/TCP probe Risk plan inference-policy invariant 1: 'the selected provider is reachable through the route advertised to the agent' Security findings F-001, F-015: DNS trust without verification enables SSRF Previous advisor PRA-1, PRA-10, PRA-15 required this test

PRA-19 Required — Missing negative test: loopback-only bind causes 503 with bind guidance (TC-INF-14)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 and documentation confirm server must bind 0.0.0.0, not 127.0.0.1 only. Onboarding validates host URL but not server bind address. No test validates 503 with actionable bind-address error.
  • Impact: User binds vLLM to 127.0.0.1 (common default), onboarding succeeds, inference fails with generic 503. No actionable guidance at onboarding time.
  • Required action: Add TC-INF-14 test: start fake server on 127.0.0.1:8000 only, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-14. Check docs/inference/set-up-openai-compatible-endpoint.mdx for bind guidance.
  • Missing regression test: TC-INF-14: fake server on 127.0.0.1:8000 only, onboard with localhost:8000, assert 503 with bind guidance error.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-14. Check docs/inference/set-up-openai-compatible-endpoint.mdx for bind guidance.
  • Evidence: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment: loopback-only bind causes 503 regardless of URL rewrite set-up-openai-compatible-endpoint.mdx:25-35 warns about 0.0.0.0 bind but no enforcement Previous advisor PRA-5 and PRA-7 required this test Acceptance finding F-010, security finding F-018

PRA-20 Required — Missing unit test: OpenShell version gating for gateway rewrite

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.test.ts:1
  • Category: tests
  • Problem: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 confirms rewrite only changes reachability on OpenShell ≥0.0.72. Code applies rewrite unconditionally. No test validates version-gated behavior or documents minimum version.
  • Impact: Users on OpenShell <0.0.72 complete onboarding successfully but inference fails with 503. No regression test for version-dependent behavior.
  • Required action: Add unit test: mock OpenShell version <0.0.72, call setupRemoteProviderInference with localhost endpoint, assert rewrite skipped or actionable error. Add integration test for older OpenShell version.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read test/onboard-inference-gateway-scope.test.ts and compatible-endpoint-gateway-route.test.ts for version-gated test case.
  • Missing regression test: Unit test: mock OpenShell version 0.0.44, call gatewayReachableCompatibleEndpointUrl, assert no rewrite or version error. Integration test: onboard on older OpenShell, assert clear version requirement error.
  • Done when: The required change is committed and verification passes: Read test/onboard-inference-gateway-scope.test.ts and compatible-endpoint-gateway-route.test.ts for version-gated test case.
  • Evidence: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment: rewrite inert on OpenShell 0.0.44, works on 0.0.72 compatible-endpoint-gateway-route.ts:27-55 applies rewrite unconditionally remote.ts:167 uses gatewayReachableCompatibleEndpointUrl without version check Acceptance finding F-006

PRA-21 Required — Missing integration test: post-onboarding sandbox verification probe for gateway routes

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: When rewrite occurs, onboarding adds --no-verify and skips host-side verification. No post-onboarding sandbox probe confirms rewritten route works. Risk-plan invariant 'health reflects a real request rather than configuration presence' untested for gateway routes.
  • Impact: Onboarding reports success even if sandbox cannot reach host.openshell.internal (DNS failure, bridge down, wrong port). User discovers broken inference only when running agent.
  • Required action: Add integration test: onboard with gateway rewrite, mock bridge DNS failure, assert onboarding fails or reports sandbox unreachability before success. Or document that --no-verify requires user to run $$nemoclaw status.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read remote.ts lines 205-210 for --no-verify logic. Check test/e2e/live/inference-routing.test.ts for post-onboarding sandbox probe.
  • Missing regression test: Integration test: onboard with gateway rewrite, mock bridge DNS failure, assert onboarding fails or reports sandbox unreachability before success.
  • Done when: The required change is committed and verification passes: Read remote.ts lines 205-210 for --no-verify logic. Check test/e2e/live/inference-routing.test.ts for post-onboarding sandbox probe.
  • Evidence: remote.ts:205-210 adds --no-verify when gatewayEndpointUrl !== resolvedEndpointUrl Comment: 'Host-side verification cannot resolve the sandbox-only bridge URL' No sandbox probe after onboarding success Correctness finding F-007, previous advisor PRA-8 and PRA-19
Review findings by urgency: 12 required fixes, 8 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-3 Resolve/justify — Silent URL parse catch returns original endpoint on malformed input without error propagation

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:33
  • Category: architecture
  • Problem: Try/catch around new URL(endpointUrl) silently returns the original endpointUrl on parse failure. Malformed URLs proceed without validation error, masking config problems.
  • Impact: User enters malformed URL (e.g., missing scheme, invalid hostname) — onboarding proceeds with invalid config, fails later at runtime with confusing error.
  • Recommended action: Add structured error return (Result type) or at minimum a debug log in catch block. Caller remote.ts should handle parse error with actionable feedback rather than proceeding with potentially invalid URL.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read compatible-endpoint-gateway-route.ts line 33 catch block; confirm silent return. Check test/compatible-endpoint-gateway-route.test.ts for malformed URL test asserting error.
  • Missing regression test: Unit test: call gatewayReachableCompatibleEndpointUrl with malformed URLs (e.g., 'not-a-url', 'http://', 'http://:8000'), assert structured error or warning logged.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read compatible-endpoint-gateway-route.ts line 33 catch block; confirm silent return. Check test/compatible-endpoint-gateway-route.test.ts for malformed URL test asserting error.
  • Evidence: compatible-endpoint-gateway-route.ts:33 catch { return endpointUrl; } test/compatible-endpoint-gateway-route.test.ts 'unchanged' cases include 'not a URL' but assert unchanged return, not error Previous advisor PRA-3 and PRA-11 identified same issue

PRA-4 Resolve/justify — Workflow trusted-code boundary expanded: dockerhub-auth added to inference-routing job

  • Location: .github/workflows/e2e.yaml:1039
  • Category: architecture
  • Problem: The inference-routing job now includes the dockerhub-auth step and cleanup, but the test dockerhub-auth-workflow-boundary.test.ts excludes inference-routing from NO_IMAGE_E2E_JOBS without justification. The job may not require Docker Hub images.
  • Impact: Unnecessary credential scope expansion increases blast radius if Docker Hub token is compromised. Violates principle of least privilege for workflow jobs.
  • Recommended action: Remove dockerhub-auth from inference-routing job unless tests actually require Docker Hub images. If kept, add justification comment and verify dockerhub-auth-workflow-boundary.test.ts asserts minimal required scope.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check .github/workflows/e2e.yaml inference-routing job steps for dockerhub-auth. Check test/e2e/support/dockerhub-auth-workflow-boundary.test.ts NO_IMAGE_E2E_JOBS list.
  • Missing regression test: Workflow boundary test: assert inference-routing job does not contain dockerhub-auth step unless a documented justification exists in code.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check .github/workflows/e2e.yaml inference-routing job steps for dockerhub-auth. Check test/e2e/support/dockerhub-auth-workflow-boundary.test.ts NO_IMAGE_E2E_JOBS list.
  • Evidence: .github/workflows/e2e.yaml:1039 shows dockerhub-auth in inference-routing job test/e2e/support/dockerhub-auth-workflow-boundary.test.ts:10 NO_IMAGE_E2E_JOBS no longer includes 'inference-routing' Previous advisor PRA-13 identified same issue

PRA-5 Resolve/justify — Mock parity mapping for inference-routing live test expanded without clear justification

  • Location: test/e2e/mock-parity.json:7
  • Category: scope
  • Problem: mock-parity.json now maps inference-routing live test to three fast tests (compatible-endpoint-gateway-route.test.ts, hosted-inference.test.ts, onboard-inference-gateway-scope.test.ts) without documenting which distinct invariants each covers. Risk of overlapping or missing coverage.
  • Impact: Fast test suite may not adequately cover live test invariants, or may duplicate coverage. CI fast path could pass while live test fails on uncovered scenarios.
  • Recommended action: Document in PR or code comment why each of the three fast tests is necessary for inference-routing parity. Verify each covers distinct, non-overlapping invariants that the live test exercises.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/e2e/mock-parity.json entries for inference-routing. Check each fast test file for explicit invariant coverage comments.
  • Missing regression test: Meta-test: validate mock-parity.json mapping completeness — each live test invariant has at least one fast test, no fast test maps to multiple live tests without justification.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/e2e/mock-parity.json entries for inference-routing. Check each fast test file for explicit invariant coverage comments.
  • Evidence: test/e2e/mock-parity.json lines 7-12 show three fast tests for inference-routing None of the three fast test files have comments mapping to specific live test invariants Previous advisor PRA-4 and PRA-18 identified same issue

PRA-8 Resolve/justify — Test/implementation mismatch: double provider get in recovery path test but implementation makes single call

  • Location: test/onboard-inference-gateway-scope.test.ts:70
  • Category: correctness
  • Problem: Test expects two 'provider get' calls in recovery path (lines 70-71 in test output), but reuseRegisteredProviderWithGatewayEndpoint makes only one runOpenshell(['provider', 'get']) call. Test passes because mock returns status 0 on first call, but expectation diverges from implementation.
  • Impact: Test does not accurately verify implementation behavior. If implementation changes to make two calls (e.g., for retry), test would not catch regression. False confidence in test coverage.
  • Recommended action: Align test expectation with implementation (single provider get) or update implementation to match test's idempotency pattern with clear rationale. Add test for concurrent provider modification between get and update.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/onboard-inference-gateway-scope.test.ts lines 100-120; compare expected commands array with reuseRegisteredProviderWithGatewayEndpoint implementation in compatible-endpoint-gateway-route.ts:61-80.
  • Missing regression test: Test: verify exact number of provider get calls in recovery path. Test: concurrent modification scenario with retry logic.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/onboard-inference-gateway-scope.test.ts lines 100-120; compare expected commands array with reuseRegisteredProviderWithGatewayEndpoint implementation in compatible-endpoint-gateway-route.ts:61-80.
  • Evidence: test/onboard-inference-gateway-scope.test.ts:108-112 expects two 'provider get -g nemoclaw-9090 compatible-endpoint' commands compatible-endpoint-gateway-route.ts:65-68 makes single runOpenshell(['provider', 'get']) call Previous advisor PRA-9 identified same mismatch

PRA-9 Resolve/justify — Bridge rewrite workaround in recovery path missing regression test and removal trigger

  • Location: docs/security/openclaw-2026.6.10-dependency-review.md:195
  • Category: acceptance
  • Problem: Documentation describes bridge rewrite as workaround with removal condition 'when OpenShell exposes bridge health endpoint'. No regression test simulates host.openshell.internal DNS failure during provider recovery. No version-check test flags when OpenShell bridge health endpoint becomes available.
  • Impact: Workaround persists indefinitely without detection. If OpenShell adds bridge health endpoint, NemoClaw continues using DNS-based rewrite without leveraging improved API. DNS failure mode untested in recovery path.
  • Recommended action: Add regression test simulating host.openshell.internal DNS failure during provider recovery. Add version-check test that flags when OpenShell bridge health endpoint becomes available. Document removal condition in code, not just docs.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read docs/security/openclaw-2026.6.10-dependency-review.md lines 195-211. Check test/onboard-inference-gateway-scope.test.ts and test/e2e/live/inference-routing.test.ts for DNS failure test in recovery path.
  • Missing regression test: Integration test: simulate DNS failure for host.openshell.internal during provider recovery with reuseGatewayCredentialWithoutLocalKey, assert actionable error or fail-closed. Unit test: check OpenShell version for bridge health endpoint availability.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read docs/security/openclaw-2026.6.10-dependency-review.md lines 195-211. Check test/onboard-inference-gateway-scope.test.ts and test/e2e/live/inference-routing.test.ts for DNS failure test in recovery path.
  • Evidence: docs/security/openclaw-2026.6.10-dependency-review.md:195-211 describes workaround with removal condition but no test references test/onboard-inference-gateway-scope.test.ts recovery test does not simulate DNS failure Previous advisor PRA-10 identified same issue

PRA-10 Resolve/justify — Documentation weakens bind guidance to 0.0.0.0 with warning but no enforcement

  • Location: docs/inference/set-up-openai-compatible-endpoint.mdx:25
  • Category: docs
  • Problem: Docs warn 'use a host firewall with default-deny inbound rules' and 'server must listen on 0.0.0.0' but onboarding does not validate bind address. User can bind to 127.0.0.1 only, onboarding succeeds, sandbox inference fails with 503.
  • Impact: User follows docs, binds to 0.0.0.0, but if they miss the warning or use a server that defaults to 127.0.0.1, onboarding succeeds silently and inference fails at runtime with no actionable error.
  • Recommended action: Add onboarding-time validation that local server is reachable from sandbox network context, or at minimum validate binding address is not 0.0.0.0 without explicit firewall confirmation. Document removal condition for bridge DNS dependency.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Missing regression test: Integration test: start fake server on 127.0.0.1:8000, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Evidence: set-up-openai-compatible-endpoint.mdx:25-35 warns about 0.0.0.0 bind and firewall remote.ts onboarding validates host URL but not server bind address Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment confirms loopback-only bind causes 503 regardless of URL rewrite Previous advisor PRA-5 identified same issue

PRA-15 Resolve/justify — Documentation warns about 0.0.0.0 bind requirement but onboarding does not enforce or validate

  • Location: docs/inference/set-up-openai-compatible-endpoint.mdx:25
  • Category: security
  • Problem: Docs state server must listen on 0.0.0.0 and warn about firewall rules, but onboarding validates only host URL reachability, not server bind address. User can bind to 127.0.0.1 only; onboarding succeeds, sandbox inference fails with 503.
  • Impact: Documentation-only mitigation for critical reachability requirement. User follows docs but misses bind-address nuance, onboarding reports success, inference fails at runtime with no actionable error about bind address.
  • Recommended action: Add onboarding-time validation that local server is reachable from sandbox network context (e.g., probe from container network), or at minimum validate binding address is not 127.0.0.1 without explicit confirmation. Document removal condition for bridge DNS dependency.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Missing regression test: Integration test: start fake server on 127.0.0.1:8000, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Evidence: set-up-openai-compatible-endpoint.mdx:25-35 warns about 0.0.0.0 bind and firewall remote.ts onboarding validates host URL but not server bind address Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment confirms loopback-only bind causes 503 regardless of URL rewrite Previous advisor PRA-5 identified same issue

PRA-22 Resolve/justify — Missing test: concurrent provider modification between get and update

  • Location: test/onboard-inference-gateway-scope.test.ts:70
  • Category: tests
  • Problem: reuseRegisteredProviderWithGatewayEndpoint makes get-then-update without CAS or retry. No test covers concurrent modification scenario. Architecture finding F-002 identifies this as lost-update/corruption risk.
  • Impact: Concurrent onboarding/recovery operations can cause lost updates, stale gateway endpoints, or provider config corruption.
  • Recommended action: Add test for concurrent provider modification: simulate parallel get/update calls, assert idempotent result or proper retry with exponential backoff.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read compatible-endpoint-gateway-route.ts:61-80 for get-then-update pattern. Check test/onboard-inference-gateway-scope.test.ts for concurrent modification test.
  • Missing regression test: Unit test: simulate concurrent provider get/update calls, assert idempotent result or proper retry. Integration test: run parallel onboarding for same provider, assert no lost updates.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read compatible-endpoint-gateway-route.ts:61-80 for get-then-update pattern. Check test/onboard-inference-gateway-scope.test.ts for concurrent modification test.
  • Evidence: compatible-endpoint-gateway-route.ts:61-80 shows get-then-update without CAS Architecture finding F-002: concurrent modification risk Previous advisor PRA-2

💡 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-11 Improvement — Dual-source inconsistency: gatewayEndpointUrl computed twice in recovery path

  • Location: src/lib/onboard/inference-providers/remote.ts:173
  • Category: correctness
  • Problem: remote.ts:173 computes gatewayEndpointUrl = gatewayReachableCompatibleEndpointUrl(provider, resolvedEndpointUrl). Then reuseRegisteredProviderWithGatewayEndpoint receives both endpointUrl (original) and gatewayEndpointUrl (rewritten) and recomputes rewrite logic internally. Two code paths for same transformation.
  • Impact: If rewrite logic changes in one place but not the other, recovery and initial onboarding diverge. Increases maintenance burden and bug surface.
  • Suggested action: Centralize rewrite logic: have reuseRegisteredProviderWithGatewayEndpoint compute gatewayEndpointUrl internally, or pass only resolvedEndpointUrl and let it derive both. Ensure single source of truth.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read remote.ts:173 and compatible-endpoint-gateway-route.ts:75-78. Compare rewrite logic in both locations.
  • Missing regression test: Unit test: verify gatewayReachableCompatibleEndpointUrl and reuseRegisteredProviderWithGatewayEndpoint produce identical gatewayEndpointUrl for same input.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: remote.ts:173 computes gatewayEndpointUrl before calling reuseRegisteredProviderWithGatewayEndpoint compatible-endpoint-gateway-route.ts:75-78 recomputes rewrite internally using same BUNDLED_LOCAL_INFERENCE_GATEWAY_PORT_SET Both use same constant but logic duplicated

PRA-12 Improvement — BUNDLED_LOCAL_INFERENCE_GATEWAY_PORTS duplicated in code and policy YAML

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:7
  • Category: architecture
  • Problem: Port list [11434, 11435, 8000] defined in TypeScript constant and in nemoclaw-blueprint/policies/presets/local-inference.yaml. Test asserts alignment but duplication creates drift risk.
  • Impact: Policy YAML update without code update (or vice versa) causes silent mismatch. Test catches drift but only at test time.
  • Suggested action: Consider single source of truth: generate TypeScript constant from policy YAML at build time, or import policy YAML in test only. Keep as-is if build complexity not justified.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read compatible-endpoint-gateway-route.ts line 7 and nemoclaw-blueprint/policies/presets/local-inference.yaml. Check test/compatible-endpoint-gateway-route.test.ts:18-27 for alignment test.
  • Missing regression test: Build-time test: assert TypeScript constant matches policy YAML ports. Already covered by compatible-endpoint-gateway-route.test.ts:18-27.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: compatible-endpoint-gateway-route.ts:7 exports BUNDLED_LOCAL_INFERENCE_GATEWAY_PORTS = [11434, 11435, 8000] nemoclaw-blueprint/policies/presets/local-inference.yaml has three endpoints with ports 11434, 11435, 8000 test/compatible-endpoint-gateway-route.test.ts:18-27 asserts alignment
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 — Run the `cloud-onboard` E2E job for Installer and platform changes must work on a clean supported host with the pinned runtime dependencies. Matched files: `.github/workflows/e2e.yaml`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Deterministic regression risks require live validation: lifecycle-state (partial failure/retry convergence, status↔probed gateway agreement), inference-policy (provider reachable via advertised route, health=real request, network policy permits/denies), platform-install (clean host installs pinned deps). Checked-in unit/mocked tests cover rewrite logic and happy-path E2E but lack negative tests for all 4 critical security invariants (policy denial, private IP egress, DNS failure, bind address) and version-gated behavior.
  • PRA-T2 Runtime validation — Run the cloud-onboard E2E job for Installer and platform changes must work on a clean supported host with the pinned runtime dependencies. Matched files: .github/workflows/e2e.yaml.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Deterministic regression risks require live validation: lifecycle-state (partial failure/retry convergence, status↔probed gateway agreement), inference-policy (provider reachable via advertised route, health=real request, network policy permits/denies), platform-install (clean host installs pinned deps). Checked-in unit/mocked tests cover rewrite logic and happy-path E2E but lack negative tests for all 4 critical security invariants (policy denial, private IP egress, DNS failure, bind address) and version-gated behavior.
  • PRA-T3 Runtime validation — Run the `inference-routing` E2E job for Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary. Matched files: `src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts`, `src/lib/onboard/inference-providers/remote.ts`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Deterministic regression risks require live validation: lifecycle-state (partial failure/retry convergence, status↔probed gateway agreement), inference-policy (provider reachable via advertised route, health=real request, network policy permits/denies), platform-install (clean host installs pinned deps). Checked-in unit/mocked tests cover rewrite logic and happy-path E2E but lack negative tests for all 4 critical security invariants (policy denial, private IP egress, DNS failure, bind address) and version-gated behavior.
  • PRA-T4 Runtime validation — Run the inference-routing E2E job for Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary. Matched files: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts, src/lib/onboard/inference-providers/remote.ts.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Deterministic regression risks require live validation: lifecycle-state (partial failure/retry convergence, status↔probed gateway agreement), inference-policy (provider reachable via advertised route, health=real request, network policy permits/denies), platform-install (clean host installs pinned deps). Checked-in unit/mocked tests cover rewrite logic and happy-path E2E but lack negative tests for all 4 critical security invariants (policy denial, private IP egress, DNS failure, bind address) and version-gated behavior.
  • PRA-T5 Runtime validation — Run the `network-policy` E2E job for Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary. Matched files: `src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts`, `src/lib/onboard/inference-providers/remote.ts`.. Deterministic regression risks require live validation: lifecycle-state, inference-policy, platform-install. Deterministic regression risks require live validation: lifecycle-state (partial failure/retry convergence, status↔probed gateway agreement), inference-policy (provider reachable via advertised route, health=real request, network policy permits/denies), platform-install (clean host installs pinned deps). Checked-in unit/mocked tests cover rewrite logic and happy-path E2E but lack negative tests for all 4 critical security invariants (policy denial, private IP egress, DNS failure, bind address) and version-gated behavior.
  • PRA-T6 Missing negative test: network policy denial for non-policy port (TC-INF-11) — Add TC-INF-11 test: onboard with endpoint on port 9000, assert onboarding fails with actionable error about port not in policy.
  • PRA-T7 Missing negative test: private IP egress denial (TC-INF-12) — Add TC-INF-12 test: start fake server on 10.0.0.5:8000, onboard with localhost:8000, assert sandbox inference fails with network policy denial.
  • PRA-T8 Missing negative test: bridge DNS failure for host.openshell.internal (TC-INF-13) — Add TC-INF-13 test: mock DNS failure for host.openshell.internal during onboarding, assert actionable error or fail-closed behavior. Also test recovery path with reuseGatewayCredentialWithoutLocalKey.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Required — Gateway rewrite depends on OpenShell bridge DNS without health check or fail-closed behavior

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:27
  • Category: architecture
  • Problem: Function gatewayReachableCompatibleEndpointUrl() rewrites loopback URLs to host.openshell.internal:<port> but performs no DNS resolution check, TCP probe, or reachability validation before registering the gateway route. Onboarding validates the host URL and succeeds, yet sandbox inference fails silently until $$nemoclaw status is run.
  • Impact: Users complete onboarding with apparently working config but have non-functional inference. DNS poisoning or bridge unavailability leads to silent sandbox inference failure with no actionable error at onboarding time.
  • Required action: Add lightweight bridge reachability check (DNS resolution + TCP probe to host.openshell.internal:port) during gateway registration with actionable error, or add regression test simulating DNS failure proving fail-closed behavior and document removal condition (when OpenShell exposes bridge health endpoint).
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read compatible-endpoint-gateway-route.ts lines 27-55; confirm no DNS/TCP probe before rewrite. Check test/compatible-endpoint-gateway-route.test.ts for DNS failure test case.
  • Missing regression test: Unit test: mock DNS resolution failure for host.openshell.internal, call gatewayReachableCompatibleEndpointUrl, assert actionable error or fail-closed behavior. Integration test: simulate bridge DNS failure during onboarding, assert onboarding fails with clear error.
  • Done when: The required change is committed and verification passes: Read compatible-endpoint-gateway-route.ts lines 27-55; confirm no DNS/TCP probe before rewrite. Check test/compatible-endpoint-gateway-route.test.ts for DNS failure test case.
  • Evidence: compatible-endpoint-gateway-route.ts:27-55 shows rewrite without reachability check test/compatible-endpoint-gateway-route.test.ts has no DNS failure test case Previous advisor PRA-1 identified same issue at same location

PRA-2 Required — reuseRegisteredProviderWithGatewayEndpoint fetches provider then updates without atomic compare-and-set

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:61
  • Category: architecture
  • Problem: Function calls runOpenshell(['provider', 'get']) then upsertProvider() without atomic compare-and-set or retry logic. Concurrent modification between get and update can lose updates or corrupt provider config.
  • Impact: Concurrent onboarding/recovery operations can cause lost updates, stale gateway endpoints, or provider config corruption. No test covers concurrent modification scenario.
  • Required action: Add retry logic with exponential backoff for provider update, or accept that upsertProvider handles missing provider gracefully. Add test for concurrent modification.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read compatible-endpoint-gateway-route.ts lines 61-80; confirm get-then-update pattern without CAS. Check test/onboard-inference-gateway-scope.test.ts for concurrent modification test.
  • Missing regression test: Unit test: simulate concurrent provider get/update calls, assert idempotent result or proper retry. Integration test: run parallel onboarding for same provider, assert no lost updates.
  • Done when: The required change is committed and verification passes: Read compatible-endpoint-gateway-route.ts lines 61-80; confirm get-then-update pattern without CAS. Check test/onboard-inference-gateway-scope.test.ts for concurrent modification test.
  • Evidence: compatible-endpoint-gateway-route.ts:61-80 shows get-then-update without CAS Previous advisor PRA-2 identified same issue at same location

PRA-3 Resolve/justify — Silent URL parse catch returns original endpoint on malformed input without error propagation

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:33
  • Category: architecture
  • Problem: Try/catch around new URL(endpointUrl) silently returns the original endpointUrl on parse failure. Malformed URLs proceed without validation error, masking config problems.
  • Impact: User enters malformed URL (e.g., missing scheme, invalid hostname) — onboarding proceeds with invalid config, fails later at runtime with confusing error.
  • Recommended action: Add structured error return (Result type) or at minimum a debug log in catch block. Caller remote.ts should handle parse error with actionable feedback rather than proceeding with potentially invalid URL.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read compatible-endpoint-gateway-route.ts line 33 catch block; confirm silent return. Check test/compatible-endpoint-gateway-route.test.ts for malformed URL test asserting error.
  • Missing regression test: Unit test: call gatewayReachableCompatibleEndpointUrl with malformed URLs (e.g., 'not-a-url', 'http://', 'http://:8000'), assert structured error or warning logged.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read compatible-endpoint-gateway-route.ts line 33 catch block; confirm silent return. Check test/compatible-endpoint-gateway-route.test.ts for malformed URL test asserting error.
  • Evidence: compatible-endpoint-gateway-route.ts:33 catch { return endpointUrl; } test/compatible-endpoint-gateway-route.test.ts 'unchanged' cases include 'not a URL' but assert unchanged return, not error Previous advisor PRA-3 and PRA-11 identified same issue

PRA-4 Resolve/justify — Workflow trusted-code boundary expanded: dockerhub-auth added to inference-routing job

  • Location: .github/workflows/e2e.yaml:1039
  • Category: architecture
  • Problem: The inference-routing job now includes the dockerhub-auth step and cleanup, but the test dockerhub-auth-workflow-boundary.test.ts excludes inference-routing from NO_IMAGE_E2E_JOBS without justification. The job may not require Docker Hub images.
  • Impact: Unnecessary credential scope expansion increases blast radius if Docker Hub token is compromised. Violates principle of least privilege for workflow jobs.
  • Recommended action: Remove dockerhub-auth from inference-routing job unless tests actually require Docker Hub images. If kept, add justification comment and verify dockerhub-auth-workflow-boundary.test.ts asserts minimal required scope.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check .github/workflows/e2e.yaml inference-routing job steps for dockerhub-auth. Check test/e2e/support/dockerhub-auth-workflow-boundary.test.ts NO_IMAGE_E2E_JOBS list.
  • Missing regression test: Workflow boundary test: assert inference-routing job does not contain dockerhub-auth step unless a documented justification exists in code.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check .github/workflows/e2e.yaml inference-routing job steps for dockerhub-auth. Check test/e2e/support/dockerhub-auth-workflow-boundary.test.ts NO_IMAGE_E2E_JOBS list.
  • Evidence: .github/workflows/e2e.yaml:1039 shows dockerhub-auth in inference-routing job test/e2e/support/dockerhub-auth-workflow-boundary.test.ts:10 NO_IMAGE_E2E_JOBS no longer includes 'inference-routing' Previous advisor PRA-13 identified same issue

PRA-5 Resolve/justify — Mock parity mapping for inference-routing live test expanded without clear justification

  • Location: test/e2e/mock-parity.json:7
  • Category: scope
  • Problem: mock-parity.json now maps inference-routing live test to three fast tests (compatible-endpoint-gateway-route.test.ts, hosted-inference.test.ts, onboard-inference-gateway-scope.test.ts) without documenting which distinct invariants each covers. Risk of overlapping or missing coverage.
  • Impact: Fast test suite may not adequately cover live test invariants, or may duplicate coverage. CI fast path could pass while live test fails on uncovered scenarios.
  • Recommended action: Document in PR or code comment why each of the three fast tests is necessary for inference-routing parity. Verify each covers distinct, non-overlapping invariants that the live test exercises.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/e2e/mock-parity.json entries for inference-routing. Check each fast test file for explicit invariant coverage comments.
  • Missing regression test: Meta-test: validate mock-parity.json mapping completeness — each live test invariant has at least one fast test, no fast test maps to multiple live tests without justification.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/e2e/mock-parity.json entries for inference-routing. Check each fast test file for explicit invariant coverage comments.
  • Evidence: test/e2e/mock-parity.json lines 7-12 show three fast tests for inference-routing None of the three fast test files have comments mapping to specific live test invariants Previous advisor PRA-4 and PRA-18 identified same issue

PRA-6 Required — Issue #5744 fix only works on specific OpenShell versions/topologies — no version guard

  • Location: src/lib/onboard/inference-providers/remote.ts:167
  • Category: acceptance
  • Problem: Issue comment confirms the localhost→host.openshell.internal rewrite only changes reachability on OpenShell ≥0.0.72 (docker-driver topology change). The code applies rewrite unconditionally without OpenShell version detection or conditional logic. On older versions, rewrite is inert but onboarding still succeeds, leaving user with non-functional inference.
  • Impact: Users on OpenShell <0.0.72 complete onboarding successfully but sandbox inference fails with 503. No actionable error or version check guides them to upgrade OpenShell or use host.openshell.internal directly.
  • Required action: Add OpenShell version detection and conditional rewrite, or document minimum OpenShell version requirement and validate server bind address during onboarding. Add regression test for version-gated behavior.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read remote.ts and compatible-endpoint-gateway-route.ts; confirm no OpenShell version check before rewrite. Check test/onboard-inference-gateway-scope.test.ts for version-gated test case.
  • Missing regression test: Unit test: mock OpenShell version <0.0.72, call setupRemoteProviderInference with localhost endpoint, assert rewrite skipped or actionable error. Integration test: onboard on older OpenShell, assert clear version requirement error.
  • Done when: The required change is committed and verification passes: Read remote.ts and compatible-endpoint-gateway-route.ts; confirm no OpenShell version check before rewrite. Check test/onboard-inference-gateway-scope.test.ts for version-gated test case.
  • Evidence: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment: rewrite inert on OpenShell 0.0.44, works on 0.0.72 compatible-endpoint-gateway-route.ts:27-55 applies rewrite unconditionally remote.ts:167 uses gatewayReachableCompatibleEndpointUrl without version check Previous advisor PRA-6 identified same issue at remote.ts:167

PRA-7 Required — Gateway routes use --no-verify skipping inference verification with no runtime probe

  • Location: src/lib/onboard/inference-providers/remote.ts:222
  • Category: correctness
  • Problem: When gatewayEndpointUrl !== resolvedEndpointUrl (i.e., rewrite occurred), onboarding adds --no-verify flag and skips host-side verification. No post-onboarding sandbox verification probe confirms the rewritten route actually works.
  • Impact: Onboarding reports success even if sandbox cannot reach host.openshell.internal (DNS failure, bridge down, wrong port). User discovers broken inference only when running agent.
  • Required action: Add post-onboarding sandbox verification probe for gateway routes (e.g., lightweight inference.local call) before reporting onboarding success, or document that --no-verify means user must run $$nemoclaw status.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read remote.ts lines 205-210; confirm --no-verify when rewrite occurs. Check test/e2e/live/inference-routing.test.ts for post-onboarding sandbox probe test.
  • Missing regression test: Integration test: onboard with gateway rewrite, mock bridge DNS failure, assert onboarding fails or reports sandbox unreachability before success. Or document that --no-verify requires user to run $$nemoclaw status.
  • Done when: The required change is committed and verification passes: Read remote.ts lines 205-210; confirm --no-verify when rewrite occurs. Check test/e2e/live/inference-routing.test.ts for post-onboarding sandbox probe test.
  • Evidence: remote.ts:205-210 adds --no-verify when gatewayEndpointUrl !== resolvedEndpointUrl Comment acknowledges 'Host-side verification cannot resolve the sandbox-only bridge URL' No sandbox probe after onboarding success Previous advisor PRA-8 and PRA-19 identified same issue

PRA-8 Resolve/justify — Test/implementation mismatch: double provider get in recovery path test but implementation makes single call

  • Location: test/onboard-inference-gateway-scope.test.ts:70
  • Category: correctness
  • Problem: Test expects two 'provider get' calls in recovery path (lines 70-71 in test output), but reuseRegisteredProviderWithGatewayEndpoint makes only one runOpenshell(['provider', 'get']) call. Test passes because mock returns status 0 on first call, but expectation diverges from implementation.
  • Impact: Test does not accurately verify implementation behavior. If implementation changes to make two calls (e.g., for retry), test would not catch regression. False confidence in test coverage.
  • Recommended action: Align test expectation with implementation (single provider get) or update implementation to match test's idempotency pattern with clear rationale. Add test for concurrent provider modification between get and update.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read test/onboard-inference-gateway-scope.test.ts lines 100-120; compare expected commands array with reuseRegisteredProviderWithGatewayEndpoint implementation in compatible-endpoint-gateway-route.ts:61-80.
  • Missing regression test: Test: verify exact number of provider get calls in recovery path. Test: concurrent modification scenario with retry logic.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read test/onboard-inference-gateway-scope.test.ts lines 100-120; compare expected commands array with reuseRegisteredProviderWithGatewayEndpoint implementation in compatible-endpoint-gateway-route.ts:61-80.
  • Evidence: test/onboard-inference-gateway-scope.test.ts:108-112 expects two 'provider get -g nemoclaw-9090 compatible-endpoint' commands compatible-endpoint-gateway-route.ts:65-68 makes single runOpenshell(['provider', 'get']) call Previous advisor PRA-9 identified same mismatch

PRA-9 Resolve/justify — Bridge rewrite workaround in recovery path missing regression test and removal trigger

  • Location: docs/security/openclaw-2026.6.10-dependency-review.md:195
  • Category: acceptance
  • Problem: Documentation describes bridge rewrite as workaround with removal condition 'when OpenShell exposes bridge health endpoint'. No regression test simulates host.openshell.internal DNS failure during provider recovery. No version-check test flags when OpenShell bridge health endpoint becomes available.
  • Impact: Workaround persists indefinitely without detection. If OpenShell adds bridge health endpoint, NemoClaw continues using DNS-based rewrite without leveraging improved API. DNS failure mode untested in recovery path.
  • Recommended action: Add regression test simulating host.openshell.internal DNS failure during provider recovery. Add version-check test that flags when OpenShell bridge health endpoint becomes available. Document removal condition in code, not just docs.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read docs/security/openclaw-2026.6.10-dependency-review.md lines 195-211. Check test/onboard-inference-gateway-scope.test.ts and test/e2e/live/inference-routing.test.ts for DNS failure test in recovery path.
  • Missing regression test: Integration test: simulate DNS failure for host.openshell.internal during provider recovery with reuseGatewayCredentialWithoutLocalKey, assert actionable error or fail-closed. Unit test: check OpenShell version for bridge health endpoint availability.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read docs/security/openclaw-2026.6.10-dependency-review.md lines 195-211. Check test/onboard-inference-gateway-scope.test.ts and test/e2e/live/inference-routing.test.ts for DNS failure test in recovery path.
  • Evidence: docs/security/openclaw-2026.6.10-dependency-review.md:195-211 describes workaround with removal condition but no test references test/onboard-inference-gateway-scope.test.ts recovery test does not simulate DNS failure Previous advisor PRA-10 identified same issue

PRA-10 Resolve/justify — Documentation weakens bind guidance to 0.0.0.0 with warning but no enforcement

  • Location: docs/inference/set-up-openai-compatible-endpoint.mdx:25
  • Category: docs
  • Problem: Docs warn 'use a host firewall with default-deny inbound rules' and 'server must listen on 0.0.0.0' but onboarding does not validate bind address. User can bind to 127.0.0.1 only, onboarding succeeds, sandbox inference fails with 503.
  • Impact: User follows docs, binds to 0.0.0.0, but if they miss the warning or use a server that defaults to 127.0.0.1, onboarding succeeds silently and inference fails at runtime with no actionable error.
  • Recommended action: Add onboarding-time validation that local server is reachable from sandbox network context, or at minimum validate binding address is not 0.0.0.0 without explicit firewall confirmation. Document removal condition for bridge DNS dependency.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Missing regression test: Integration test: start fake server on 127.0.0.1:8000, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Evidence: set-up-openai-compatible-endpoint.mdx:25-35 warns about 0.0.0.0 bind and firewall remote.ts onboarding validates host URL but not server bind address Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment confirms loopback-only bind causes 503 regardless of URL rewrite Previous advisor PRA-5 identified same issue

PRA-11 Improvement — Dual-source inconsistency: gatewayEndpointUrl computed twice in recovery path

  • Location: src/lib/onboard/inference-providers/remote.ts:173
  • Category: correctness
  • Problem: remote.ts:173 computes gatewayEndpointUrl = gatewayReachableCompatibleEndpointUrl(provider, resolvedEndpointUrl). Then reuseRegisteredProviderWithGatewayEndpoint receives both endpointUrl (original) and gatewayEndpointUrl (rewritten) and recomputes rewrite logic internally. Two code paths for same transformation.
  • Impact: If rewrite logic changes in one place but not the other, recovery and initial onboarding diverge. Increases maintenance burden and bug surface.
  • Suggested action: Centralize rewrite logic: have reuseRegisteredProviderWithGatewayEndpoint compute gatewayEndpointUrl internally, or pass only resolvedEndpointUrl and let it derive both. Ensure single source of truth.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read remote.ts:173 and compatible-endpoint-gateway-route.ts:75-78. Compare rewrite logic in both locations.
  • Missing regression test: Unit test: verify gatewayReachableCompatibleEndpointUrl and reuseRegisteredProviderWithGatewayEndpoint produce identical gatewayEndpointUrl for same input.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: remote.ts:173 computes gatewayEndpointUrl before calling reuseRegisteredProviderWithGatewayEndpoint compatible-endpoint-gateway-route.ts:75-78 recomputes rewrite internally using same BUNDLED_LOCAL_INFERENCE_GATEWAY_PORT_SET Both use same constant but logic duplicated

PRA-12 Improvement — BUNDLED_LOCAL_INFERENCE_GATEWAY_PORTS duplicated in code and policy YAML

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.ts:7
  • Category: architecture
  • Problem: Port list [11434, 11435, 8000] defined in TypeScript constant and in nemoclaw-blueprint/policies/presets/local-inference.yaml. Test asserts alignment but duplication creates drift risk.
  • Impact: Policy YAML update without code update (or vice versa) causes silent mismatch. Test catches drift but only at test time.
  • Suggested action: Consider single source of truth: generate TypeScript constant from policy YAML at build time, or import policy YAML in test only. Keep as-is if build complexity not justified.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read compatible-endpoint-gateway-route.ts line 7 and nemoclaw-blueprint/policies/presets/local-inference.yaml. Check test/compatible-endpoint-gateway-route.test.ts:18-27 for alignment test.
  • Missing regression test: Build-time test: assert TypeScript constant matches policy YAML ports. Already covered by compatible-endpoint-gateway-route.test.ts:18-27.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: compatible-endpoint-gateway-route.ts:7 exports BUNDLED_LOCAL_INFERENCE_GATEWAY_PORTS = [11434, 11435, 8000] nemoclaw-blueprint/policies/presets/local-inference.yaml has three endpoints with ports 11434, 11435, 8000 test/compatible-endpoint-gateway-route.test.ts:18-27 asserts alignment

PRA-13 Required — Broad private CIDR allowlist in local-inference network policy permits unintended egress

  • Location: nemoclaw-blueprint/policies/presets/local-inference.yaml:1
  • Category: security
  • Problem: The local-inference policy preset allows egress to 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 for host.openshell.internal endpoints on ports 11434, 11435, 8000. This permits sandbox access to any private IP in those ranges if DNS resolves host.openshell.internal to an unexpected address, enabling SSRF bypass and unintended private network access.
  • Impact: Sandbox can reach arbitrary private IPs on allowed ports if DNS is poisoned or OpenShell bridge misconfigured. Violates least-privilege network policy. No negative test verifies denial of non-loopback private IP egress.
  • Required action: Narrow allowed_ips to OpenShell bridge subnet only (e.g., 172.17.0.0/16 for Docker bridge). Add negative test: attempt egress to 10.0.0.5:8000, assert denial. Document rationale for CIDR breadth if narrowing not feasible.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read nemoclaw-blueprint/policies/presets/local-inference.yaml lines 10-12, 21-23, 32-34. Check test/e2e/live/inference-routing.test.ts for negative network policy test.
  • Missing regression test: Integration test: configure fake server on non-loopback private IP (10.0.0.5:8000), onboard with localhost rewrite, assert sandbox inference fails with network policy denial.
  • Done when: The required change is committed and verification passes: Read nemoclaw-blueprint/policies/presets/local-inference.yaml lines 10-12, 21-23, 32-34. Check test/e2e/live/inference-routing.test.ts for negative network policy test.
  • Evidence: local-inference.yaml allows 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 for host.openshell.internal endpoints No negative test in inference-routing.test.ts for non-loopback private IP egress Previous advisor PRA-14 identified same issue

PRA-14 Required — Missing negative security tests for network policy denial, private IP egress, DNS failure, and loopback-only bind

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: security
  • Problem: E2E test suite validates happy-path gateway routing but lacks negative test cases for: (TC-INF-11) non-policy port 9000 → onboarding failure, (TC-INF-12) non-loopback private IP 10.0.0.5:8000 → no rewrite/denial, (TC-INF-13) mock DNS failure for host.openshell.internal → actionable error, (TC-INF-14) 127.0.0.1-only bind → 503 with bind guidance. Security invariants untested.
  • Impact: Network policy enforcement, SSRF defenses, DNS failure handling, and bind-address requirements have no automated regression coverage. Regressions in these critical trust boundaries will not be caught.
  • Required action: Add four negative test cases to inference-routing.test.ts covering the above scenarios. Verify network-policy job exercises these denials.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read test/e2e/live/inference-routing.test.ts around line 123 (TC-INF-10). Search for TC-INF-11 through TC-INF-14. Check test/e2e/support/ for network policy test helpers.
  • Missing regression test: TC-INF-11: onboard with endpoint on port 9000, assert failure. TC-INF-12: fake server on 10.0.0.5:8000, onboard with localhost, assert denial. TC-INF-13: mock DNS failure for host.openshell.internal, assert actionable error. TC-INF-14: fake server on 127.0.0.1:8000 only, onboard, assert 503 with bind guidance.
  • Done when: The required change is committed and verification passes: Read test/e2e/live/inference-routing.test.ts around line 123 (TC-INF-10). Search for TC-INF-11 through TC-INF-14. Check test/e2e/support/ for network policy test helpers.
  • Evidence: test/e2e/live/inference-routing.test.ts has TC-INF-10 (DNS-backed HTTPS fail-closed) but no TC-INF-11 through TC-INF-14 Previous advisor PRA-12 and PRA-16 required these negative tests Risk plan inference-policy invariant: 'network policy permits intended route and denies unintended egress' untested

PRA-15 Resolve/justify — Documentation warns about 0.0.0.0 bind requirement but onboarding does not enforce or validate

  • Location: docs/inference/set-up-openai-compatible-endpoint.mdx:25
  • Category: security
  • Problem: Docs state server must listen on 0.0.0.0 and warn about firewall rules, but onboarding validates only host URL reachability, not server bind address. User can bind to 127.0.0.1 only; onboarding succeeds, sandbox inference fails with 503.
  • Impact: Documentation-only mitigation for critical reachability requirement. User follows docs but misses bind-address nuance, onboarding reports success, inference fails at runtime with no actionable error about bind address.
  • Recommended action: Add onboarding-time validation that local server is reachable from sandbox network context (e.g., probe from container network), or at minimum validate binding address is not 127.0.0.1 without explicit confirmation. Document removal condition for bridge DNS dependency.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Missing regression test: Integration test: start fake server on 127.0.0.1:8000, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read set-up-openai-compatible-endpoint.mdx lines 25-35 for bind guidance. Check remote.ts onboarding flow for bind address validation.
  • Evidence: set-up-openai-compatible-endpoint.mdx:25-35 warns about 0.0.0.0 bind and firewall remote.ts onboarding validates host URL but not server bind address Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment confirms loopback-only bind causes 503 regardless of URL rewrite Previous advisor PRA-5 identified same issue

PRA-16 Required — Missing negative test: network policy denial for non-policy port (TC-INF-11)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Risk-plan inference-policy invariant requires 'network policy permits the intended route and denies unintended egress'. No test validates onboarding failure when endpoint uses non-policy port (e.g., 9000).
  • Impact: Regression in network policy enforcement for gateway routes would not be caught. Users could onboard endpoints on arbitrary ports bypassing policy.
  • Required action: Add TC-INF-11 test: onboard with endpoint on port 9000, assert onboarding fails with actionable error about port not in policy.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-11. Verify network-policy job exercises port denial.
  • Missing regression test: TC-INF-11: onboard with NEMOCLAW_ENDPOINT_URL=http://localhost:9000/v1, assert onboarding fails with port policy error.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-11. Verify network-policy job exercises port denial.
  • Evidence: Risk plan inference-policy invariant 3: 'network policy permits the intended route and denies unintended egress' test/e2e/live/inference-routing.test.ts has TC-INF-10 but no TC-INF-11 through TC-INF-14 Previous advisor PRA-12 and PRA-16 required this test

PRA-17 Required — Missing negative test: private IP egress denial (TC-INF-12)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Risk-plan inference-policy invariant requires 'network policy denies unintended egress'. No test validates denial when fake server runs on non-loopback private IP (10.0.0.5:8000) and onboarding attempts localhost rewrite.
  • Impact: Combined with broad CIDR allowlist (security F-014), SSRF to private networks would not be caught by regression tests.
  • Required action: Add TC-INF-12 test: start fake server on 10.0.0.5:8000, onboard with localhost:8000, assert sandbox inference fails with network policy denial.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-12. Verify network-policy job exercises private IP egress denial.
  • Missing regression test: TC-INF-12: fake server on 10.0.0.5:8000, onboard with localhost:8000, assert denial.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-12. Verify network-policy job exercises private IP egress denial.
  • Evidence: local-inference.yaml allows 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 No test for non-loopback private IP egress denial Security finding F-014: broad CIDR allowlist amplifies risk

PRA-18 Required — Missing negative test: bridge DNS failure for host.openshell.internal (TC-INF-13)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Gateway rewrite depends on host.openshell.internal DNS resolution without verification. No test simulates DNS failure during onboarding or recovery, despite risk-plan invariant 'the selected provider is reachable through the route advertised to the agent' and security findings F-001, F-015.
  • Impact: DNS poisoning or bridge unavailability leads to silent onboarding success but runtime inference failure. No regression coverage for this critical trust boundary.
  • Required action: Add TC-INF-13 test: mock DNS failure for host.openshell.internal during onboarding, assert actionable error or fail-closed behavior. Also test recovery path with reuseGatewayCredentialWithoutLocalKey.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-13. Check test/onboard-inference-gateway-scope.test.ts for recovery DNS failure test.
  • Missing regression test: TC-INF-13: mock DNS resolution failure for host.openshell.internal, onboard with localhost endpoint, assert actionable error. Recovery variant: simulate DNS failure during provider recovery with reuseGatewayCredentialWithoutLocalKey.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-13. Check test/onboard-inference-gateway-scope.test.ts for recovery DNS failure test.
  • Evidence: compatible-endpoint-gateway-route.ts:27-55 rewrites to host.openshell.internal without DNS/TCP probe Risk plan inference-policy invariant 1: 'the selected provider is reachable through the route advertised to the agent' Security findings F-001, F-015: DNS trust without verification enables SSRF Previous advisor PRA-1, PRA-10, PRA-15 required this test

PRA-19 Required — Missing negative test: loopback-only bind causes 503 with bind guidance (TC-INF-14)

  • Location: test/e2e/live/inference-routing.test.ts:123
  • Category: tests
  • Problem: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 and documentation confirm server must bind 0.0.0.0, not 127.0.0.1 only. Onboarding validates host URL but not server bind address. No test validates 503 with actionable bind-address error.
  • Impact: User binds vLLM to 127.0.0.1 (common default), onboarding succeeds, inference fails with generic 503. No actionable guidance at onboarding time.
  • Required action: Add TC-INF-14 test: start fake server on 127.0.0.1:8000 only, onboard with localhost:8000, assert onboarding fails with actionable error about bind address.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Search test/e2e/live/inference-routing.test.ts for TC-INF-14. Check docs/inference/set-up-openai-compatible-endpoint.mdx for bind guidance.
  • Missing regression test: TC-INF-14: fake server on 127.0.0.1:8000 only, onboard with localhost:8000, assert 503 with bind guidance error.
  • Done when: The required change is committed and verification passes: Search test/e2e/live/inference-routing.test.ts for TC-INF-14. Check docs/inference/set-up-openai-compatible-endpoint.mdx for bind guidance.
  • Evidence: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment: loopback-only bind causes 503 regardless of URL rewrite set-up-openai-compatible-endpoint.mdx:25-35 warns about 0.0.0.0 bind but no enforcement Previous advisor PRA-5 and PRA-7 required this test Acceptance finding F-010, security finding F-018

PRA-20 Required — Missing unit test: OpenShell version gating for gateway rewrite

  • Location: src/lib/onboard/inference-providers/compatible-endpoint-gateway-route.test.ts:1
  • Category: tests
  • Problem: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 confirms rewrite only changes reachability on OpenShell ≥0.0.72. Code applies rewrite unconditionally. No test validates version-gated behavior or documents minimum version.
  • Impact: Users on OpenShell <0.0.72 complete onboarding successfully but inference fails with 503. No regression test for version-dependent behavior.
  • Required action: Add unit test: mock OpenShell version <0.0.72, call setupRemoteProviderInference with localhost endpoint, assert rewrite skipped or actionable error. Add integration test for older OpenShell version.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read test/onboard-inference-gateway-scope.test.ts and compatible-endpoint-gateway-route.test.ts for version-gated test case.
  • Missing regression test: Unit test: mock OpenShell version 0.0.44, call gatewayReachableCompatibleEndpointUrl, assert no rewrite or version error. Integration test: onboard on older OpenShell, assert clear version requirement error.
  • Done when: The required change is committed and verification passes: Read test/onboard-inference-gateway-scope.test.ts and compatible-endpoint-gateway-route.test.ts for version-gated test case.
  • Evidence: Issue [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 comment: rewrite inert on OpenShell 0.0.44, works on 0.0.72 compatible-endpoint-gateway-route.ts:27-55 applies rewrite unconditionally remote.ts:167 uses gatewayReachableCompatibleEndpointUrl without version check Acceptance finding F-006

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.

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocking findings on exact head a5e56373aa3662c46a91d5c74f582c75c2434e3a:

  1. The rewrite accepts a missing/default port. For HTTP URLs, URL.port is empty both when the port is omitted and when :80 is explicit, so the current port=null branch rewrites both to host.openshell.internal:80. Existing authoritative containment permits only HTTP + exact loopback host + an explicit numeric port >=1024. Please require that explicit unprivileged port and add negative regressions for http://localhost/v1 and http://localhost:80/v1 plus adjacent no-rewrite shapes. Remove the docs claim that the default HTTP port is supported.

  2. The rewrite accepts arbitrary ports >=1024, but the bundled local-inference policy permits only 11434, 11435, and 8000. A URL such as port 9000 can be rewritten with --no-verify and then fail inside the sandbox. Restrict the rewrite to policy-supported ports, inspect the active policy, or fail/warn with clear policy configuration guidance before provider registration.

  3. Add recovery-path coverage proving an existing provider is updated to the bridge alias without replacing/exporting its credential, followed by inference set --no-verify. Current coverage exercises only fresh creation.

  4. Extract the pure URL transform from remote.ts; the file grows from 372 to 419 lines and the focused transform is directly testable. Both exact-head advisors flag this growth, and Nemotron marks it required.

The old five-target live run used ancestor ab676171, not this exact head, and its compatible-endpoint case was skipped. After fixing and syncing current main, run exact-head inference-routing, network-policy, onboard-repair, onboard-resume, and cloud-onboard, including a real supported-port localhost service that is registered as host.openshell.internal and reached through sandbox inference.local. Re-run both advisors and obtain human approval afterward.

The advisor’s general topology concern cites unsupported OpenShell 0.0.44 behavior; current 0.0.72 A/B evidence supports the bridge hypothesis. Exact-head implementation proof is still required before that warning can be explicitly dispositioned.

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

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29129222547
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: inference-routing,network-policy,onboard-repair,onboard-resume,cloud-onboard
Summary: 3 passed, 1 failed, 1 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ❌ failure
network-policy ⚠️ cancelled
onboard-repair ✅ success
onboard-resume ✅ success

Failed jobs: inference-routing. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29129492764
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: inference-routing,network-policy,onboard-repair,onboard-resume,cloud-onboard
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

@cjagwani
cjagwani dismissed their stale review July 10, 2026 23:19

dismissed

@cv

cv commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

@cjagwani, the requested follow-ups are ready for re-review on e332453e7.

Implemented:

  • Rewriting is limited to exact HTTP loopback hosts with explicit bundled-policy ports 11434, 11435, or 8000; missing ports, :80, privileged/unsupported ports, userinfo, alternate loopback spellings, and other adjacent shapes remain unchanged.
  • The transform and recovered-provider update are extracted from remote.ts, which is back to its main line count.
  • Recovery now proves an existing provider gets a config-only gateway-alias update with no credential flag/value in argv or env, followed by inference set --no-verify.
  • The hermetic live case starts a real authenticated service at localhost:8000, verifies host-side access there, and proves the sandbox request reaches it through inference.local with Host: host.openshell.internal:8000.
  • Docs now state the exact qualifying URL shapes, bundled ports, bridge dependency, unsupported cases, and exposure guidance.

Verification:

  • Live run 29129492764: inference-routing, network-policy, onboard-repair, onboard-resume, and cloud-onboard all passed.
  • PR CI: 42 checks passed, none pending or failing.
  • env -u SSH_CONNECTION -u SSH_CLIENT -u SSH_TTY npm test: 1,383 files and 15,864 tests passed (39 skipped, 1 todo).
  • npm run docs: 0 errors and 2 pre-existing warnings.
  • All commits are GitHub-verified and DCO is passing.

Automated-advisor dispositions:

  • PRA-1: perf(onboard): reuse provider validation connections #6419 and perf(onboard): reuse provider validation connections #6661 are alternate performance branches from the same author; neither is in main, so whichever lands later must rebase. There is no combined behavior in this PR to test.
  • PRA-2, PRA-4, PRA-7, PRA-9, PRA-10: NemoClaw pins and enforces OpenShell 0.0.72. Gateway startup already probes host.openshell.internal from the OpenShell Docker network and fails actionable bridge errors. A host-process DNS probe would test the wrong namespace, while duplicating the gateway probe in the pure provider helper would split topology ownership. The docs state the bridge dependency and runtime check, and the successful live case proves the supported route. Also, compatible-endpoint already had skipVerify: true; rewriting does not introduce a new verification bypass, and host smoke still validates the entered URL. Existing bridge-negative tests plus the recovery and live tests cover the stated gaps.
  • PRA-3: the parity manifest maps the live case to the complete URL matrix, fake-server contract, and credential-recovery test; the full e2e-support lane passed.
  • PRA-5: shared provider tests prove --credential is omitted when update env is empty; the new recovery test proves the config-only command, empty env, absent credential value, and subsequent inference configuration.
  • PRA-6: the second provider read is an intentional final existence check so keyless recovery cannot silently become a create; the shared upsert then rechecks to select update versus create.
  • PRA-8: the pure transform is not the URL validator. It leaves malformed input unchanged for the existing fail-closed endpoint preflight, which reports the validation error; both behaviors are tested.
  • PRA-T1 through PRA-T5 and PRA-T8 are satisfied by the successful live run and existing bridge-probe coverage. PRA-T6 is covered by malformed-input passthrough plus fail-closed preflight tests. PRA-T7 requires no new warning behavior because the provider already used skipVerify; the exact command path is covered.

GPT reports no blocking findings. Nemotron's remaining topology item is dispositioned above using the supported-version boundary, existing gateway probe, and the requested live implementation proof.

Please re-review when convenient.

@cv
cv requested a review from cjagwani July 10, 2026 23:21
@prekshivyas prekshivyas added v0.0.81 Release target and removed v0.0.80 Release target labels Jul 10, 2026
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29130555308
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: inference-routing,network-policy,onboard-repair,onboard-resume,cloud-onboard
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

@cjagwani

Copy link
Copy Markdown
Collaborator

Maintainer disposition on exact head 364791ba94bc2a4e10c38f045ba5d71edbc65d8f:

  • PRA-1 / PRA-3 / PRA-8 / PRA-11 / PRA-T8 — Docker auth is required and contained. The live test is not a local-Node-only job: requireLivePrerequisites explicitly requires Docker, onboardSandbox creates a real OpenShell sandbox, and TC-INF-09 now runs that image-consuming path unconditionally. The shared workflow-boundary test treats every non-exempt E2E job as image-consuming and enforces exactly one guarded auth step plus final always() cleanup. The credentials are exposed only on trusted main/manual runs; PR runs receive an isolated empty Docker config. Exact-head run 29130555308 used this path and passed.
  • PRA-2 / PRA-10 / PRA-T7 — the port invariant already has a CI guard. compatible-endpoint-gateway-route.test.ts parses nemoclaw-blueprint/policies/presets/local-inference.yaml and requires exact equality with BUNDLED_LOCAL_INFERENCE_GATEWAY_PORTS. That test is in the required CLI Vitest project; the exact-head CLI shards and aggregate checks job passed.
  • PRA-4 / PRA-5 / PRA-6 / PRA-9 / PRA-T6 — manual gateway aliases already skip network probing. compatible-endpoint has skipVerify: true, so inference set uses --no-verify whether or not rewriting changed the URL. The shared smoke wrapper calls probeOpenAiLikeEndpoint, which recognizes exact host.openshell.internal URLs, performs no curl, and returns an OK “validation skipped” note. onboard-probes.test.ts directly covers that no-curl behavior, and inference-options-docs.test.ts couples the same result to the documented manual-alias wording. The advisor’s claim that the host issues a request to the alias is therefore not applicable.
  • PRA-7 — removal condition is already concrete for this repository. The workaround is scoped to [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 and says to remove it when OpenShell can verify provider routes from the sandbox/gateway network context; NemoClaw currently pins exactly OpenShell 0.0.72, so there is no ambiguous supported-version branch today.
  • PRA-T1 through PRA-T5 — runtime proof complete. Exact-head run 29130555308 passed cloud-onboard, inference-routing, network-policy, onboard-repair, and onboard-resume. TC-INF-09 proves host validation at localhost:8000 and a sandbox inference.local request reaching Host: host.openshell.internal:8000.

The exact-head standard CI suite is green, CodeRabbit has no unresolved major/critical finding, all six commits are GitHub Verified, and DCO passes. No code change is warranted for these warning-level findings; they are either already implemented and tested or based on an incomplete reading of the live job/probe path.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani

Copy link
Copy Markdown
Collaborator

Follow-up disposition for the remaining Nemotron warnings on exact head f348858830f30d7848685752ea9ee14bfbf2f99d:

  • PRA-1 / PRA-T8 — bridge availability is already probed and regression-tested. Docker-driver gateway startup calls verifySandboxBridgeGatewayReachableOrExit, whose helper runs on the OpenShell Docker network with the same host.openshell.internal mapping. Its test suite covers missing network/DNS, TCP failure, timeout, daemon failure, veth failure, retries, and severity. NemoClaw pins exactly OpenShell 0.0.72, and the [Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway #5744 helper comment defines removal when OpenShell can verify from the sandbox/gateway context. The docs accurately retain the warn-only inconclusive-probe case instead of claiming every probe-infrastructure failure is fatal.
  • PRA-2 / PRA-T7 — existing manual aliases are already documented and preserved. The guide explicitly explains manual http://host.openshell.internal:8000/v1 entry and that host validation is skipped. The URL matrix proves that alias remains unchanged. Automatic loopback rewriting is additive; there is no migration action for existing configurations.
  • PRA-3 — this transform is deliberately not the URL-validation boundary. Malformed input is returned unchanged so the existing endpoint SSRF/preflight validator remains the single fail-closed authority and produces the user-facing validation error. The helper matrix already includes malformed input passthrough; turning this pure transform into a second parser/error surface would split validation ownership.
  • PRA-4 — the cited policy was not broadened by this PR. local-inference.yaml already scopes the cross-topology private ranges to the exact host.openshell.internal name and three exact ports. Those ranges are required because Docker/rootless/desktop host-gateway addresses differ. This PR narrows application-side eligibility to exact loopback authorities and those existing ports; it adds no new policy egress.
  • PRA-5 — negative security coverage already exists at the appropriate layers. The pure URL matrix rejects missing/default/privileged/unsupported ports, private and alternate loopback spellings, userinfo, HTTPS, zone IDs, subdomain confusion, and manual aliases. The endpoint SSRF/preflight tests reject non-loopback private LAN targets, and the exact-head network-policy live job proves denied egress remains denied. Duplicating that full matrix in the expensive live happy-path test would not add a new boundary assertion.
  • PRA-6 / PRA-T6 — NemoClaw mutations are serialized and re-authorized. The setup path runs under withGatewayRouteMutationLock; merged main commit fix(onboard): scope live inference recovery to sandbox #6634 also re-checks recorded-provider recovery authorization inside that lock immediately before route setup. Its recovery-gating and route-containment tests passed together with this PR’s credential-preserving update tests. External concurrent mutation through a separate OpenShell client has no compare-and-swap API in pinned OpenShell 0.0.72 and is outside the supported transaction boundary; inventing a mock config race would not create a safe retry primitive.

The second main sync was mechanical only: it combined this PR’s inference-routing mock-parity entry with #6663’s separate full-E2E entry. scripts/checks/e2e-mock-parity.ts and test/e2e-mock-parity.test.ts pass on the merge result; the product diff is unchanged. Fresh exact-head CI and the five required live targets are running at 29131552351.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29131552351
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: inference-routing,network-policy,onboard-repair,onboard-resume,cloud-onboard
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29132091441
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: cloud-onboard,inference-routing,network-policy,onboard-repair,onboard-resume
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29132484397
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: cloud-onboard,inference-routing,network-policy,onboard-repair,onboard-resume
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

@cjagwani

Copy link
Copy Markdown
Collaborator

Maintainer disposition on exact head 71bca2a11fffbab269c365081591fa57313eef17 after the completed live and standard gates:

  • PRA-1 / PRA-8 / PRA-19 — bridge reachability and --no-verify: non-blocking, already bounded. Gateway startup probes host.openshell.internal from the OpenShell Docker network and fails on proven DNS/TCP bridge failures; its tests cover DNS failure, TCP failure, timeout, and the documented inconclusive-probe warning path. compatible-endpoint already used skipVerify before this change. The flow retains host API smoke validation, while the guide explicitly makes nemoclaw <name> status plus a short agent request the authoritative runtime check. Exact-head live run 29132484397 proves both inference.local and the literal public dcode -n path reach host.openshell.internal:8000.
  • PRA-2 — provider mutation race: not a supported-transaction defect. Setup and recovery run under the cross-process gateway route mutation lock, recovery authority is rechecked inside that lock, the helper performs a final provider-existence guard, and upsertProvider re-reads and propagates update failure. OpenShell 0.0.72 exposes no compare-and-swap primitive; an out-of-band direct OpenShell client can race any managed mutation, and retry/backoff would not make it atomic. The recovery test proves both reads, the config-only update, empty credential environment, and that inference mutation follows only success.
  • PRA-6 — version premise is false. The blueprint declares both min_openshell_version and max_openshell_version as 0.0.72; onboarding and the installer enforce that exact supported version. The container-reachable bind/topology caveat is documented.
  • PRA-12 / PRA-16 — requested negative cases are already covered at their enforcement layers. The URL matrix rejects unsupported/default/privileged ports, adjacent loopback forms, private-IP spellings, userinfo, HTTPS, zone IDs, and aliases; endpoint SSRF preflight rejects non-loopback private targets; the live network-policy target proves allowed versus denied host-gateway ports. Repeating the same matrix in the expensive positive inference-routing lane would not add a distinct boundary assertion.
  • The claimed double-provider get mismatch is also false: one read authorizes recovered provider metadata and the second is the final existence guard immediately before the config-only update.

The seven “required” entries reduce to two documented residual constraints plus duplicate/incorrect restatements; I judge them non-blocking for this PR. The Nemotron job produced a partial review after timing out at turn 10/13. The canonical primary advisor completed on this exact head with merge_as_is, 0 required, 0 warnings, and 0 suggestions.

Verification: all five required live targets passed in run 29132484397; standard CI and aggregates passed after rerunning one unrelated docker info timing flake in untouched code; DCO and all nine commit signatures are clean; CodeRabbit has no unresolved major/critical finding.

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved at exact head 71bca2a11fffbab269c365081591fa57313eef17.

The canonical primary advisor is merge_as_is; DCO and all nine commit signatures are clean; CodeRabbit has no unresolved major/critical finding; standard CI and aggregates pass; and exact-head live run 29132484397 passes cloud-onboard, inference-routing, network-policy, onboard-repair, and onboard-resume. TC-INF-09 exercises the reported public nemoclaw <sandbox> exec -- dcode -n ... path and verifies authenticated traffic reaches host.openshell.internal:8000.

I manually triaged the incomplete secondary Nemotron findings and explicitly judged them non-blocking here: #6649 (comment)

Disclosure: I authored the mechanical main-sync and maintainer follow-up docs/test commits on this branch; contributor/approver overlap is advisory under current maintainer policy.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@cjagwani

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 29135327499
Workflow ref: fix/5744-local-inference-gateway-verified
Requested targets: (default — all supported)
Requested jobs: cloud-onboard,inference-routing,network-policy,onboard-repair,onboard-resume
Summary: 5 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
inference-routing ✅ success
network-policy ✅ success
onboard-repair ✅ success
onboard-resume ✅ success

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@docs/inference/set-up-openai-compatible-endpoint.mdx`:
- Around line 14-17: Rewrite the referenced documentation passages in
second-person, active, present-tense voice, replacing third-person subjects such
as “The agent,” “OpenShell,” and “NemoClaw” with direct instructions or “you”
statements while preserving the technical meaning. Review all mentioned
sections, including the endpoint connection, validation, and setup guidance.

In `@docs/security/openclaw-2026.6.10-dependency-review.md`:
- Around line 194-207: Rewrite the recovery section in direct second-person
voice, replacing third-person subjects such as “NemoClaw,” “OpenShell,” and
“Recovery” with imperative guidance using “you.” Preserve all security
constraints and technical details, including credential handling, provider
updates, endpoint validation, route provenance, and cleanup behavior.
🪄 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: 0e8d1588-1153-479b-862a-98c92ea47c72

📥 Commits

Reviewing files that changed from the base of the PR and between e332453 and 619e0a8.

📒 Files selected for processing (7)
  • docs/inference/how-inference-routing-works.mdx
  • docs/inference/set-up-openai-compatible-endpoint.mdx
  • docs/security/openclaw-2026.6.10-dependency-review.md
  • test/e2e/lib/fake-openai-compatible-api.mts
  • test/e2e/live/inference-routing.test.ts
  • test/e2e/mock-parity.json
  • test/inference-options-docs.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/inference/how-inference-routing-works.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e/mock-parity.json
  • test/e2e/live/inference-routing.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🤖 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 `@docs/inference/set-up-openai-compatible-endpoint.mdx`:
- Around line 14-17: Rewrite the referenced documentation passages in
second-person, active, present-tense voice, replacing third-person subjects such
as “The agent,” “OpenShell,” and “NemoClaw” with direct instructions or “you”
statements while preserving the technical meaning. Review all mentioned
sections, including the endpoint connection, validation, and setup guidance.

In `@docs/security/openclaw-2026.6.10-dependency-review.md`:
- Around line 194-207: Rewrite the recovery section in direct second-person
voice, replacing third-person subjects such as “NemoClaw,” “OpenShell,” and
“Recovery” with imperative guidance using “you.” Preserve all security
constraints and technical details, including credential handling, provider
updates, endpoint validation, route provenance, and cleanup behavior.
🪄 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: 0e8d1588-1153-479b-862a-98c92ea47c72

📥 Commits

Reviewing files that changed from the base of the PR and between e332453 and 619e0a8.

📒 Files selected for processing (7)
  • docs/inference/how-inference-routing-works.mdx
  • docs/inference/set-up-openai-compatible-endpoint.mdx
  • docs/security/openclaw-2026.6.10-dependency-review.md
  • test/e2e/lib/fake-openai-compatible-api.mts
  • test/e2e/live/inference-routing.test.ts
  • test/e2e/mock-parity.json
  • test/inference-options-docs.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/inference/how-inference-routing-works.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e/mock-parity.json
  • test/e2e/live/inference-routing.test.ts
🛑 Comments failed to post (2)
docs/inference/set-up-openai-compatible-endpoint.mdx (1)

14-17: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use second-person voice throughout the new documentation.

The docs/**/*.{md,mdx} guideline requires active voice, second person, and present tense. Several passages use third-person narration such as “The agent connects,” “OpenShell forwards,” and “NemoClaw validates.” Rewrite these as direct instructions or second-person statements while preserving the technical meaning.

Suggested wording
-The agent connects to `inference.local` inside the sandbox.
-OpenShell forwards that traffic to the endpoint configured during onboarding.
+Your agent connects to `inference.local` inside the sandbox.
+You route that traffic through OpenShell to the endpoint you configure during onboarding.

Also applies to: 51-56, 62-63, 69-70, 85-89, 93-99, 129-131

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

In `@docs/inference/set-up-openai-compatible-endpoint.mdx` around lines 14 - 17,
Rewrite the referenced documentation passages in second-person, active,
present-tense voice, replacing third-person subjects such as “The agent,”
“OpenShell,” and “NemoClaw” with direct instructions or “you” statements while
preserving the technical meaning. Review all mentioned sections, including the
endpoint connection, validation, and setup guidance.

Source: Coding guidelines

docs/security/openclaw-2026.6.10-dependency-review.md (1)

194-207: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rewrite the recovery section in second-person voice.

The docs/**/*.{md,mdx} guideline requires direct second-person documentation. The new text repeatedly uses third-person narration (NemoClaw does..., OpenShell deliberately reports..., Recovery does...). Rewrite it as direct guidance such as “Do not read or replace...” and “Keep the recovery path...”.

Also applies to: 208-211

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

In `@docs/security/openclaw-2026.6.10-dependency-review.md` around lines 194 -
207, Rewrite the recovery section in direct second-person voice, replacing
third-person subjects such as “NemoClaw,” “OpenShell,” and “Recovery” with
imperative guidance using “you.” Preserve all security constraints and technical
details, including credential handling, provider updates, endpoint validation,
route provenance, and cleanup behavior.

Source: Coding guidelines

@cjagwani

Copy link
Copy Markdown
Collaborator

Maintainer disposition on exact head 619e0a869642dbd40fff00653f89e1fc1d162d6a after the main sync and fresh validation:

  • Canonical advisor and runtime gates: the primary exact-head advisor is merge_as_is with 0 required, 0 warnings, and 0 suggestions: fix(inference): route local compatible endpoints through gateway #6649 (comment). Its five runtime follow-ups are satisfied by exact-head run https://github.com/NVIDIA/NemoClaw/actions/runs/29135327499, where cloud-onboard, inference-routing, network-policy, onboard-repair, and onboard-resume all passed. TC-INF-09 proves host validation at localhost:8000, sandbox inference.local, and literal dcode -n traffic reaching host.openshell.internal:8000.
  • Nemotron PRA-1 through PRA-10: PRA-3/4/6/8 are factually incorrect; PRA-5 is a presentation-only justification; PRA-1/2/7/9/10 repeat already bounded or documented residuals. Gateway startup already probes the real OpenShell Docker bridge alias and fails on proven DNS/TCP failures, with retry/severity coverage. Route mutation is serialized, recovered authority is rechecked inside the lock, the second provider get is an intentional final existence/update guard, and OpenShell 0.0.72 has no compare-and-swap primitive. Malformed URLs remain owned by the fail-closed endpoint validator. NemoClaw supports exactly OpenShell 0.0.72, and compatible-endpoint already used --no-verify; the flow retains host smoke validation and documents status plus a short agent request as authoritative runtime verification.
  • PRA-11/PRA-12: PRA-11 has a false premise: gatewayEndpointUrl is computed once by remote.ts; the helper only compares and uses the supplied value. PRA-12 is already guarded by a test that parses local-inference.yaml and asserts exact equality with the TypeScript port list; build-time generation would add coupling without a safety gain.
  • PRA-13 through PRA-20: these conflate the unchanged, separately selected local-inference preset with the provider-composed base inference.local route used here. This PR does not broaden that preset. Exact URL-shape tests reject adjacent/private/unsupported rewrite shapes; SSRF tests reject literal and DNS-resolved private endpoints; and the live network-policy lane proves allowed versus denied host-gateway ports plus non-bridge allowed_ips rejection. Port 9000 is intentionally left unchanged rather than rejected so other compatible topologies remain possible. OpenShell versions below 0.0.72 are outside the enforced support contract. The loopback-only bind and bridge-diagnostic requests are useful future availability/UX ideas, but the limitations are already documented and are not privilege-expansion defects.
  • CodeRabbit: the two exact-head findings are Minor documentation-voice suggestions, not correctness or security issues. The style guide explicitly permits active software subjects (for example, “The CLI creates a gateway”), while changing “OpenShell forwards” to “You route” would misstate agency. The dependency review is a declarative security-evidence artifact; converting product guarantees into reader imperatives would weaken the enforcement boundary. No churn is warranted, and there are zero unresolved review threads.

I explicitly judge the secondary advisor's required/warning items non-blocking on this head. All required checks are green, all ten commits are GitHub Verified, DCO passes, the PR is mechanically mergeable, and no code change is warranted from the exact-head automated feedback.

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved at exact head 619e0a869642dbd40fff00653f89e1fc1d162d6a.

All five required checks and the complete check rollup are green; DCO passes and all ten commits are GitHub Verified. Exact-head live run 29135327499 passes cloud-onboard, inference-routing, network-policy, onboard-repair, and onboard-resume, including TC-INF-09's host-validation, sandbox inference.local, and literal dcode -n route through host.openshell.internal:8000.

The canonical primary advisor is exact-head merge_as_is with no required/warning/suggestion findings. I independently triaged every inconsistent secondary-advisor item and CodeRabbit's two minor documentation-style suggestions here: #6649 (comment). None identifies an unaddressed correctness, security, acceptance, or test-depth blocker. CodeRabbit has no unresolved major/critical finding, and all review threads are resolved.

Disclosure: I authored the mechanical main-sync and follow-up docs/test resolution on this branch; contributor/approver overlap is advisory under current maintainer policy.

@cv
cv merged commit fa480df into main Jul 11, 2026
128 checks passed
@cv
cv deleted the fix/5744-local-inference-gateway-verified branch July 11, 2026 02:52
@cv cv mentioned this pull request Jul 12, 2026
21 tasks
cv added a commit that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Release-prep documentation for v0.0.81 now summarizes user-facing
changes merged since v0.0.80.
It also closes the Hermes dashboard-profile backup gap and distinguishes
direct blueprint-runner actions from public host CLI commands.

## Changes

- Add the `v0.0.81` section to `docs/about/release-notes.mdx` with links
to the detailed user guides.
- Document that Hermes rebuilds preserve `.hermes/dashboard-home/`,
including Dashboard `MEMORY.md` and `USER.md`.
- Update Hermes manual backup and restore examples to transfer those two
profile files without copying generated configuration or the
secret-bearing dashboard `.env`.
- Explain the new per-item backup failure causes.
- Clarify that migration snapshot retention fragments are direct-runner
arguments and are not exposed by the host `nemoclaw` CLI.

### Source summary

- #6445 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Summarize manifest-owned
key-level restore and current-config authority.
- #6617 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Record the fail-closed
`/proc` fallback used to verify an idle Deep Agents runtime before
snapshot creation.
- #6685 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Document Hermes Web
Dashboard profile persistence and safe manual transfer.
- #6649 -> `docs/about/release-notes.mdx`: Summarize host-validated
loopback compatible-endpoint routing through the sandbox gateway.
- #6643 -> `docs/about/release-notes.mdx`: Summarize automatic
`max_completion_tokens` handling for GPT-5 and o-series models.
- #6661 -> `docs/about/release-notes.mdx`: Summarize bounded connection
reuse for eligible provider-validation probes.
- #6704 -> `docs/about/release-notes.mdx`: Record that direct blueprint
apply stops instead of persisting incomplete state after provider or
inference setup fails.
- #6677 -> `docs/about/release-notes.mdx`: Summarize transactional
recovery for legacy Docker containers whose managed supervisor
disappeared after restart.
- #6625 -> `docs/about/release-notes.mdx`: Record Hermes managed-startup
persistence across direct Docker restarts.
- #6597 -> `docs/about/release-notes.mdx`: Record final-sandbox gateway
cleanup on macOS.
- #6680 -> `docs/about/release-notes.mdx`: Summarize managed Deep Agents
first-run and process-tree cleanup improvements.
- #6647 -> `docs/about/release-notes.mdx`: Record fail-closed validation
for the managed Deep Agents fetch CA bundle.
- #6645 -> `docs/about/release-notes.mdx`: Summarize WhatsApp loopback
pairing and trusted npm plugin provenance.
- #6673 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document stopped-sandbox
backup remediation.
- #6631 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document per-item backup
failure causes.
- #6620 -> `docs/about/release-notes.mdx`: Record the
created-but-not-ready sandbox lifecycle receipt.
- #6664 -> `docs/about/release-notes.mdx`: Record prompt-aware
onboarding progress output.
- #6598 -> `docs/about/release-notes.mdx`: Summarize stale replay-result
invalidation during resumed onboarding.
- #6593 -> `docs/about/release-notes.mdx`: Summarize contextual OpenClaw
audit findings for managed dashboard compatibility settings.
- #6650 -> `docs/about/release-notes.mdx`: Record redaction of
token-shaped URL query values.
- #6638 -> `docs/about/release-notes.mdx`: Record the exact-path MCP
`DELETE` policy recipe for session termination.
- #5453 -> `docs/reference/host-files-and-state.mdx`: Clarify that
snapshot retention actions belong to direct runner integrations and are
not standalone host CLI commands.

### Skipped from docs-skip

- #6633 matched the `openclaw-sandbox-permissive.yaml` path in
`docs/.docs-skip` and produced no documentation in this update.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: This is a documentation-only
release-prep update; behavior is protected by the merged source PRs, and
the documentation build validates the changed examples and routes.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [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 — tests are not applicable for this
documentation-only change; `npm run docs` completed successfully.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not run for this
documentation-only change.
- [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) — 0
errors; two existing Fern warnings remain.
- [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)
— no new pages.

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


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

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.81 covering state preservation, inference
setup, sandbox recovery, session setup, pairing, diagnostics, and
security policy updates.
- Expanded backup and restore guidance to include dashboard profile
files and clarify files that must not be copied.
- Added dashboard profile persistence details to workspace and rebuild
documentation.
- Clarified snapshot retention guidance and the distinction between host
CLI capabilities and direct runner actions.
  - Added more detailed backup failure reporting information.

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

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…DIA#6649)

<!-- markdownlint-disable MD041 -->
## Summary
Replaces PR NVIDIA#6331 with a clean, GitHub-verified branch for the local
compatible-endpoint gateway fix.
The change keeps host-side validation on the user-entered loopback URL,
registers eligible sandbox routes through `host.openshell.internal`, and
documents the exposure risk of `0.0.0.0` binds.

## Related Issue
Fixes NVIDIA#5744.
Replaces NVIDIA#6331.

## Changes
- Rewrite only `compatible-endpoint` HTTP URLs with exact loopback hosts
and explicit bundled policy ports (`11434`, `11435`, or `8000`) when
registering the OpenShell provider route.
- Keep host validation on the user-entered URL; on credential reuse,
update an existing provider to the gateway alias without exporting or
replacing its credential, then configure inference with `--no-verify`.
- Extract the focused transformation and recovery logic from
`remote.ts`, and document the exact supported URL shapes, bundled ports,
bridge reachability, and `0.0.0.0` exposure mitigations.
- Add unit, recovery-integration, docs, fast E2E-support, and hermetic
live inference-routing coverage for the gateway registration contract.

## 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
<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [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: This is the
clean-history replacement for NVIDIA#6331 after the maintainer sweep at
NVIDIA#6331 (review).
The replacement preserves the reviewed gateway-routing change and adds
the requested adjacent `0.0.0.0` exposure warning instead of accepting
the risk silently.
- [ ] 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:
focused CLI, integration, docs, E2E-support, mock-parity,
project-membership, title, size, and build checks passed; `npm run docs`
reported 0 errors and 2 existing warnings; live run
[29129492764](https://github.com/NVIDIA/NemoClaw/actions/runs/29129492764)
passed `inference-routing`, `network-policy`, `onboard-repair`,
`onboard-resume`, and `cloud-onboard`.
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: `env -u SSH_CONNECTION -u
SSH_CLIENT -u SSH_TTY npm test` passed 1,383 test files and 15,864 tests
(39 skipped, 1 todo).
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

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


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

- **New Features**
- Compatible inference endpoints using supported loopback addresses and
ports can now be automatically routed through the sandbox gateway.
- Rebuilds can restore compatible endpoint routing without requiring
stored host credentials.
- Endpoint paths, query strings, and fragments are preserved during
automatic routing.

- **Documentation**
- Expanded guidance explains supported endpoints, routing behavior,
validation limits, and runtime status checks.
  - Clarified credential handling during gateway recovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: San Dang <sdang@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Charan Jagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Release-prep documentation for v0.0.81 now summarizes user-facing
changes merged since v0.0.80.
It also closes the Hermes dashboard-profile backup gap and distinguishes
direct blueprint-runner actions from public host CLI commands.

## Changes

- Add the `v0.0.81` section to `docs/about/release-notes.mdx` with links
to the detailed user guides.
- Document that Hermes rebuilds preserve `.hermes/dashboard-home/`,
including Dashboard `MEMORY.md` and `USER.md`.
- Update Hermes manual backup and restore examples to transfer those two
profile files without copying generated configuration or the
secret-bearing dashboard `.env`.
- Explain the new per-item backup failure causes.
- Clarify that migration snapshot retention fragments are direct-runner
arguments and are not exposed by the host `nemoclaw` CLI.

### Source summary

- NVIDIA#6445 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Summarize manifest-owned
key-level restore and current-config authority.
- NVIDIA#6617 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Record the fail-closed
`/proc` fallback used to verify an idle Deep Agents runtime before
snapshot creation.
- NVIDIA#6685 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Document Hermes Web
Dashboard profile persistence and safe manual transfer.
- NVIDIA#6649 -> `docs/about/release-notes.mdx`: Summarize host-validated
loopback compatible-endpoint routing through the sandbox gateway.
- NVIDIA#6643 -> `docs/about/release-notes.mdx`: Summarize automatic
`max_completion_tokens` handling for GPT-5 and o-series models.
- NVIDIA#6661 -> `docs/about/release-notes.mdx`: Summarize bounded connection
reuse for eligible provider-validation probes.
- NVIDIA#6704 -> `docs/about/release-notes.mdx`: Record that direct blueprint
apply stops instead of persisting incomplete state after provider or
inference setup fails.
- NVIDIA#6677 -> `docs/about/release-notes.mdx`: Summarize transactional
recovery for legacy Docker containers whose managed supervisor
disappeared after restart.
- NVIDIA#6625 -> `docs/about/release-notes.mdx`: Record Hermes managed-startup
persistence across direct Docker restarts.
- NVIDIA#6597 -> `docs/about/release-notes.mdx`: Record final-sandbox gateway
cleanup on macOS.
- NVIDIA#6680 -> `docs/about/release-notes.mdx`: Summarize managed Deep Agents
first-run and process-tree cleanup improvements.
- NVIDIA#6647 -> `docs/about/release-notes.mdx`: Record fail-closed validation
for the managed Deep Agents fetch CA bundle.
- NVIDIA#6645 -> `docs/about/release-notes.mdx`: Summarize WhatsApp loopback
pairing and trusted npm plugin provenance.
- NVIDIA#6673 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document stopped-sandbox
backup remediation.
- NVIDIA#6631 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document per-item backup
failure causes.
- NVIDIA#6620 -> `docs/about/release-notes.mdx`: Record the
created-but-not-ready sandbox lifecycle receipt.
- NVIDIA#6664 -> `docs/about/release-notes.mdx`: Record prompt-aware
onboarding progress output.
- NVIDIA#6598 -> `docs/about/release-notes.mdx`: Summarize stale replay-result
invalidation during resumed onboarding.
- NVIDIA#6593 -> `docs/about/release-notes.mdx`: Summarize contextual OpenClaw
audit findings for managed dashboard compatibility settings.
- NVIDIA#6650 -> `docs/about/release-notes.mdx`: Record redaction of
token-shaped URL query values.
- NVIDIA#6638 -> `docs/about/release-notes.mdx`: Record the exact-path MCP
`DELETE` policy recipe for session termination.
- NVIDIA#5453 -> `docs/reference/host-files-and-state.mdx`: Clarify that
snapshot retention actions belong to direct runner integrations and are
not standalone host CLI commands.

### Skipped from docs-skip

- NVIDIA#6633 matched the `openclaw-sandbox-permissive.yaml` path in
`docs/.docs-skip` and produced no documentation in this update.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: This is a documentation-only
release-prep update; behavior is protected by the merged source PRs, and
the documentation build validates the changed examples and routes.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [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 — tests are not applicable for this
documentation-only change; `npm run docs` completed successfully.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not run for this
documentation-only change.
- [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) — 0
errors; two existing Fern warnings remain.
- [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)
— no new pages.

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


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

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.81 covering state preservation, inference
setup, sandbox recovery, session setup, pairing, diagnostics, and
security policy updates.
- Expanded backup and restore guidance to include dashboard profile
files and clarify files that must not be copied.
- Added dashboard profile persistence details to workspace and rebuild
documentation.
- Clarified snapshot retention guidance and the distinction between host
CLI capabilities and direct runner actions.
  - Added more detailed backup failure reporting information.

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

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

Labels

area: docs Documentation, examples, guides, or docs build area: inference Inference routing, serving, model selection, or outputs area: local-models Local model providers, downloads, launch, or connectivity area: routing Request routing, policy routing, model selection, or fallback logic area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening bug-fix PR fixes a bug or regression v0.0.81 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Linux][Inference] nemoclaw sandbox returns 503 when proxying inference requests to local vLLM custom endpoint via inference.local gateway

4 participants