Skip to content

fix(status): make inference route health authoritative#6412

Merged
apurvvkumaria merged 22 commits into
mainfrom
fix/6192-authoritative-inference-route
Jul 8, 2026
Merged

fix(status): make inference route health authoritative#6412
apurvvkumaria merged 22 commits into
mainfrom
fix/6192-authoritative-inference-route

Conversation

@apurvvkumaria

@apurvvkumaria apurvvkumaria commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Make the in-sandbox https://inference.local/v1/models route authoritative for inference health in nemoclaw status, nemoclaw doctor, and nemoclaw connect. This supersedes #6203 and #6264 while retaining credit for Harjoth's original implementation and Souvik's typed test-seam contribution.

Related Issue

Fixes #6192

Changes

  • Share one agent-aware inference.local probe and fail-closed parser across connect, status, and doctor.
  • Treat final HTTP 200-499 responses as route-reachable; treat interim 100-199 responses, HTTP 500-599, 000, malformed output, timeout, and unavailable probes as failing.
  • Centralize route-failure labels and status exit decisions so text, JSON, status, doctor, and connect cannot drift.
  • Discard route-probe response bodies through /dev/null instead of a persistent sandbox temp file.
  • Verify route TLS with OpenShell's managed CA bundle; certificate failures are authoritative unreachable results.
  • Keep direct provider checks as explicitly labeled, non-authoritative upstream diagnostics.
  • Return nonzero status for unhealthy or unavailable inference routes in text and JSON output.
  • Add regression coverage for HTTP boundaries, unavailable probes, framed OpenShell output, no-direct-probe providers, DCode, and CLI exit behavior.
  • Update command, monitoring, local-inference, and troubleshooting documentation for the authoritative route semantics.

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: nine-category review passed after the only hardening finding was fixed.
  • 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 — npx vitest run --project cli over the nine route/connect/status/doctor/recovery/adapter files: 163 passed; npx vitest run --project integration over the eight changed CLI/recovery files: 43 passed.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: npm run checks passed; the exact-head PR CI suite completed without failures; typed OpenClaw and DCode live targets passed; inference-routing, diagnostics, and sandbox-operations live jobs passed.
  • 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) — build passed with 0 errors and two existing Fern warnings.
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Architecture and Runtime-Boundary Review

  • Invalid state: Host/provider checks can succeed while the agent-visible https://inference.local/v1/models route is unusable. This PR exposes that disagreement; it does not preserve or mask it.
  • Source boundary: OpenShell owns sandbox exec, DNS, TLS CA injection, and proxy provisioning. NemoClaw owns interpretation and orchestration in status, doctor, and connect, so it probes the exact in-sandbox route and fails closed when OpenShell cannot return trusted OK or BROKEN evidence.
  • Source-fix constraint: Read-only diagnostics cannot repair OpenShell infrastructure, and an inconclusive result is inherently lossy. connect must not open SSH or mutate route state on inconclusive evidence. This fail-closed behavior is a permanent security boundary, not a temporary workaround.
  • Regression and removal contract: Checked-in parser, flow, CLI, missing-CA, 401/403, DCode argv/proxy, and redaction tests cover deterministic fault injection. The DCode wrapper may be removed only if OpenShell provides an agent-independent structured route-health API that preserves its CA and login-shell contract; fail-closed handling remains.
  • Runtime justification: A separate standalone live artifact would duplicate the repository's existing typed E2E lanes. Exact head 130e74f3c520aa82db86fd80e830eff362390b08 passed the required live jobs and OpenClaw and DCode live targets; exact-head macOS E2E and arm64 image/build checks also passed. Induced broken-route, auth, and CA faults remain deterministic checked-in tests to avoid destructive shared-state mutation.
  • PR sequencing: fix(status): make inference route health authoritative #6412 is foundational. Merge it first, then rebase feat(status): warn when the gateway route drifts from the sandbox's recorded route #6465 and integrate its additive route-drift warning into the final status-snapshot shape.

Summary by CodeRabbit

  • New Features

    • Added clearer, authoritative inference health checks and diagnostics for sandbox status and doctor commands.
    • connect now fails closed when the in-sandbox inference route cannot be trusted, with safer redacted error details.
  • Bug Fixes

    • Improved handling of reachable, unhealthy, unreachable, and not-probed inference states.
    • Fixed status exit behavior so inference-route failures correctly return a non-zero result.
  • Documentation

    • Updated troubleshooting and command docs to explain the new inference health and proxy diagnostic output.

Signed-off-by: Apurv Kumaria akumaria@nvidia.com
Co-authored-by: harjoth harjoth.khara@gmail.com
Co-authored-by: Souvik Ghosh 138186578+souvikDevloper@users.noreply.github.com

Probe inference.local from the sandbox for status and doctor.
Classify HTTP transport boundaries consistently with connect.
Keep provider checks as non-authoritative upstream diagnostics.

Co-authored-by: harjoth <harjoth.khara@gmail.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

apurvvkumaria commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Contributor credit: this PR supersedes #6203 and #6264 while retaining the original work. @harjothkhara authored the original inference.local route-health implementation in #6203, and @souvikDevloper contributed the typed dependency-injection/test seam in #6264. Both are recorded as Co-authored-by in the signed commit and PR description. Thank you both for the foundation and reviewable test seams that made this consolidated fix possible.

@github-code-quality

github-code-quality Bot commented Jul 7, 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 remains at 76%, unchanged from the branch.

Show a code coverage summary of the most impacted files.
File 0b11898 2e17464 +/-
src/lib/inferen...board-probes.ts 93% 89% -4%
src/lib/shields...nsition-lock.ts 85% 87% +2%
src/lib/actions...dbox/connect.ts 72% 76% +4%
src/lib/actions.../status-text.ts 42% 48% +6%
src/lib/actions...ard-recovery.ts 82% 91% +9%
src/lib/actions...tus-snapshot.ts 79% 91% +12%
src/lib/actions...ess-recovery.ts 64% 79% +15%
src/lib/sandbox...vileged-exec.ts 45% 89% +44%
src/lib/actions...or-inference.ts 0% 97% +97%
src/lib/actions...route-health.ts 0% 100% +100%

Updated July 08, 2026 21:10 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR makes an in-sandbox probe of https://inference.local/v1/models the authoritative inference health signal for status, doctor, and connect, replacing upstream-only probing. It adds shared probe parsing/classification, a new gateway probe module, refactors doctor/status health composition, updates exit-code logic, extends tests, and revises documentation accordingly.

Changes

Inference route authority fix

Layer / File(s) Summary
Probe result parsing contract
src/lib/actions/sandbox/connect-inference-route-probe.ts, connect-inference-route-probe.test.ts
Adds CA-bundle validation, a simplified OK/BROKEN <code> stdout contract, classifyInferenceRouteFailureLabel, and exported parseSandboxInferenceRouteProbeResult, with new tests covering script generation and parsing edge cases.
Connect route probing and repair logic
src/lib/actions/sandbox/connect.ts, connect-flow.test.ts, connect-route-repair.test.ts, connect-route-repair-inconclusive.test.ts
Delegates probe classification to the shared parser, changes non-broken/indeterminate probe handling to fail closed, updates unrecoverable-route messaging with redacted details, and adds tests for inconclusive repair outcomes.
In-sandbox inference gateway probe module
src/lib/actions/sandbox/inference-route-health.ts, inference-route-health.test.ts, process-recovery.ts, process-recovery.test.ts
Introduces probeSandboxInferenceGatewayHealth built on the shared parser and removes the older curl-based probe from process-recovery.ts.
Doctor inference checks module
src/lib/actions/sandbox/doctor-inference.ts, doctor.ts
Adds a dedicated module producing an authoritative gateway-route check plus non-authoritative upstream diagnostics, replacing local doctor.ts logic.
Doctor flow and CLI adapter tests
doctor-flow.test.ts, src/commands/sandbox/oclif-command-adapters.test.ts
Updates mocks/labels for renamed inference checks and adds a JSON adapter test asserting non-zero exit on failing inference.
Status snapshot, text, and command wiring
status-snapshot.ts, status-text.ts, status.ts (lib and command), status-inference.test.ts, status-flow.test.ts
Rebuilds inferenceHealth from the route probe, adds isInferenceHealthFailing, and derives non-zero exit codes from failing/unprobed inference health.
CLI test fixtures for sandbox exec inference probe
test/cli/*, test/*.test.ts, test/support/status-flow-test-harness.ts
Extends fake openshell stubs across many CLI tests to handle sandbox exec inference probe calls.
Documentation updates
docs/reference/commands.mdx, docs/monitoring/monitor-sandbox-activity.mdx, docs/reference/troubleshooting.mdx, docs/inference/use-local-inference.mdx
Describes the in-sandbox inference.local probe as authoritative and clarifies host/provider diagnostics as non-authoritative.

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

Sequence Diagram(s)

sequenceDiagram
  participant StatusCommand
  participant collectSandboxStatusSnapshot
  participant probeSandboxInferenceGatewayHealth
  participant OpenShell

  StatusCommand->>collectSandboxStatusSnapshot: collect status snapshot
  collectSandboxStatusSnapshot->>probeSandboxInferenceGatewayHealth: probe inference.local route
  probeSandboxInferenceGatewayHealth->>OpenShell: capture curl probe result
  OpenShell-->>probeSandboxInferenceGatewayHealth: OK/BROKEN httpStatus
  probeSandboxInferenceGatewayHealth-->>collectSandboxStatusSnapshot: SandboxInferenceRouteHealth or null
  collectSandboxStatusSnapshot-->>StatusCommand: report with authoritative inferenceHealth
Loading
sequenceDiagram
  participant ConnectCommand
  participant probeSandboxInferenceRoute
  participant parseSandboxInferenceRouteProbeResult
  participant repairSandboxInferenceRouteWithDeps

  ConnectCommand->>probeSandboxInferenceRoute: probe route before SSH
  probeSandboxInferenceRoute->>parseSandboxInferenceRouteProbeResult: parse OK/BROKEN status
  parseSandboxInferenceRouteProbeResult-->>probeSandboxInferenceRoute: healthy/broken/detail
  probeSandboxInferenceRoute-->>repairSandboxInferenceRouteWithDeps: initial probe result
  repairSandboxInferenceRouteWithDeps-->>ConnectCommand: healthy: false, repairAttempted: false (fail closed)
Loading

Suggested labels: area: sandbox, area: e2e, area: architecture

Suggested reviewers: cv, jyaunches

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR aligns with #6192 by making status, doctor, and connect rely on the in-sandbox inference.local route and treating upstream checks as non-authoritative.
Out of Scope Changes check ✅ Passed The code and docs changes are all tied to the inference-route health fix, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately captures the main change: making inference route health authoritative for status checks.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/6192-authoritative-inference-route

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

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: inference-routing, cloud-inference, sandbox-operations, sandbox-rlimits-connect
Optional E2E: diagnostics, ollama-auth-proxy, issue-4434-tui-unreachable-inference

Dispatch hint: inference-routing,cloud-inference,sandbox-operations,sandbox-rlimits-connect

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • inference-routing (medium): Required because the PR changes inference route probing/classification and route repair behavior. This job exercises real onboarding and inference.local routing boundaries.
  • cloud-inference (medium): Required to validate a hosted OpenClaw sandbox still onboards and can complete real inference through inference.local after the route-health changes.
  • sandbox-operations (medium): Required because the PR changes sandbox status, recovery/status text, and process recovery paths. This job exercises real status, agent inference.local use, logs, and recovery contracts.
  • sandbox-rlimits-connect (medium): Required because connect.ts now performs an authoritative inference.local route probe before opening SSH. This explicit connect E2E is the closest existing real SSH/connect flow.

Optional E2E

  • diagnostics (medium): Useful additional confidence for the changed status diagnostics and redaction behavior because it runs install/onboard, sandbox exec/status, and debug archive credential-redaction checks.
  • ollama-auth-proxy (medium): Optional adjacent coverage for local Ollama auth-proxy diagnostics described in the docs and surfaced as status subprobes, although the auth-proxy implementation itself was not changed.
  • issue-4434-tui-unreachable-inference (high): Optional high-cost confidence for user-facing behavior when inference.local becomes unreachable; it complements but does not directly cover status/doctor/connect route-probe semantics.

New E2E recommendations

  • status and doctor authoritative inference route failures (high): Existing live jobs cover healthy status and inference.local chat, but there is no focused E2E that intentionally leaves the upstream/provider diagnostic healthy while breaking or making unavailable the in-sandbox inference.local /v1/models probe, then asserts nemoclaw <name> status --json and nemoclaw <name> doctor --json fail closed with redacted details.
    • Suggested test: Add a live E2E target such as inference-route-health-fail-closed that onboards a sandbox, sabotages the inference.local route or OpenShell exec probe boundary in a controlled way, and verifies status/doctor exit status and JSON/text diagnostics.
  • connect route-probe inconclusive vs broken repair policy (high): Unit tests cover the new distinction between inconclusive and broken route probes, but existing live connect coverage does not prove that a real connect refuses SSH without repair on an inconclusive initial probe and only repairs when the route is trusted-broken.
    • Suggested test: Add a live connect E2E that creates a real sandbox, induces a trusted BROKEN inference.local result and an inconclusive probe result in separate phases, and asserts connect repair/SSH behavior for each.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: inference-routing,cloud-inference,sandbox-operations,sandbox-rlimits-connect

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: ubuntu-repo-cloud-openclaw, ubuntu-repo-cloud-langchain-deepagents-code, ubuntu-repo-docker-post-reboot-recovery
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field targets=ubuntu-repo-cloud-openclaw
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field targets=ubuntu-repo-cloud-langchain-deepagents-code
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field targets=ubuntu-repo-docker-post-reboot-recovery

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • ubuntu-repo-cloud-openclaw: Core sandbox connect/status/doctor and inference-route health logic changed; the standard Ubuntu Docker cloud OpenClaw target is the smallest live-supported target that exercises the primary OpenClaw route, readiness, and inference checks.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field targets=ubuntu-repo-cloud-openclaw
  • ubuntu-repo-cloud-langchain-deepagents-code: The connect inference route probe now has a Deep Agents Code-specific login-shell CA/proxy path; this live-supported target exercises that terminal-agent onboarding and managed inference.local route contract.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field targets=ubuntu-repo-cloud-langchain-deepagents-code
  • ubuntu-repo-docker-post-reboot-recovery: Process recovery and status behavior changed; the post-reboot recovery target is the live-supported lifecycle target that exercises status/recovery invariants after Docker-driver sandbox disruption.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field targets=ubuntu-repo-docker-post-reboot-recovery

Optional E2E targets

  • None.

Relevant changed files

  • src/commands/sandbox/status.ts
  • src/lib/actions/sandbox/connect-inference-route-probe.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/doctor-inference.ts
  • src/lib/actions/sandbox/doctor.ts
  • src/lib/actions/sandbox/inference-route-health.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/status-snapshot.ts
  • src/lib/actions/sandbox/status-text.ts
  • src/lib/actions/sandbox/status.ts

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Source-of-truth review needed: DCode login-shell route-probe output parsing.
Open items: 0 required · 2 warnings · 0 suggestions · 8 test follow-ups
Since last review: 2 prior items resolved · 0 still apply · 1 new item found

Action checklist

  • PRA-1 Resolve or justify: Source-of-truth review needed: DCode login-shell route-probe output parsing
  • PRA-2 Resolve or justify: Reject DCode login-shell stdout before trusted route-probe output in src/lib/actions/sandbox/connect-inference-route-probe.ts:67
  • 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: Acceptance clause
  • PRA-T6 Add or justify test follow-up: Acceptance clause
  • PRA-T7 Add or justify test follow-up: Acceptance clause
  • PRA-T8 Add or justify test follow-up: DCode login-shell route-probe output parsing

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify security src/lib/actions/sandbox/connect-inference-route-probe.ts:67 Keep the DCode CA/proxy behavior, but make the trusted probe grammar unspoofable. For example, redirect login-shell startup stdout away from the capture before executing the probe, or emit a unique probe marker from the final script and reject any preamble before that marker. Then parse only the marker-bound probe result and treat any preamble or missing marker as unavailable evidence.
Review findings by urgency: 0 required fixes, 2 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

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

PRA-1 Resolve/justify — Source-of-truth review needed: DCode login-shell route-probe output parsing

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Missing: a DCode regression where profile/startup stdout emits `OK 200` or `BROKEN 503` before the real probe. The expected result should be unavailable evidence, not healthy/broken.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` runs `HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`; `parseSandboxInferenceRouteProbeResult()` trusts route grammar at the beginning of combined stdout.

PRA-2 Resolve/justify — Reject DCode login-shell stdout before trusted route-probe output

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:67
  • Category: security
  • Problem: The DCode probe intentionally runs a login shell before the curl probe so `/sandbox/.profile` can rebuild the proxy environment. That means mutable in-sandbox startup files can write to stdout before the probe runs. `parseSandboxInferenceRouteProbeResult()` trusts `OK ###` or `BROKEN ###` at the beginning of the combined stdout when the exec status is 0, so a profile that prints `OK 200` can make connect/status/doctor accept a healthy route without using the curl result, and a profile that prints `BROKEN 503` can authorize route repair from sandbox-controlled output.
  • Impact: A sandbox-controlled profile can contaminate host-side route evidence. In the healthy-spoof case, `connect`, `status`, and `doctor` can report an agent route as healthy when `https://inference.local/v1/models\` is still broken. In the broken-spoof case, `connect` can perform DNS or route mutation based on untrusted startup output rather than the authoritative curl probe.
  • Recommended action: Keep the DCode CA/proxy behavior, but make the trusted probe grammar unspoofable. For example, redirect login-shell startup stdout away from the capture before executing the probe, or emit a unique probe marker from the final script and reject any preamble before that marker. Then parse only the marker-bound probe result and treat any preamble or missing marker as unavailable evidence.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` and `INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT` in `src/lib/actions/sandbox/connect-inference-route-probe.ts`, then read `parseSandboxInferenceRouteProbeResult()` in the same file. The wrapper invokes `bash -lc "$1" "$CA_BUNDLE"` with `HOME=/sandbox`, and the parser accepts `OK ###` / `BROKEN ###` from the start of combined stdout.
  • Missing regression test: Add a DCode-specific regression where the login-shell/profile preamble writes `OK 200` or `BROKEN 503` before the real probe output. Assert `parseSandboxInferenceRouteProbeResult()` or the DCode route-health path treats that output as unavailable, not healthy or broken, and assert connect does not repair or open SSH from the spoofed preamble.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` and `INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT` in `src/lib/actions/sandbox/connect-inference-route-probe.ts`, then read `parseSandboxInferenceRouteProbeResult()` in the same file. The wrapper invokes `bash -lc "$1" "$CA_BUNDLE"` with `HOME=/sandbox`, and the parser accepts `OK ###` / `BROKEN ###` from the start of combined stdout.
  • Evidence: `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` executes `env ... HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`, so shell startup output can precede the probe. `parseSandboxInferenceRouteProbeResult()` then runs `/^(OK|BROKEN)\s+([0-9]{3})\b/` against the normalized captured output and only checks `result.status === 0` before trusting the match.

💡 In-scope improvements

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

  • None.
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 — DCode login-shell profile stdout that prints `OK 200` or `BROKEN 503` before the route probe is rejected as unavailable evidence and does not allow connect to repair or open SSH.. Checked-in tests cover most deterministic parser, status, doctor, and connect behavior, including missing CA, failed exec, malformed statuses, 401/403, and no-repair/no-SSH. Runtime validation remains advisable because the highest-risk behavior crosses real OpenShell exec framing, CA injection, DNS, TLS, proxy provisioning, and DCode login-shell profile loading.
  • PRA-T2 Runtime validation — Real OpenShell missing or unreadable inference CA makes connect, status --json, and doctor --json fail closed without DNS repair, inference route reapply, or SSH connect.. Checked-in tests cover most deterministic parser, status, doctor, and connect behavior, including missing CA, failed exec, malformed statuses, 401/403, and no-repair/no-SSH. Runtime validation remains advisable because the highest-risk behavior crosses real OpenShell exec framing, CA injection, DNS, TLS, proxy provisioning, and DCode login-shell profile loading.
  • PRA-T3 Runtime validation — Real `https://inference.local/v1/models\` responses with HTTP 401 or 403 are classified healthy by connect, status --json, and doctor --json while failed upstream diagnostics remain non-authoritative.. Checked-in tests cover most deterministic parser, status, doctor, and connect behavior, including missing CA, failed exec, malformed statuses, 401/403, and no-repair/no-SSH. Runtime validation remains advisable because the highest-risk behavior crosses real OpenShell exec framing, CA injection, DNS, TLS, proxy provisioning, and DCode login-shell profile loading.
  • PRA-T4 Runtime validation — Real LangChain Deep Agents Code route probe preserves the captured OpenShell CA path after login-shell profile loading and clears inherited proxy variables before reconstructing the DCode proxy environment.. Checked-in tests cover most deterministic parser, status, doctor, and connect behavior, including missing CA, failed exec, malformed statuses, 401/403, and no-repair/no-SSH. Runtime validation remains advisable because the highest-risk behavior crosses real OpenShell exec framing, CA injection, DNS, TLS, proxy provisioning, and DCode login-shell profile loading.
  • PRA-T5 Acceptance clause — `status` and `doctor` probe the actual `inference.local` route the agent uses (the same route `connect` probes) and report it BROKEN when it is unreachable, so the three commands agree. — add test evidence or identify existing coverage. The commands share the route-probe builder and parser, and tests cover 000, 5xx, unavailable probes, 401/403, and DCode argv selection. The remaining partial gap is that the DCode login-shell path can include mutable profile stdout before the probe result, so the shared parser can still trust contaminated evidence unless the preamble is rejected.
  • PRA-T6 Acceptance clause — A green "healthy" should require the route the agent actually calls to be reachable, not just the upstream provider endpoint. — add test evidence or identify existing coverage. For normal and mocked probe output, top-level status/doctor health is based on `https://inference.local/v1/models\`, and upstream failures remain diagnostic when the route works. The DCode profile-stdout spoofing finding prevents marking this fully met for all agent paths because a mutable login-shell preamble can produce a green result before the actual route probe runs.
  • PRA-T7 Acceptance clause — ✨ Thanks for the clear report with logs and root cause. The health check should probe the inference.local route the agent uses, not the upstream endpoint directly. — add test evidence or identify existing coverage. Status and doctor now call the in-sandbox route probe and keep direct provider health as diagnostics only. The DCode profile-output contamination finding leaves one agent-specific route where the captured output can be influenced before the actual probe output.
  • PRA-T8 DCode login-shell route-probe output parsing — Missing: a DCode regression where profile/startup stdout emits `OK 200` or `BROKEN 503` before the real probe. The expected result should be unavailable evidence, not healthy/broken.. `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` runs `HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`; `parseSandboxInferenceRouteProbeResult()` trusts route grammar at the beginning of combined stdout.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: DCode login-shell route-probe output parsing

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Missing: a DCode regression where profile/startup stdout emits `OK 200` or `BROKEN 503` before the real probe. The expected result should be unavailable evidence, not healthy/broken.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` runs `HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`; `parseSandboxInferenceRouteProbeResult()` trusts route grammar at the beginning of combined stdout.

PRA-2 Resolve/justify — Reject DCode login-shell stdout before trusted route-probe output

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:67
  • Category: security
  • Problem: The DCode probe intentionally runs a login shell before the curl probe so `/sandbox/.profile` can rebuild the proxy environment. That means mutable in-sandbox startup files can write to stdout before the probe runs. `parseSandboxInferenceRouteProbeResult()` trusts `OK ###` or `BROKEN ###` at the beginning of the combined stdout when the exec status is 0, so a profile that prints `OK 200` can make connect/status/doctor accept a healthy route without using the curl result, and a profile that prints `BROKEN 503` can authorize route repair from sandbox-controlled output.
  • Impact: A sandbox-controlled profile can contaminate host-side route evidence. In the healthy-spoof case, `connect`, `status`, and `doctor` can report an agent route as healthy when `https://inference.local/v1/models\` is still broken. In the broken-spoof case, `connect` can perform DNS or route mutation based on untrusted startup output rather than the authoritative curl probe.
  • Recommended action: Keep the DCode CA/proxy behavior, but make the trusted probe grammar unspoofable. For example, redirect login-shell startup stdout away from the capture before executing the probe, or emit a unique probe marker from the final script and reject any preamble before that marker. Then parse only the marker-bound probe result and treat any preamble or missing marker as unavailable evidence.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` and `INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT` in `src/lib/actions/sandbox/connect-inference-route-probe.ts`, then read `parseSandboxInferenceRouteProbeResult()` in the same file. The wrapper invokes `bash -lc "$1" "$CA_BUNDLE"` with `HOME=/sandbox`, and the parser accepts `OK ###` / `BROKEN ###` from the start of combined stdout.
  • Missing regression test: Add a DCode-specific regression where the login-shell/profile preamble writes `OK 200` or `BROKEN 503` before the real probe output. Assert `parseSandboxInferenceRouteProbeResult()` or the DCode route-health path treats that output as unavailable, not healthy or broken, and assert connect does not repair or open SSH from the spoofed preamble.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` and `INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT` in `src/lib/actions/sandbox/connect-inference-route-probe.ts`, then read `parseSandboxInferenceRouteProbeResult()` in the same file. The wrapper invokes `bash -lc "$1" "$CA_BUNDLE"` with `HOME=/sandbox`, and the parser accepts `OK ###` / `BROKEN ###` from the start of combined stdout.
  • Evidence: `DCODE_INFERENCE_ROUTE_PROBE_WRAPPER` executes `env ... HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`, so shell startup output can precede the probe. `parseSandboxInferenceRouteProbeResult()` then runs `/^(OK|BROKEN)\s+([0-9]{3})\b/` against the normalized captured output and only checks `result.status === 0` before trusting the match.

Workflow run details

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

@github-actions

github-actions Bot commented Jul 7, 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: connect.ts monolith at 1178 lines handling 5+ orthogonal flows; then add or justify PRA-T1.
Open items: 3 required · 6 warnings · 6 suggestions · 8 test follow-ups
Since last review: 0 prior items resolved · 11 still apply · 4 new items found

Action checklist

  • PRA-1 Fix: connect.ts monolith at 1178 lines handling 5+ orthogonal flows in src/lib/actions/sandbox/connect.ts:1
  • PRA-2 Fix: connect-flow.test.ts monolith growth +126 lines (now 516) — blocker threshold in src/lib/actions/sandbox/connect-flow.test.ts:1
  • PRA-3 Fix: No end-to-end runtime validation tests for authoritative route behavior in test/cli/sandbox-status-json.test.ts:1
  • PRA-4 Resolve or justify: Source-of-truth: CA validation only checks existence/readability, not PEM format in src/lib/actions/sandbox/connect-inference-route-probe.ts:20
  • PRA-5 Resolve or justify: Source-of-truth: argv[0] convention for DCode CA bundle passing in src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • PRA-6 Resolve or justify: CA bundle validation only checks existence/readability, not PEM format in src/lib/actions/sandbox/connect-inference-route-probe.ts:20
  • PRA-7 Resolve or justify: Unusual argv[0] pattern for CA bundle passing in DCode wrapper in src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • PRA-8 Resolve or justify: Status exit code change for authoritative inference route failure in src/commands/sandbox/status.ts:40
  • PRA-9 Resolve or justify: DCode probe test only verifies argv shape, not runtime proxy clearing behavior in src/lib/actions/sandbox/connect-inference-route-probe.test.ts:15
  • 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: No end-to-end runtime validation tests for authoritative route behavior
  • PRA-T7 Add or justify test follow-up: DCode probe test only verifies argv shape, not runtime proxy clearing behavior
  • PRA-T8 Add or justify test follow-up: CLI e2e tests use shell stubs, not real OpenShell exec
  • PRA-10 In-scope improvement: Doctor flow extraction created doctor-inference.ts but no behavioral drift verification in src/lib/actions/sandbox/doctor-inference.ts:1
  • PRA-11 In-scope improvement: CA validation doesn't verify non-empty regular file in src/lib/actions/sandbox/connect-inference-route-probe.ts:31
  • PRA-12 In-scope improvement: Error redaction timing gap in probe failure path in src/lib/actions/sandbox/status-snapshot.ts:274
  • PRA-13 In-scope improvement: CLI e2e tests use shell stubs, not real OpenShell exec in test/cli/sandbox-status-json.test.ts:1
  • PRA-14 In-scope improvement: Troubleshooting docs lack remediation guidance per failureLabel in docs/inference/use-local-inference.mdx:1
  • PRA-15 In-scope improvement: Refactor argv[0] CA passing to explicit env var for clarity in src/lib/actions/sandbox/connect-inference-route-probe.ts:55

Findings index

ID Severity Category Location Required action
PRA-1 Required architecture src/lib/actions/sandbox/connect.ts:1 Extract remaining flows: connect-flow.ts (orchestration), connect-repair.ts (route repair), connect-process.ts (process recovery), connect-ssh.ts (SSH attach). Keep fail-closed inconclusive handling atomic in connect-flow.ts.
PRA-2 Required architecture src/lib/actions/sandbox/connect-flow.test.ts:1 Move new inconclusive-probe tests to connect-route-repair-inconclusive.test.ts (already created) or a new connect-fail-closed.test.ts. Keep connect-flow.test.ts focused on SSH attach/terminal flow.
PRA-3 Required tests test/cli/sandbox-status-json.test.ts:1 Add 6 targeted runtime tests in existing CLI suite: (1) status --json exits 1 with inferenceHealth.ok=false on broken inference.local; (2) doctor --json shows authoritative fail + upstream ok; (3) connect fails closed on inconclusive probe; (4) DCode agent CA capture + proxy clearing argv shape; (5) missing CA bundle returns UNAVAILABLE; (6) framed OpenShell output parsed correctly.
PRA-4 Resolve/justify architecture src/lib/actions/sandbox/connect-inference-route-probe.ts:20 Add lightweight PEM format check (e.g., `grep -q 'BEGIN CERTIFICATE' "$CA_BUNDLE"`) before curl, or document that BROKEN 000 covers both missing CA and TLS handshake failures. Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-5 Resolve/justify architecture src/lib/actions/sandbox/connect-inference-route-probe.ts:55 Refactor to pass CA_BUNDLE as explicit environment variable (e.g., NEMOCLAW_CA_BUNDLE) or positional parameter to the inner script for clarity, or add prominent comment explaining the argv[0] convention. Add test with mocked login shell verifying proxy env vars are unset in child curl process.
PRA-6 Resolve/justify security src/lib/actions/sandbox/connect-inference-route-probe.ts:20 Add lightweight PEM format check (`grep -q 'BEGIN CERTIFICATE' "$CA_BUNDLE"`) before curl invocation, or explicitly document the ambiguity in the UNAVAILABLE/BROKEN classification.
PRA-7 Resolve/justify correctness src/lib/actions/sandbox/connect-inference-route-probe.ts:55 Refactor to pass CA_BUNDLE as explicit environment variable (e.g., NEMOCLAW_CA_BUNDLE) or positional parameter. Add test with mocked login shell verifying proxy env vars are unset in child curl process.
PRA-8 Resolve/justify correctness src/commands/sandbox/status.ts:40 Document exit code change in release notes. Consider if transition period or flag needed for automation consumers. Verify CI pipelines handle new behavior.
PRA-9 Resolve/justify tests src/lib/actions/sandbox/connect-inference-route-probe.test.ts:15 Add test with mocked login shell that verifies proxy env vars are unset in the child curl process, covering failure paths. This is local to changed code and should be fixed in this PR.
PRA-10 Improvement architecture src/lib/actions/sandbox/doctor-inference.ts:1 Run full doctor test suite; compare pre/post behavior for edge cases (gateway unreachable, sandbox unreachable, upstream probe throws). This is a verification step, not a code change.
PRA-11 Improvement correctness src/lib/actions/sandbox/connect-inference-route-probe.ts:31 Add `[ -s "$CA_BUNDLE" ]` to verify non-empty file.
PRA-12 Improvement security src/lib/actions/sandbox/status-snapshot.ts:274 Ensure all error paths that could expose secrets are redacted before logging. Consider centralizing error redaction for probe failures.
PRA-13 Improvement tests test/cli/sandbox-status-json.test.ts:1 Keep the stub-based tests for fast feedback; add a separate integration test suite (opt-in, slower) that runs against a real sandbox with controlled inference.local failures.
PRA-14 Improvement docs docs/inference/use-local-inference.mdx:1 Add remediation guidance per failureLabel: unhealthy = check gateway logs/upstream; unreachable = check DNS/gateway/proxy; not probed = check sandbox connectivity/doctor.
PRA-15 Improvement scope src/lib/actions/sandbox/connect-inference-route-probe.ts:55 Change DCODE_INFERENCE_ROUTE_PROBE_WRAPPER to export CA_BUNDLE as environment variable and have inner script read from env. Update INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT accordingly.

🚨 Required before merge

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

PRA-1 Required — connect.ts monolith at 1178 lines handling 5+ orthogonal flows

  • Location: src/lib/actions/sandbox/connect.ts:1
  • Category: architecture
  • Problem: connect.ts grew to 1178 lines (+14 this PR) handling process recovery, DNS repair, route reconcile, auto-pair, SSH attach, and authoritative probe orchestration. New inference-route-health.ts (81 lines) and connect-inference-route-probe.ts (109 lines) are good extractions but orchestration layer continues accumulating responsibilities. Fail-closed inconclusive handling is mixed with repair orchestration in the same file.
  • Impact: Monolith growth makes security review harder, increases coupling, and raises risk that changes to one flow inadvertently affect another. Previous review PRA-3 still applies.
  • Required action: Extract remaining flows: connect-flow.ts (orchestration), connect-repair.ts (route repair), connect-process.ts (process recovery), connect-ssh.ts (SSH attach). Keep fail-closed inconclusive handling atomic in connect-flow.ts.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check connect.ts line count and import graph; verify inference-route-health.ts and connect-inference-route-probe.ts are imported rather than inlined.
  • Missing regression test: None needed — this is a refactor suggestion. Existing tests would validate behavior preservation.
  • Done when: The required change is committed and verification passes: Check connect.ts line count and import graph; verify inference-route-health.ts and connect-inference-route-probe.ts are imported rather than inlined.
  • Evidence: monolithDeltas shows connect.ts +14 lines, severity warning; connect-flow.test.ts +126 lines (blocker threshold); 22 commits in PR showing iterative growth

PRA-2 Required — connect-flow.test.ts monolith growth +126 lines (now 516) — blocker threshold

  • Location: src/lib/actions/sandbox/connect-flow.test.ts:1
  • Category: architecture
  • Problem: connect-flow.test.ts grew +126 lines this PR with new inconclusive-probe tests added inline rather than in a focused test file. New connect-route-repair-inconclusive.test.ts (3 tests) exists but connect-flow.test.ts still accumulates fail-closed behavior tests. Test monolith growth parallels production code monolith.
  • Impact: Harder to maintain, review, and isolate test failures. Inconclusive-probe tests are conceptually separate from SSH attach/terminal flow tests.
  • Required action: Move new inconclusive-probe tests to connect-route-repair-inconclusive.test.ts (already created) or a new connect-fail-closed.test.ts. Keep connect-flow.test.ts focused on SSH attach/terminal flow.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Count test blocks in connect-flow.test.ts vs connect-route-repair-inconclusive.test.ts; verify no duplicate inconclusive coverage.
  • Missing regression test: None — reorganization of existing tests.
  • Done when: The required change is committed and verification passes: Count test blocks in connect-flow.test.ts vs connect-route-repair-inconclusive.test.ts; verify no duplicate inconclusive coverage.
  • Evidence: monolithDeltas shows connect-flow.test.ts +126 lines, severity blocker; 4 new inconclusive tests in connect-flow.test.ts (lines 241-395) duplicate concept with connect-route-repair-inconclusive.test.ts

PRA-3 Required — No end-to-end runtime validation tests for authoritative route behavior

  • Location: test/cli/sandbox-status-json.test.ts:1
  • Category: tests
  • Problem: Unit tests comprehensively cover parser/classification logic (100+ test blocks across 20 changed test files), but no end-to-end runtime validation tests exercise the authoritative probe against a real sandbox with controlled inference.local failures. Integration gaps between unit-tested components and the real OpenShell exec/DNS/TLS/proxy stack could surface in production.
  • Impact: False confidence from unit tests; real OpenShell sandbox exec, DNS resolution, TLS handshake, proxy provisioning, and response framing not exercised. Production bugs in the integration layer would not be caught.
  • Required action: Add 6 targeted runtime tests in existing CLI suite: (1) status --json exits 1 with inferenceHealth.ok=false on broken inference.local; (2) doctor --json shows authoritative fail + upstream ok; (3) connect fails closed on inconclusive probe; (4) DCode agent CA capture + proxy clearing argv shape; (5) missing CA bundle returns UNAVAILABLE; (6) framed OpenShell output parsed correctly.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run new integration tests against a test sandbox with controlled inference.local failures (gateway returning 503, DNS failure, CA missing, timeout).
  • Missing regression test: 6 end-to-end CLI tests exercising the authoritative route path with real sandbox exec, covering the 6 behaviors listed in recommendation.
  • Done when: The required change is committed and verification passes: Run new integration tests against a test sandbox with controlled inference.local failures (gateway returning 503, DNS failure, CA missing, timeout).
  • Evidence: pr_review_validation_context testDepth verdict: runtime_validation_recommended; 13 CLI stub tests exist but use shell stubs not real OpenShell exec
Review findings by urgency: 3 required fixes, 6 items to resolve/justify, 6 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-4 Resolve/justify — Source-of-truth: CA validation only checks existence/readability, not PEM format

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:20
  • Category: architecture
  • Problem: INFERENCE_ROUTE_CA_VALIDATION only checks `[ -f "$CA_BUNDLE" ] && [ -r "$CA_BUNDLE" ]` — no PEM format validation. Invalid PEM would surface as curl TLS error (classified as BROKEN 000) but the error class is ambiguous — it could be missing CA, unreadable CA, malformed PEM, or actual TLS handshake failure. The 'UNAVAILABLE' marker is only for missing/unreadable CA.
  • Impact: Reduces diagnostic precision and could mask configuration issues. An invalid PEM file would cause curl to fail with a TLS error, classified as BROKEN 000 (unreachable), indistinguishable from a missing CA or actual network failure.
  • Recommended action: Add lightweight PEM format check (e.g., `grep -q 'BEGIN CERTIFICATE' "$CA_BUNDLE"`) before curl, or document that BROKEN 000 covers both missing CA and TLS handshake failures. Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect INFERENCE_ROUTE_CA_VALIDATION in connect-inference-route-probe.ts; verify if PEM format validation exists or is documented as intentionally omitted.
  • Missing regression test: Test with malformed PEM CA bundle to verify classification (should be UNAVAILABLE or BROKEN with clear distinction).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect INFERENCE_ROUTE_CA_VALIDATION in connect-inference-route-probe.ts; verify if PEM format validation exists or is documented as intentionally omitted.
  • Evidence: connect-inference-route-probe.ts:26-31 INFERENCE_ROUTE_CA_VALIDATION; connect-inference-route-probe.test.ts 'reports unavailable before curl when the injected CA bundle is missing' test exists but no malformed PEM test

PRA-5 Resolve/justify — Source-of-truth: argv[0] convention for DCode CA bundle passing

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • Category: architecture
  • Problem: DCODE_INFERENCE_ROUTE_PROBE_WRAPPER passes CA_BUNDLE as argv[0] to `bash -lc "$1" "$CA_BUNDLE"` where the inner script reads it as `$0`. This is unconventional and fragile — argv[0] is traditionally the script name. No test verifies the login shell doesn't mutate argv[0] before the inner script runs.
  • Impact: Relies on bash preserving argv[0] through the login shell, which is not guaranteed across shell implementations or future changes. Could silently break CA injection for DCode agents.
  • Recommended action: Refactor to pass CA_BUNDLE as explicit environment variable (e.g., NEMOCLAW_CA_BUNDLE) or positional parameter to the inner script for clarity, or add prominent comment explaining the argv[0] convention. Add test with mocked login shell verifying proxy env vars are unset in child curl process.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT in connect-inference-route-probe.ts; verify comment explains argv[0] usage.
  • Missing regression test: Test with mocked login shell that verifies proxy env vars are unset in the child curl process, covering failure paths.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT in connect-inference-route-probe.ts; verify comment explains argv[0] usage.
  • Evidence: connect-inference-route-probe.ts:55-61 DCODE_INFERENCE_ROUTE_PROBE_WRAPPER; connect-inference-route-probe.test.ts:15 only verifies argv shape contains '-u HTTPS_PROXY', not runtime proxy clearing

PRA-6 Resolve/justify — CA bundle validation only checks existence/readability, not PEM format

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:20
  • Category: security
  • Problem: CA validation only checks existence/readability, not PEM format. An invalid PEM file would cause curl to fail with a TLS error, classified as BROKEN 000 (unreachable), indistinguishable from a missing CA or actual network failure. This reduces diagnostic precision and could mask configuration issues.
  • Impact: Security diagnostic precision degraded; configuration issues (malformed CA) masked as network failures, increasing MTTR for real incidents.
  • Recommended action: Add lightweight PEM format check (`grep -q 'BEGIN CERTIFICATE' "$CA_BUNDLE"`) before curl invocation, or explicitly document the ambiguity in the UNAVAILABLE/BROKEN classification.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run probe with malformed PEM file; verify output classification and error message clarity.
  • Missing regression test: Unit test: probe with malformed PEM CA bundle returns UNAVAILABLE (not BROKEN) or BROKEN with distinct detail.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run probe with malformed PEM file; verify output classification and error message clarity.
  • Evidence: INFERENCE_ROUTE_CA_VALIDATION at line 26-31; no PEM format validation in script or parser

PRA-7 Resolve/justify — Unusual argv[0] pattern for CA bundle passing in DCode wrapper

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • Category: correctness
  • Problem: The wrapper passes CA_BUNDLE as argv[0] to `bash -lc "$1" "$CA_BUNDLE"`, then inner script reads `$0`. This relies on bash preserving argv[0] through the login shell, which is not guaranteed across shell implementations or future changes. No test verifies the proxy env vars (-u HTTP_PROXY etc.) are actually unset in the child curl process.
  • Impact: Silent CA injection or proxy clearing failures for DCode agents could cause probe to use wrong TLS trust or inherit proxy settings, leading to incorrect health classification.
  • Recommended action: Refactor to pass CA_BUNDLE as explicit environment variable (e.g., NEMOCLAW_CA_BUNDLE) or positional parameter. Add test with mocked login shell verifying proxy env vars are unset in child curl process.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and verify proxy clearing behavior in a runtime test.
  • Missing regression test: Integration test: DCode probe with inherited proxy env vars verifies they are unset in the curl subprocess.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and verify proxy clearing behavior in a runtime test.
  • Evidence: DCODE_INFERENCE_ROUTE_PROBE_WRAPPER uses `exec env ${PROXY_ENV_KEYS.map((key) => `-u ${key}`).join(" ")} HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`; test only checks argv contains `-u HTTPS_PROXY`

PRA-8 Resolve/justify — Status exit code change for authoritative inference route failure

  • Location: src/commands/sandbox/status.ts:40
  • Category: correctness
  • Problem: isInferenceHealthFailing(report.inferenceHealth) now causes non-zero exit when authoritative in-sandbox inference route fails or cannot be probed. This is a behavioral change for automation consumers. Previous review asked to document in release notes and consider transition period/flag.
  • Impact: Automation scripts (CI, deployment pipelines) that rely on status --json exit code 0 for healthy inference will now fail when inference.local is unreachable but upstream is healthy. Could cause false deployment failures.
  • Recommended action: Document exit code change in release notes. Consider if transition period or flag needed for automation consumers. Verify CI pipelines handle new behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check release notes for this change; verify automation consumers (CI, scripts) are updated or can tolerate the new exit code.
  • Missing regression test: E2E test: status --json exits 1 when inference.local is unreachable but upstream is healthy.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check release notes for this change; verify automation consumers (CI, scripts) are updated or can tolerate the new exit code.
  • Evidence: status.ts:40 `isInferenceHealthFailing(report.inferenceHealth) ||` added to exit condition; isInferenceHealthFailing returns true when !probed || !ok

PRA-9 Resolve/justify — DCode probe test only verifies argv shape, not runtime proxy clearing behavior

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.test.ts:15
  • Category: tests
  • Problem: DCode probe test only verifies argv shape (`-u HTTPS_PROXY` in argv), not runtime proxy clearing behavior. The test confirms the command string contains proxy unset flags but doesn't verify they actually take effect in the child curl process when the login shell runs.
  • Impact: Proxy clearing could fail silently in production if login shell behavior differs from expectations, causing curl to inherit proxy settings and potentially hit wrong endpoints or fail auth.
  • Recommended action: Add test with mocked login shell that verifies proxy env vars are unset in the child curl process, covering failure paths. This is local to changed code and should be fixed in this PR.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run connect-inference-route-probe.test.ts; verify no test exercises the login shell proxy clearing at runtime.
  • Missing regression test: Test with mocked login shell verifying HTTP_PROXY/HTTPS_PROXY are unset in child curl process.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run connect-inference-route-probe.test.ts; verify no test exercises the login shell proxy clearing at runtime.
  • Evidence: connect-inference-route-probe.test.ts:15-24 test 'uses the dcode login-shell proxy contract without inherited proxy variables' only checks argv array contents

💡 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-10 Improvement — Doctor flow extraction created doctor-inference.ts but no behavioral drift verification

  • Location: src/lib/actions/sandbox/doctor-inference.ts:1
  • Category: architecture
  • Problem: Doctor flow extraction created doctor-inference.ts (158 lines) but no verification that doctor behavior is unchanged for edge cases (gateway unreachable, sandbox unreachable, upstream probe throws).
  • Impact: Behavioral regression in doctor output for edge cases could go undetected.
  • Suggested action: Run full doctor test suite; compare pre/post behavior for edge cases (gateway unreachable, sandbox unreachable, upstream probe throws). This is a verification step, not a code change.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Run doctor-flow.test.ts and doctor-inference.test.ts; verify all edge cases pass.
  • Missing regression test: Behavioral comparison test: doctor output for gateway unreachable / sandbox unreachable / upstream probe throws matches pre-extraction behavior.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: doctor-inference.ts created as new file; doctor-flow.test.ts updated but no explicit edge-case comparison tests added

PRA-11 Improvement — CA validation doesn't verify non-empty regular file

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:31
  • Category: correctness
  • Problem: INFERENCE_ROUTE_CA_VALIDATION uses `[ -f "$CA_BUNDLE" ] && [ -r "$CA_BUNDLE" ]` but doesn't verify the file is non-empty. An empty CA bundle file would pass the check and cause curl to fail with TLS error classified as BROKEN 000.
  • Impact: Empty CA bundle (possible if OpenShell injection writes empty file) misclassified as network failure instead of configuration issue.
  • Suggested action: Add `[ -s "$CA_BUNDLE" ]` to verify non-empty file.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check INFERENCE_ROUTE_CA_VALIDATION; test with empty CA bundle file.
  • Missing regression test: Test with empty CA bundle file returns UNAVAILABLE.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: INFERENCE_ROUTE_CA_VALIDATION at line 26-31 lacks `-s` check

PRA-12 Improvement — Error redaction timing gap in probe failure path

  • Location: src/lib/actions/sandbox/status-snapshot.ts:274
  • Category: security
  • Problem: Error redaction in reportInferenceProbeError uses `redact()` but the redaction happens after the error is caught. The original error object may contain secrets in stack traces or properties before redaction. The catch block in collectSandboxStatusSnapshot catches and redacts, but probeSandboxInferenceGatewayHealth also catches and returns null without redacting the error.
  • Impact: Secrets in error stack traces or properties could leak if logged upstream before redaction in collectSandboxStatusSnapshot.
  • Suggested action: Ensure all error paths that could expose secrets are redacted before logging. Consider centralizing error redaction for probe failures.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Trace error paths from probeSandboxInferenceGatewayHealth through collectSandboxStatusSnapshot to console.error; verify no secret leakage.
  • Missing regression test: Test that thrown probe errors with token-shaped values in message are redacted in output.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: status-snapshot.ts:274 reportInferenceProbeError redacts; inference-route-health.ts:50 catches and returns null without redacting

PRA-13 Improvement — CLI e2e tests use shell stubs, not real OpenShell exec

  • Location: test/cli/sandbox-status-json.test.ts:1
  • Category: tests
  • Problem: New CLI e2e tests for authoritative route behavior are excellent (13 test cases covering HTTP 200/401/403, 503, 000, 199, unavailable probe, missing CA). However, they use shell stubs rather than real OpenShell exec. Real integration tests would catch DNS/TLS/proxy/framing issues.
  • Impact: Stub-based tests cannot catch real OpenShell exec behavior, DNS resolution, TLS handshake, proxy provisioning, or response framing issues.
  • Suggested action: Keep the stub-based tests for fast feedback; add a separate integration test suite (opt-in, slower) that runs against a real sandbox with controlled inference.local failures.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Run test/cli/sandbox-status-json.test.ts; verify all 13 cases pass. Note these are stub-based.
  • Missing regression test: Real sandbox integration test for authoritative route probe with controlled gateway failures.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: sandbox-status-json.test.ts creates stub openshell/docker/curl binaries in temp directory

PRA-14 Improvement — Troubleshooting docs lack remediation guidance per failureLabel

  • Location: docs/inference/use-local-inference.mdx:1
  • Category: docs
  • Problem: Documentation changes accurately reflect the new authoritative route behavior. However, the troubleshooting section says "If that line shows unhealthy, unreachable, or not probed, inspect the labeled diagnostic lines to identify the failing hop" — but doesn't explain what operators should DO for each failureLabel (unhealthy vs unreachable vs not probed).
  • Impact: Operators seeing 'unhealthy', 'unreachable', or 'not probed' won't know specific remediation steps, increasing support burden and MTTR.
  • Suggested action: Add remediation guidance per failureLabel: unhealthy = check gateway logs/upstream; unreachable = check DNS/gateway/proxy; not probed = check sandbox connectivity/doctor.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read troubleshooting.mdx inference timeout section; verify remediation guidance covers all three failureLabel values.
  • Missing regression test: None — documentation improvement.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: troubleshooting.mdx:1344-1345 mentions failureLabel values but no remediation per label

PRA-15 Improvement — Refactor argv[0] CA passing to explicit env var for clarity

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • Category: scope
  • Problem: The argv[0] convention for passing CA_BUNDLE to DCode's login shell is fragile and unclear. Using an explicit environment variable (NEMOCLAW_CA_BUNDLE) would be more robust and self-documenting.
  • Impact: Maintainability risk; future shell changes or different login shell implementations could break CA injection silently.
  • Suggested action: Change DCODE_INFERENCE_ROUTE_PROBE_WRAPPER to export CA_BUNDLE as environment variable and have inner script read from env. Update INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT accordingly.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT; verify env var approach works with mocked login shell.
  • Missing regression test: Test with env var CA passing verifies CA reaches curl --cacert correctly.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Current argv[0] approach at lines 55-61; simplification opportunity with safety boundary of preserving proxy clearing and CA injection
Simplification opportunities: 1 possible cut, net -5 lines possible

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

  • PRA-15 native (src/lib/actions/sandbox/connect-inference-route-probe.ts:55): argv[0] CA_BUNDLE passing via bash -lc "$1" "$CA_BUNDLE" with inner script reading $0
    • Replacement: Export NEMOCLAW_CA_BUNDLE env var in wrapper; inner script reads ${NEMOCLAW_CA_BUNDLE} with same proxy clearing via exec env -u
    • Net: -5 lines
    • Safety boundary: Must preserve: (1) proxy env var clearing (-u HTTP_PROXY etc.), (2) CA bundle reaching curl --cacert, (3) OpenShell CA injection contract, (4) fail-closed on missing CA
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 — status --json exits 1 with inferenceHealth.ok=false on broken inference.local (real sandbox). Runtime/sandbox/infrastructure paths need behavioral runtime validation: authoritative in-sandbox probe uses OpenShell exec, DNS, TLS CA injection, proxy provisioning, and response framing — all unexercised by stub-based unit/CLI tests. 13 stub-based CLI tests exist but real integration gaps remain.
  • PRA-T2 Runtime validation — doctor --json shows authoritative fail + upstream ok (real sandbox). Runtime/sandbox/infrastructure paths need behavioral runtime validation: authoritative in-sandbox probe uses OpenShell exec, DNS, TLS CA injection, proxy provisioning, and response framing — all unexercised by stub-based unit/CLI tests. 13 stub-based CLI tests exist but real integration gaps remain.
  • PRA-T3 Runtime validation — connect fails closed on inconclusive probe (real sandbox). Runtime/sandbox/infrastructure paths need behavioral runtime validation: authoritative in-sandbox probe uses OpenShell exec, DNS, TLS CA injection, proxy provisioning, and response framing — all unexercised by stub-based unit/CLI tests. 13 stub-based CLI tests exist but real integration gaps remain.
  • PRA-T4 Runtime validation — DCode agent CA capture + proxy clearing argv shape (real sandbox with DCode agent). Runtime/sandbox/infrastructure paths need behavioral runtime validation: authoritative in-sandbox probe uses OpenShell exec, DNS, TLS CA injection, proxy provisioning, and response framing — all unexercised by stub-based unit/CLI tests. 13 stub-based CLI tests exist but real integration gaps remain.
  • PRA-T5 Runtime validation — Missing CA bundle returns UNAVAILABLE (real OpenShell exec). Runtime/sandbox/infrastructure paths need behavioral runtime validation: authoritative in-sandbox probe uses OpenShell exec, DNS, TLS CA injection, proxy provisioning, and response framing — all unexercised by stub-based unit/CLI tests. 13 stub-based CLI tests exist but real integration gaps remain.
  • PRA-T6 No end-to-end runtime validation tests for authoritative route behavior — Add 6 targeted runtime tests in existing CLI suite: (1) status --json exits 1 with inferenceHealth.ok=false on broken inference.local; (2) doctor --json shows authoritative fail + upstream ok; (3) connect fails closed on inconclusive probe; (4) DCode agent CA capture + proxy clearing argv shape; (5) missing CA bundle returns UNAVAILABLE; (6) framed OpenShell output parsed correctly.
  • PRA-T7 DCode probe test only verifies argv shape, not runtime proxy clearing behavior — Add test with mocked login shell that verifies proxy env vars are unset in the child curl process, covering failure paths. This is local to changed code and should be fixed in this PR.
  • PRA-T8 CLI e2e tests use shell stubs, not real OpenShell exec — Keep the stub-based tests for fast feedback; add a separate integration test suite (opt-in, slower) that runs against a real sandbox with controlled inference.local failures.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Required — connect.ts monolith at 1178 lines handling 5+ orthogonal flows

  • Location: src/lib/actions/sandbox/connect.ts:1
  • Category: architecture
  • Problem: connect.ts grew to 1178 lines (+14 this PR) handling process recovery, DNS repair, route reconcile, auto-pair, SSH attach, and authoritative probe orchestration. New inference-route-health.ts (81 lines) and connect-inference-route-probe.ts (109 lines) are good extractions but orchestration layer continues accumulating responsibilities. Fail-closed inconclusive handling is mixed with repair orchestration in the same file.
  • Impact: Monolith growth makes security review harder, increases coupling, and raises risk that changes to one flow inadvertently affect another. Previous review PRA-3 still applies.
  • Required action: Extract remaining flows: connect-flow.ts (orchestration), connect-repair.ts (route repair), connect-process.ts (process recovery), connect-ssh.ts (SSH attach). Keep fail-closed inconclusive handling atomic in connect-flow.ts.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check connect.ts line count and import graph; verify inference-route-health.ts and connect-inference-route-probe.ts are imported rather than inlined.
  • Missing regression test: None needed — this is a refactor suggestion. Existing tests would validate behavior preservation.
  • Done when: The required change is committed and verification passes: Check connect.ts line count and import graph; verify inference-route-health.ts and connect-inference-route-probe.ts are imported rather than inlined.
  • Evidence: monolithDeltas shows connect.ts +14 lines, severity warning; connect-flow.test.ts +126 lines (blocker threshold); 22 commits in PR showing iterative growth

PRA-2 Required — connect-flow.test.ts monolith growth +126 lines (now 516) — blocker threshold

  • Location: src/lib/actions/sandbox/connect-flow.test.ts:1
  • Category: architecture
  • Problem: connect-flow.test.ts grew +126 lines this PR with new inconclusive-probe tests added inline rather than in a focused test file. New connect-route-repair-inconclusive.test.ts (3 tests) exists but connect-flow.test.ts still accumulates fail-closed behavior tests. Test monolith growth parallels production code monolith.
  • Impact: Harder to maintain, review, and isolate test failures. Inconclusive-probe tests are conceptually separate from SSH attach/terminal flow tests.
  • Required action: Move new inconclusive-probe tests to connect-route-repair-inconclusive.test.ts (already created) or a new connect-fail-closed.test.ts. Keep connect-flow.test.ts focused on SSH attach/terminal flow.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Count test blocks in connect-flow.test.ts vs connect-route-repair-inconclusive.test.ts; verify no duplicate inconclusive coverage.
  • Missing regression test: None — reorganization of existing tests.
  • Done when: The required change is committed and verification passes: Count test blocks in connect-flow.test.ts vs connect-route-repair-inconclusive.test.ts; verify no duplicate inconclusive coverage.
  • Evidence: monolithDeltas shows connect-flow.test.ts +126 lines, severity blocker; 4 new inconclusive tests in connect-flow.test.ts (lines 241-395) duplicate concept with connect-route-repair-inconclusive.test.ts

PRA-3 Required — No end-to-end runtime validation tests for authoritative route behavior

  • Location: test/cli/sandbox-status-json.test.ts:1
  • Category: tests
  • Problem: Unit tests comprehensively cover parser/classification logic (100+ test blocks across 20 changed test files), but no end-to-end runtime validation tests exercise the authoritative probe against a real sandbox with controlled inference.local failures. Integration gaps between unit-tested components and the real OpenShell exec/DNS/TLS/proxy stack could surface in production.
  • Impact: False confidence from unit tests; real OpenShell sandbox exec, DNS resolution, TLS handshake, proxy provisioning, and response framing not exercised. Production bugs in the integration layer would not be caught.
  • Required action: Add 6 targeted runtime tests in existing CLI suite: (1) status --json exits 1 with inferenceHealth.ok=false on broken inference.local; (2) doctor --json shows authoritative fail + upstream ok; (3) connect fails closed on inconclusive probe; (4) DCode agent CA capture + proxy clearing argv shape; (5) missing CA bundle returns UNAVAILABLE; (6) framed OpenShell output parsed correctly.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run new integration tests against a test sandbox with controlled inference.local failures (gateway returning 503, DNS failure, CA missing, timeout).
  • Missing regression test: 6 end-to-end CLI tests exercising the authoritative route path with real sandbox exec, covering the 6 behaviors listed in recommendation.
  • Done when: The required change is committed and verification passes: Run new integration tests against a test sandbox with controlled inference.local failures (gateway returning 503, DNS failure, CA missing, timeout).
  • Evidence: pr_review_validation_context testDepth verdict: runtime_validation_recommended; 13 CLI stub tests exist but use shell stubs not real OpenShell exec

PRA-4 Resolve/justify — Source-of-truth: CA validation only checks existence/readability, not PEM format

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:20
  • Category: architecture
  • Problem: INFERENCE_ROUTE_CA_VALIDATION only checks `[ -f "$CA_BUNDLE" ] && [ -r "$CA_BUNDLE" ]` — no PEM format validation. Invalid PEM would surface as curl TLS error (classified as BROKEN 000) but the error class is ambiguous — it could be missing CA, unreadable CA, malformed PEM, or actual TLS handshake failure. The 'UNAVAILABLE' marker is only for missing/unreadable CA.
  • Impact: Reduces diagnostic precision and could mask configuration issues. An invalid PEM file would cause curl to fail with a TLS error, classified as BROKEN 000 (unreachable), indistinguishable from a missing CA or actual network failure.
  • Recommended action: Add lightweight PEM format check (e.g., `grep -q 'BEGIN CERTIFICATE' "$CA_BUNDLE"`) before curl, or document that BROKEN 000 covers both missing CA and TLS handshake failures. Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect INFERENCE_ROUTE_CA_VALIDATION in connect-inference-route-probe.ts; verify if PEM format validation exists or is documented as intentionally omitted.
  • Missing regression test: Test with malformed PEM CA bundle to verify classification (should be UNAVAILABLE or BROKEN with clear distinction).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect INFERENCE_ROUTE_CA_VALIDATION in connect-inference-route-probe.ts; verify if PEM format validation exists or is documented as intentionally omitted.
  • Evidence: connect-inference-route-probe.ts:26-31 INFERENCE_ROUTE_CA_VALIDATION; connect-inference-route-probe.test.ts 'reports unavailable before curl when the injected CA bundle is missing' test exists but no malformed PEM test

PRA-5 Resolve/justify — Source-of-truth: argv[0] convention for DCode CA bundle passing

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • Category: architecture
  • Problem: DCODE_INFERENCE_ROUTE_PROBE_WRAPPER passes CA_BUNDLE as argv[0] to `bash -lc "$1" "$CA_BUNDLE"` where the inner script reads it as `$0`. This is unconventional and fragile — argv[0] is traditionally the script name. No test verifies the login shell doesn't mutate argv[0] before the inner script runs.
  • Impact: Relies on bash preserving argv[0] through the login shell, which is not guaranteed across shell implementations or future changes. Could silently break CA injection for DCode agents.
  • Recommended action: Refactor to pass CA_BUNDLE as explicit environment variable (e.g., NEMOCLAW_CA_BUNDLE) or positional parameter to the inner script for clarity, or add prominent comment explaining the argv[0] convention. Add test with mocked login shell verifying proxy env vars are unset in child curl process.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT in connect-inference-route-probe.ts; verify comment explains argv[0] usage.
  • Missing regression test: Test with mocked login shell that verifies proxy env vars are unset in the child curl process, covering failure paths.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT in connect-inference-route-probe.ts; verify comment explains argv[0] usage.
  • Evidence: connect-inference-route-probe.ts:55-61 DCODE_INFERENCE_ROUTE_PROBE_WRAPPER; connect-inference-route-probe.test.ts:15 only verifies argv shape contains '-u HTTPS_PROXY', not runtime proxy clearing

PRA-6 Resolve/justify — CA bundle validation only checks existence/readability, not PEM format

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:20
  • Category: security
  • Problem: CA validation only checks existence/readability, not PEM format. An invalid PEM file would cause curl to fail with a TLS error, classified as BROKEN 000 (unreachable), indistinguishable from a missing CA or actual network failure. This reduces diagnostic precision and could mask configuration issues.
  • Impact: Security diagnostic precision degraded; configuration issues (malformed CA) masked as network failures, increasing MTTR for real incidents.
  • Recommended action: Add lightweight PEM format check (`grep -q 'BEGIN CERTIFICATE' "$CA_BUNDLE"`) before curl invocation, or explicitly document the ambiguity in the UNAVAILABLE/BROKEN classification.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run probe with malformed PEM file; verify output classification and error message clarity.
  • Missing regression test: Unit test: probe with malformed PEM CA bundle returns UNAVAILABLE (not BROKEN) or BROKEN with distinct detail.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run probe with malformed PEM file; verify output classification and error message clarity.
  • Evidence: INFERENCE_ROUTE_CA_VALIDATION at line 26-31; no PEM format validation in script or parser

PRA-7 Resolve/justify — Unusual argv[0] pattern for CA bundle passing in DCode wrapper

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • Category: correctness
  • Problem: The wrapper passes CA_BUNDLE as argv[0] to `bash -lc "$1" "$CA_BUNDLE"`, then inner script reads `$0`. This relies on bash preserving argv[0] through the login shell, which is not guaranteed across shell implementations or future changes. No test verifies the proxy env vars (-u HTTP_PROXY etc.) are actually unset in the child curl process.
  • Impact: Silent CA injection or proxy clearing failures for DCode agents could cause probe to use wrong TLS trust or inherit proxy settings, leading to incorrect health classification.
  • Recommended action: Refactor to pass CA_BUNDLE as explicit environment variable (e.g., NEMOCLAW_CA_BUNDLE) or positional parameter. Add test with mocked login shell verifying proxy env vars are unset in child curl process.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and verify proxy clearing behavior in a runtime test.
  • Missing regression test: Integration test: DCode probe with inherited proxy env vars verifies they are unset in the curl subprocess.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and verify proxy clearing behavior in a runtime test.
  • Evidence: DCODE_INFERENCE_ROUTE_PROBE_WRAPPER uses `exec env ${PROXY_ENV_KEYS.map((key) => `-u ${key}`).join(" ")} HOME=/sandbox bash -lc "$1" "$CA_BUNDLE"`; test only checks argv contains `-u HTTPS_PROXY`

PRA-8 Resolve/justify — Status exit code change for authoritative inference route failure

  • Location: src/commands/sandbox/status.ts:40
  • Category: correctness
  • Problem: isInferenceHealthFailing(report.inferenceHealth) now causes non-zero exit when authoritative in-sandbox inference route fails or cannot be probed. This is a behavioral change for automation consumers. Previous review asked to document in release notes and consider transition period/flag.
  • Impact: Automation scripts (CI, deployment pipelines) that rely on status --json exit code 0 for healthy inference will now fail when inference.local is unreachable but upstream is healthy. Could cause false deployment failures.
  • Recommended action: Document exit code change in release notes. Consider if transition period or flag needed for automation consumers. Verify CI pipelines handle new behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check release notes for this change; verify automation consumers (CI, scripts) are updated or can tolerate the new exit code.
  • Missing regression test: E2E test: status --json exits 1 when inference.local is unreachable but upstream is healthy.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check release notes for this change; verify automation consumers (CI, scripts) are updated or can tolerate the new exit code.
  • Evidence: status.ts:40 `isInferenceHealthFailing(report.inferenceHealth) ||` added to exit condition; isInferenceHealthFailing returns true when !probed || !ok

PRA-9 Resolve/justify — DCode probe test only verifies argv shape, not runtime proxy clearing behavior

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.test.ts:15
  • Category: tests
  • Problem: DCode probe test only verifies argv shape (`-u HTTPS_PROXY` in argv), not runtime proxy clearing behavior. The test confirms the command string contains proxy unset flags but doesn't verify they actually take effect in the child curl process when the login shell runs.
  • Impact: Proxy clearing could fail silently in production if login shell behavior differs from expectations, causing curl to inherit proxy settings and potentially hit wrong endpoints or fail auth.
  • Recommended action: Add test with mocked login shell that verifies proxy env vars are unset in the child curl process, covering failure paths. This is local to changed code and should be fixed in this PR.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run connect-inference-route-probe.test.ts; verify no test exercises the login shell proxy clearing at runtime.
  • Missing regression test: Test with mocked login shell verifying HTTP_PROXY/HTTPS_PROXY are unset in child curl process.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run connect-inference-route-probe.test.ts; verify no test exercises the login shell proxy clearing at runtime.
  • Evidence: connect-inference-route-probe.test.ts:15-24 test 'uses the dcode login-shell proxy contract without inherited proxy variables' only checks argv array contents

PRA-10 Improvement — Doctor flow extraction created doctor-inference.ts but no behavioral drift verification

  • Location: src/lib/actions/sandbox/doctor-inference.ts:1
  • Category: architecture
  • Problem: Doctor flow extraction created doctor-inference.ts (158 lines) but no verification that doctor behavior is unchanged for edge cases (gateway unreachable, sandbox unreachable, upstream probe throws).
  • Impact: Behavioral regression in doctor output for edge cases could go undetected.
  • Suggested action: Run full doctor test suite; compare pre/post behavior for edge cases (gateway unreachable, sandbox unreachable, upstream probe throws). This is a verification step, not a code change.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Run doctor-flow.test.ts and doctor-inference.test.ts; verify all edge cases pass.
  • Missing regression test: Behavioral comparison test: doctor output for gateway unreachable / sandbox unreachable / upstream probe throws matches pre-extraction behavior.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: doctor-inference.ts created as new file; doctor-flow.test.ts updated but no explicit edge-case comparison tests added

PRA-11 Improvement — CA validation doesn't verify non-empty regular file

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:31
  • Category: correctness
  • Problem: INFERENCE_ROUTE_CA_VALIDATION uses `[ -f "$CA_BUNDLE" ] && [ -r "$CA_BUNDLE" ]` but doesn't verify the file is non-empty. An empty CA bundle file would pass the check and cause curl to fail with TLS error classified as BROKEN 000.
  • Impact: Empty CA bundle (possible if OpenShell injection writes empty file) misclassified as network failure instead of configuration issue.
  • Suggested action: Add `[ -s "$CA_BUNDLE" ]` to verify non-empty file.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check INFERENCE_ROUTE_CA_VALIDATION; test with empty CA bundle file.
  • Missing regression test: Test with empty CA bundle file returns UNAVAILABLE.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: INFERENCE_ROUTE_CA_VALIDATION at line 26-31 lacks `-s` check

PRA-12 Improvement — Error redaction timing gap in probe failure path

  • Location: src/lib/actions/sandbox/status-snapshot.ts:274
  • Category: security
  • Problem: Error redaction in reportInferenceProbeError uses `redact()` but the redaction happens after the error is caught. The original error object may contain secrets in stack traces or properties before redaction. The catch block in collectSandboxStatusSnapshot catches and redacts, but probeSandboxInferenceGatewayHealth also catches and returns null without redacting the error.
  • Impact: Secrets in error stack traces or properties could leak if logged upstream before redaction in collectSandboxStatusSnapshot.
  • Suggested action: Ensure all error paths that could expose secrets are redacted before logging. Consider centralizing error redaction for probe failures.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Trace error paths from probeSandboxInferenceGatewayHealth through collectSandboxStatusSnapshot to console.error; verify no secret leakage.
  • Missing regression test: Test that thrown probe errors with token-shaped values in message are redacted in output.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: status-snapshot.ts:274 reportInferenceProbeError redacts; inference-route-health.ts:50 catches and returns null without redacting

PRA-13 Improvement — CLI e2e tests use shell stubs, not real OpenShell exec

  • Location: test/cli/sandbox-status-json.test.ts:1
  • Category: tests
  • Problem: New CLI e2e tests for authoritative route behavior are excellent (13 test cases covering HTTP 200/401/403, 503, 000, 199, unavailable probe, missing CA). However, they use shell stubs rather than real OpenShell exec. Real integration tests would catch DNS/TLS/proxy/framing issues.
  • Impact: Stub-based tests cannot catch real OpenShell exec behavior, DNS resolution, TLS handshake, proxy provisioning, or response framing issues.
  • Suggested action: Keep the stub-based tests for fast feedback; add a separate integration test suite (opt-in, slower) that runs against a real sandbox with controlled inference.local failures.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Run test/cli/sandbox-status-json.test.ts; verify all 13 cases pass. Note these are stub-based.
  • Missing regression test: Real sandbox integration test for authoritative route probe with controlled gateway failures.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: sandbox-status-json.test.ts creates stub openshell/docker/curl binaries in temp directory

PRA-14 Improvement — Troubleshooting docs lack remediation guidance per failureLabel

  • Location: docs/inference/use-local-inference.mdx:1
  • Category: docs
  • Problem: Documentation changes accurately reflect the new authoritative route behavior. However, the troubleshooting section says "If that line shows unhealthy, unreachable, or not probed, inspect the labeled diagnostic lines to identify the failing hop" — but doesn't explain what operators should DO for each failureLabel (unhealthy vs unreachable vs not probed).
  • Impact: Operators seeing 'unhealthy', 'unreachable', or 'not probed' won't know specific remediation steps, increasing support burden and MTTR.
  • Suggested action: Add remediation guidance per failureLabel: unhealthy = check gateway logs/upstream; unreachable = check DNS/gateway/proxy; not probed = check sandbox connectivity/doctor.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Read troubleshooting.mdx inference timeout section; verify remediation guidance covers all three failureLabel values.
  • Missing regression test: None — documentation improvement.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: troubleshooting.mdx:1344-1345 mentions failureLabel values but no remediation per label

PRA-15 Improvement — Refactor argv[0] CA passing to explicit env var for clarity

  • Location: src/lib/actions/sandbox/connect-inference-route-probe.ts:55
  • Category: scope
  • Problem: The argv[0] convention for passing CA_BUNDLE to DCode's login shell is fragile and unclear. Using an explicit environment variable (NEMOCLAW_CA_BUNDLE) would be more robust and self-documenting.
  • Impact: Maintainability risk; future shell changes or different login shell implementations could break CA injection silently.
  • Suggested action: Change DCODE_INFERENCE_ROUTE_PROBE_WRAPPER to export CA_BUNDLE as environment variable and have inner script read from env. Update INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT accordingly.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check DCODE_INFERENCE_ROUTE_PROBE_WRAPPER and INFERENCE_ROUTE_PROBE_FROM_ARG0_SCRIPT; verify env var approach works with mocked login shell.
  • Missing regression test: Test with env var CA passing verifies CA reaches curl --cacert correctly.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Current argv[0] approach at lines 55-61; simplification opportunity with safety boundary of preserving proxy clearing and CA injection

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.

Write curl response bodies to /dev/null so repeated diagnostics do not
share a sandbox temp path. Update healthy CLI fixtures to emit
authoritative route evidence.

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

apurvvkumaria commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Sensitive-path security review — PASS

I reviewed the full PR diff against the nine-category NemoClaw security checklist. The authoritative, fail-closed inference.local route check improves the diagnostic security posture, and there is no open merge-blocking security finding.

The first pass found one low-severity hardening issue: the shared probe wrote response bodies to a fixed sandbox /tmp path, creating avoidable symlink and concurrent-probe collision risk. Commit 13a3dd263b7575180e601265d0cd57bd60f7bbfa resolves it by discarding response bodies through /dev/null and adds regression coverage that rejects persistent temp-path use.

A later advisor pass found that the probe still used curl's -k certificate bypass, which could report a false-green result when the agent's TLS-verified route would fail. Commit 61760344fbe586a9cbd86ccc3d1e3f0a445a59db removes that bypass, relies on OpenShell's injected CA environment, maps TLS failures to 000/unreachable, and adds a regression assertion forbidding -k and --insecure.

The final advisor pass identified that an interim HTTP 1xx response was accepted as healthy even though /v1/models had not produced a final response. Commit ab6c9c23f26b799333020f2b9fe83e418315802b aligns the shell and parser on final HTTP 200–499 responses, fails closed on 100–199, and adds boundary and forged-output regression coverage. The nine-category delta review remains PASS.

Final-head live diagnostics then proved that removing -k without selecting OpenShell's trust bundle produced BROKEN 000. A first hardcoded-path attempt in 4bcc1b2bbcee51ac779e1ceb0860ff3d28cdc27c was also disproved by live DCode, diagnostics, and sandbox-operations runs: real agent inference succeeded while status alone failed. Commit 6750ba0deaf9f8a1b301af4c02eef8898211b8ee now selects OpenShell's injected CURL_CA_BUNDLE (falling back to SSL_CERT_FILE) and passes it explicitly to /usr/bin/curl --cacert. For DCode, the trusted path is captured and validated before its login shell sources the sandbox-owned proxy environment. Missing, unreadable, malformed, or unusable CA state still fails closed as 000/unreachable; no hardcoded path or certificate bypass remains. A focused nine-category delta review of this exact implementation remains PASS.

Category Verdict Rationale
Secrets and credentials PASS No keys or tokens added; diagnostic output remains bounded and redacted.
Input validation and sanitization PASS Shell text and URL are constant, sandbox names remain argv values, and HTTP output parsing is anchored and allowlisted.
Authentication and authorization PASS No auth boundary changed; 401/403 means route-reachable, not credential-valid, and the docs state that distinction.
Dependencies PASS No dependency, lockfile, registry, or license changes.
Error handling and logging PASS Timeouts, transport failures, malformed output, interim 1xx, HTTP 000, and 5xx fail closed without exposing response bodies.
Cryptography and data protection PASS TLS peer verification stays enabled and uses only the per-exec trust bundle injected by OpenShell; no certificate bypass or persistent sensitive data is introduced.
Configuration and security headers PASS No policy, image, port, privilege, CORS, or CSP change; probe timeouts are bounded.
Security testing PASS Coverage includes malformed/framed output, 000, HTTP boundaries, unavailable probes, DCode proxy isolation, CLI exits, and no-persistent-temp-file behavior.
Holistic security posture PASS Status, doctor, and connect now share the same authoritative route truth and no longer return a false-green result from an upstream-only probe.

Verification after the hardening changes:

  • Issue-focused source suites: 163/163 passed.
  • Changed status/connect/recovery integration fixtures: 43/43 passed.
  • Repository checks, TypeScript, Biome, docs, and git diff --check: passed.

Files reviewed: docs/inference/use-local-inference.mdx, docs/monitoring/monitor-sandbox-activity.mdx, docs/reference/commands-nemohermes.mdx, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx, src/commands/sandbox/oclif-command-adapters.test.ts, src/commands/sandbox/status.ts, src/lib/actions/sandbox/connect-inference-route-probe.test.ts, src/lib/actions/sandbox/connect-inference-route-probe.ts, src/lib/actions/sandbox/connect-route-repair.test.ts, src/lib/actions/sandbox/connect.ts, src/lib/actions/sandbox/doctor-flow.test.ts, src/lib/actions/sandbox/doctor.ts, src/lib/actions/sandbox/process-recovery.test.ts, src/lib/actions/sandbox/process-recovery.ts, src/lib/actions/sandbox/status-flow.test.ts, src/lib/actions/sandbox/status-snapshot.ts, src/lib/actions/sandbox/status-text.ts, src/lib/actions/sandbox/status.test.ts, test/cli/connect-readiness.test.ts, test/cli/connect-recovery.test.ts, test/cli/helpers.ts, test/cli/sandbox-status-json.test.ts, test/cli/sandbox-status-text.test.ts, test/cli/status-gateway-lifecycle.test.ts, test/nemoclaw-cli-recovery.test.ts, test/reboot-identity-drift.test.ts, test/sandbox-stuck-recovery.test.ts, and test/support/status-flow-test-harness.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.

🧹 Nitpick comments (6)
docs/inference/use-local-inference.mdx (1)

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

Terminology drift from the authoritative state table.

This section uses "reachable" and "broken" for the sandbox probe outcomes, but docs/reference/commands.mdx and docs/reference/commands-nemohermes.mdx define the authoritative states as healthy, unhealthy, unreachable, not probed, and not verified. Using different wording here for the same classification (100–499 → "healthy" elsewhere vs "reachable" here; 000/unavailable → "not probed"/"unreachable" elsewhere vs "broken" here) risks confusing readers trying to map this page's guidance to the exact status label they see in CLI output.

✏️ Align wording with the states table
-The authoritative `status` and `doctor` route probe runs from inside the sandbox and treats HTTP `100` through `499` as reachable, HTTP `500` through `599` as unhealthy, and `000` or an unavailable probe as broken.
+The authoritative `status` and `doctor` route probe runs from inside the sandbox and treats HTTP `100` through `499` as `healthy`, HTTP `500` through `599` as `unhealthy`, and `000`, a transport failure, or an unavailable probe as `unreachable`/`not probed`.
🤖 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/use-local-inference.mdx` around lines 162 - 163, Align the
terminology in the local inference docs with the authoritative CLI state labels:
in the section describing the proxy and sandbox probe outcomes, replace
“reachable” and “broken” with the same state names used by the status/doctor
docs. Update the wording around the probe behavior in the relevant narrative so
the 100–499, 500–599, and 000/unavailable cases map consistently to the
documented states in the commands references.
src/lib/actions/sandbox/connect-inference-route-probe.test.ts (1)

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

Test duplicates the production shell-script literal instead of importing it.

INFERENCE_ROUTE_PROBE_SCRIPT here is a hand-copied duplicate of the script string owned by connect-inference-route-probe.ts. If the production script's classification logic changes but this copy isn't updated in lockstep, any test asserting against this local copy (e.g. for buildSandboxInferenceRouteProbeArgs) can pass while silently drifting from the real behavior.

As per path instructions for test files, "Flag copied production algorithms... that bypass the behavior under test." Consider exporting the constant from connect-inference-route-probe.ts and importing it here instead of re-declaring it.

♻️ Proposed fix
-const INFERENCE_ROUTE_PROBE_SCRIPT = [
-  "OUT=/tmp/nemoclaw-inference-route-probe.out",
-  "HTTP_CODE=$(curl -sk -o \"$OUT\" -w '%{http_code}' --connect-timeout 3 --max-time 8 https://inference.local/v1/models 2>/dev/null) || HTTP_CODE=000",
-  'case "$HTTP_CODE" in [1-4][0-9][0-9]) printf \'OK %s\' "$HTTP_CODE" ;; *) printf \'BROKEN %s \' "$HTTP_CODE"; head -c 160 "$OUT" 2>/dev/null || true ;; esac',
-].join("; ");
+// import the shared script constant instead of duplicating it, e.g.:
+// export const INFERENCE_ROUTE_PROBE_SCRIPT = [...] in connect-inference-route-probe.ts
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/actions/sandbox/connect-inference-route-probe.test.ts` around lines
11 - 15, The test currently re-declares the production probe script instead of
using the source of truth, so it can drift from the behavior under test. Export
INFERENCE_ROUTE_PROBE_SCRIPT from connect-inference-route-probe.ts and import it
into connect-inference-route-probe.test.ts, then update any assertions to
reference the imported constant rather than the local duplicate.

Source: Path instructions

test/cli/sandbox-status-text.test.ts (1)

52-55: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate stub block repeated across tests.

The same 4-line "sandbox exec → OK 200" fallback is copy-pasted into four separate openshell stub scripts in this file. Consider extracting a small helper (similar to how createDoctorTestSetup centralizes this in helpers.ts) that appends this fallback branch to a base script, to avoid drift if the probe response format changes again.

Also applies to: 116-119, 174-177, 294-297

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

In `@test/cli/sandbox-status-text.test.ts` around lines 52 - 55, The same sandbox
exec fallback stub is duplicated in multiple openshell test scripts, so
centralize it to avoid drift. Add a small helper in the test setup utilities
(similar to createDoctorTestSetup in helpers.ts) that appends the sandbox exec →
OK 200 branch to a base script, then update the affected sandbox-status-text
tests to use that helper instead of repeating the 4-line block in each stub.
src/lib/actions/sandbox/process-recovery.test.ts (1)

153-175: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Mock-call argv assertion tests implementation shape, not behavior.

This test asserts the exact array passed to captureOpenshellImpl rather than an observable effect of probeSandboxInferenceGatewayHealth. If the DCode-specific argv building (buildSandboxInferenceRouteProbeArgs) is already unit-tested directly against its own pure contract, this integration test could instead assert on the function's return value/behavior for the DCode agent case, keeping this test resilient to argv-shape refactors that don't change behavior.

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

In `@src/lib/actions/sandbox/process-recovery.test.ts` around lines 153 - 175, The
test is too tightly coupled to the argv shape passed into captureOpenshellImpl,
so update probeSandboxInferenceGatewayHealth’s DCode-case assertion to verify
the observable behavior of the function instead of the exact command array. Use
the existing DCode-specific path in buildSandboxInferenceRouteProbeArgs or
probeSandboxInferenceGatewayHealth to assert the returned status/health behavior
for the langchain-deepagents-code session agent, keeping the test resilient to
internal argv refactors.

Source: Path instructions

src/commands/sandbox/status.ts (1)

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

Inference-health failure predicate duplicated between JSON and text paths.

This inline condition (inferenceHealth && (!probed || !ok)) is logically the same "is inference unhealthy" check as inferenceHealthExitCode in status-text.ts, implemented independently. As per path instructions, behavior/orchestration decisions belong in src/lib/actions/** rather than inline in the command class; extracting a single exported predicate (e.g. isInferenceHealthFailing(inferenceHealth)) and reusing it from both the JSON path here and the text-exit-code path would remove the risk of the two paths disagreeing on what counts as "unhealthy" — the exact class of bug this PR is fixing.

♻️ Sketch
+// status-snapshot.ts (or a shared helper)
+export function isInferenceHealthFailing(inferenceHealth: ProviderHealthStatus | null): boolean {
+  return !!inferenceHealth && (!inferenceHealth.probed || !inferenceHealth.ok);
+}
-        (report.inferenceHealth &&
-          (!report.inferenceHealth.probed || !report.inferenceHealth.ok)) ||
+        isInferenceHealthFailing(report.inferenceHealth) ||
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/sandbox/status.ts` around lines 31 - 41, The inference-health
failure check is duplicated and should be centralized so the JSON and text paths
cannot drift. Move the inline unhealthy predicate from status handling into a
shared exported helper under src/lib/actions/**, such as an inference-health
predicate used by the command flow, then reuse that helper in both the sandbox
status command and the status-text exit-code logic. Keep the command class
focused on orchestration and ensure both callers use the same single source of
truth for determining whether inference health is failing.

Source: Path instructions

src/lib/actions/sandbox/status-snapshot.ts (1)

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

Duplicate HTTP-status boundary classification across files.

buildSandboxInferenceRouteHealth re-derives gateway.httpStatus >= 500 && gateway.httpStatus < 600 to pick "unhealthy" vs "unreachable", but probeSandboxInferenceGatewayHealth in process-recovery.ts already encodes the exact same 500-599 boundary independently to build its detail wording. Since this PR's whole point is making the 100-499/500-599/000 boundary consistent and authoritative across status, doctor, and connect, having the boundary hard-coded twice risks drift if the classification is ever adjusted. Consider exposing the boundary/label decision from the shared parser module (connect-inference-route-probe.ts) and having both call sites consume it instead of re-deriving the range.

♻️ Sketch of a shared classifier
+// connect-inference-route-probe.ts
+export function classifyInferenceRouteFailureLabel(httpStatus: number): "unhealthy" | "unreachable" {
+  return httpStatus >= 500 && httpStatus < 600 ? "unhealthy" : "unreachable";
+}
-              failureLabel:
-                gateway.httpStatus >= 500 && gateway.httpStatus < 600 ? "unhealthy" : "unreachable",
+              failureLabel: classifyInferenceRouteFailureLabel(gateway.httpStatus),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/actions/sandbox/status-snapshot.ts` around lines 83 - 111, The
HTTP-status boundary logic is duplicated in buildSandboxInferenceRouteHealth and
should not be re-derived locally. Move the 500-599 vs other classification into
the shared probe/parser path used by connect-inference-route-probe.ts, then have
buildSandboxInferenceRouteHealth consume that shared label or helper instead of
checking gateway.httpStatus directly. Keep the route health failureLabel in sync
with the authoritative classification already used by
probeSandboxInferenceGatewayHealth so the status, doctor, and connect paths all
share one source of truth.

Source: Path instructions

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

Nitpick comments:
In `@docs/inference/use-local-inference.mdx`:
- Around line 162-163: Align the terminology in the local inference docs with
the authoritative CLI state labels: in the section describing the proxy and
sandbox probe outcomes, replace “reachable” and “broken” with the same state
names used by the status/doctor docs. Update the wording around the probe
behavior in the relevant narrative so the 100–499, 500–599, and 000/unavailable
cases map consistently to the documented states in the commands references.

In `@src/commands/sandbox/status.ts`:
- Around line 31-41: The inference-health failure check is duplicated and should
be centralized so the JSON and text paths cannot drift. Move the inline
unhealthy predicate from status handling into a shared exported helper under
src/lib/actions/**, such as an inference-health predicate used by the command
flow, then reuse that helper in both the sandbox status command and the
status-text exit-code logic. Keep the command class focused on orchestration and
ensure both callers use the same single source of truth for determining whether
inference health is failing.

In `@src/lib/actions/sandbox/connect-inference-route-probe.test.ts`:
- Around line 11-15: The test currently re-declares the production probe script
instead of using the source of truth, so it can drift from the behavior under
test. Export INFERENCE_ROUTE_PROBE_SCRIPT from connect-inference-route-probe.ts
and import it into connect-inference-route-probe.test.ts, then update any
assertions to reference the imported constant rather than the local duplicate.

In `@src/lib/actions/sandbox/process-recovery.test.ts`:
- Around line 153-175: The test is too tightly coupled to the argv shape passed
into captureOpenshellImpl, so update probeSandboxInferenceGatewayHealth’s
DCode-case assertion to verify the observable behavior of the function instead
of the exact command array. Use the existing DCode-specific path in
buildSandboxInferenceRouteProbeArgs or probeSandboxInferenceGatewayHealth to
assert the returned status/health behavior for the langchain-deepagents-code
session agent, keeping the test resilient to internal argv refactors.

In `@src/lib/actions/sandbox/status-snapshot.ts`:
- Around line 83-111: The HTTP-status boundary logic is duplicated in
buildSandboxInferenceRouteHealth and should not be re-derived locally. Move the
500-599 vs other classification into the shared probe/parser path used by
connect-inference-route-probe.ts, then have buildSandboxInferenceRouteHealth
consume that shared label or helper instead of checking gateway.httpStatus
directly. Keep the route health failureLabel in sync with the authoritative
classification already used by probeSandboxInferenceGatewayHealth so the status,
doctor, and connect paths all share one source of truth.

In `@test/cli/sandbox-status-text.test.ts`:
- Around line 52-55: The same sandbox exec fallback stub is duplicated in
multiple openshell test scripts, so centralize it to avoid drift. Add a small
helper in the test setup utilities (similar to createDoctorTestSetup in
helpers.ts) that appends the sandbox exec → OK 200 branch to a base script, then
update the affected sandbox-status-text tests to use that helper instead of
repeating the 4-line block in each stub.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 23e3d718-d1d4-4b25-a050-0869b16a5993

📥 Commits

Reviewing files that changed from the base of the PR and between 6fa6f4b and 7072f1b.

📒 Files selected for processing (24)
  • docs/inference/use-local-inference.mdx
  • docs/monitoring/monitor-sandbox-activity.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • src/commands/sandbox/oclif-command-adapters.test.ts
  • src/commands/sandbox/status.ts
  • src/lib/actions/sandbox/connect-inference-route-probe.test.ts
  • src/lib/actions/sandbox/connect-inference-route-probe.ts
  • src/lib/actions/sandbox/connect-route-repair.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/doctor-flow.test.ts
  • src/lib/actions/sandbox/doctor.ts
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/status-flow.test.ts
  • src/lib/actions/sandbox/status-snapshot.ts
  • src/lib/actions/sandbox/status-text.ts
  • src/lib/actions/sandbox/status.test.ts
  • test/cli/helpers.ts
  • test/cli/sandbox-status-json.test.ts
  • test/cli/sandbox-status-text.test.ts
  • test/cli/status-gateway-lifecycle.test.ts
  • test/support/status-flow-test-harness.ts

@github-actions github-actions Bot mentioned this pull request Jul 7, 2026
21 tasks
Share failure labels and exit predicates across status, doctor, and
connect. Add full-CLI HTTP 401 coverage and align docs and fixtures
with the stable route vocabulary.

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

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28886806104
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: ubuntu-repo-cloud-openclaw,ubuntu-repo-docker-post-reboot-recovery,ubuntu-repo-cloud-langchain-deepagents-code
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: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: inference Inference routing, serving, model selection, or outputs area: routing Request routing, policy routing, model selection, or fallback logic bug-fix PR fixes a bug or regression integration: dcode LangChain Deep Code integration behavior labels Jul 7, 2026
Use the OpenShell-provided CA environment instead of bypassing certificate
validation. Treat TLS failures as unreachable so diagnostics match the route
the agent actually uses.

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

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28886806227
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: (default — all supported)
Requested jobs: inference-routing,sandbox-operations,diagnostics
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
diagnostics ✅ success
inference-routing ✅ success
sandbox-operations ✅ success

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28887240249
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: ubuntu-repo-cloud-openclaw,ubuntu-repo-docker-post-reboot-recovery,ubuntu-repo-cloud-langchain-deepagents-code
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: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 28887240238
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: (default — all supported)
Requested jobs: inference-routing,sandbox-operations,diagnostics
Summary: 2 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
diagnostics ❌ failure
inference-routing ✅ success
sandbox-operations ✅ success

Failed jobs: diagnostics. Check run artifacts for logs.

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

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28887940694
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: ubuntu-repo-cloud-openclaw,ubuntu-repo-docker-post-reboot-recovery,ubuntu-repo-cloud-langchain-deepagents-code
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: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 28887945371
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: (default — all supported)
Requested jobs: inference-routing,diagnostics,sandbox-operations
Summary: 2 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
diagnostics ❌ failure
inference-routing ✅ success
sandbox-operations ✅ success

Failed jobs: diagnostics. Check run artifacts for logs.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28969901801
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: (default — all supported)
Requested jobs: inference-routing,diagnostics,sandbox-operations
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
diagnostics ✅ success
inference-routing ✅ success
sandbox-operations ✅ success

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

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All selected jobs passed

Run: 28970519701
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: ubuntu-repo-cloud-openclaw,ubuntu-repo-cloud-langchain-deepagents-code
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: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
live ✅ success

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested jobs passed

Run: 28970503175
Workflow ref: fix/6192-authoritative-inference-route
Requested targets: (default — all supported)
Requested jobs: inference-routing,diagnostics,sandbox-operations
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
diagnostics ✅ success
inference-routing ✅ success
sandbox-operations ✅ success

@cv

cv commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (2)
docs/inference/use-local-inference.mdx (1)

273-275: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the same reachability boundary here.

This sentence conflicts with the authoritative probe contract above. status and doctor treat final 200499 responses as reachable, so this should not narrow success to 2xx.

♻️ Proposed fix
- It treats only a 2xx response as success because that path includes the proxy authentication rewrite the agent uses.
+ It treats any final `200` through `499` response as success because that path includes the proxy authentication rewrite the agent uses.
🤖 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/use-local-inference.mdx` around lines 273 - 275, The local
inference reachability description in NemoClaw is too strict and conflicts with
the probe contract used by status and doctor. Update the wording around the
sandbox runtime check to match the same reachability boundary as the
authoritative probe, and make sure the logic references the OpenShell bridge
route and the https://inference.local/v1/models check without narrowing success
to only 2xx responses.
src/lib/actions/sandbox/connect.ts (1)

799-807: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Generic catch defaults to “repair attempted” messaging even when no repair ran.

printUnrecoverableInferenceRoute is called here without { repairAttempted: false }, so it defaults to true and prints "...after DNS and route repair" / "known to be broken." But exceptions reaching this generic catch (e.g., a failure in the inference get call or parseGatewayInference before repairSandboxInferenceRouteIfNeeded even runs) may occur before any repair attempt, making this messaging misleading for troubleshooting.

🐛 Proposed fix
     const detail = error instanceof Error && error.message ? error.message : String(error);
     if (!quiet) {
       console.error(`  Error: failed to verify or repair inference route: ${detail}`);
       printUnrecoverableInferenceRoute(
         sandboxName,
         `${sanitizeRouteValueForDisplay(inference.provider)}/${sanitizeRouteValueForDisplay(inference.model)}`,
         detail,
+        { repairAttempted: false },
       );
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/actions/sandbox/connect.ts` around lines 799 - 807, The generic catch
in connect.ts is using the default repair messaging even when no repair was
attempted, so update the error path around the verify/repair flow to pass the
correct flag into printUnrecoverableInferenceRoute. Use the surrounding
inference verification logic in the connect flow to distinguish failures that
happen before repair-related work from those after repair, and call
printUnrecoverableInferenceRoute with repairAttempted set to false for
pre-repair exceptions so the output stays accurate.
🧹 Nitpick comments (4)
docs/reference/commands.mdx (1)

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

Replace em dashes with standard punctuation.

These changed lines use em dashes () in prose, e.g. "[user-added] — anything else: presets applied later through policy-add, presets that match no tier or agent default, or presets that match the opposite agent's reserved names on a sandbox running the other agent." and "Identical HTTP 400, 401, or 403 rejections raise a warning that names the hypotheses — the placeholder forwarded verbatim, an expired or revoked credential that resolved correctly, or (for HTTP 400) endpoint request validation — and tells you to verify the stored credential first."

As per path instructions, docs/**/*.{md,mdx} guidance states: "Avoid filler, hype, rhetorical questions, emoji, em dashes, and unnecessary bold text." Replace the em dashes with colons, parentheses, or separate sentences.

✏️ Example fix pattern
-- `[user-added]` — anything else: presets applied later through `policy-add`, presets that match no tier or agent default, or presets that match the opposite agent's reserved names on a sandbox running the other agent.
-- `[source unverified]` — the row is active but the local registry and live gateway state disagree. When the gateway cannot be queried, this renders as `[source unverified (gateway unreachable)]`. The provenance check is suppressed in these trust-degraded states because the source cannot be confirmed against both halves of the sandbox policy view.
+- `[user-added]`: anything else, including presets applied later through `policy-add`, presets that match no tier or agent default, or presets that match the opposite agent's reserved names on a sandbox running the other agent.
+- `[source unverified]`: the row is active but the local registry and live gateway state disagree. When the gateway cannot be queried, this renders as `[source unverified (gateway unreachable)]`. The provenance check is suppressed in these trust-degraded states because the source cannot be confirmed against both halves of the sandbox policy view.

Also applies to: 1875-1878

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

In `@docs/reference/commands.mdx` around lines 1559 - 1561, Replace the em dash
prose in the affected docs text with standard punctuation, following the docs
style guidance that forbids em dashes in docs. Update the descriptive bullets in
the command reference so the `[user-added]`, `[source unverified]`, and related
explanatory sentences use colons, parentheses, or separate sentences instead of
`—`, and apply the same cleanup to any other nearby affected prose referenced by
this comment.

Source: Coding guidelines

src/lib/actions/sandbox/doctor-inference.ts (1)

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

Fail-closed vs. skip distinction relies on an implicit failureLabel presence check.

skippedInferenceGatewayProbe and unavailableInferenceGatewayProbe both set probed: false, but only the latter sets failureLabel, which is what makes pushInferenceHealthCheck render one as "info" (skipped) and the other as "fail" (unavailable). This is correct per the tests, but it's a subtle, easy-to-break invariant for future edits (e.g., adding failureLabel to the skip path, or refactoring failed in pushInferenceHealthCheck, would silently flip a "sandbox unreachable" skip into a false failure or vice versa). Consider a short comment noting why one path sets failureLabel and the other doesn't, or making the distinction explicit (e.g., a skipped: true field) rather than relying on absence of an optional field.

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

In `@src/lib/actions/sandbox/doctor-inference.ts` around lines 53 - 103, The skip
vs unavailable distinction in `skippedInferenceGatewayProbe`,
`unavailableInferenceGatewayProbe`, and `collectInferenceRouteProbe` currently
depends on whether `failureLabel` is present, which is easy to break. Make this
intent explicit by adding a clear comment or an explicit skipped/unavailable
field in the `ProviderHealthStatus` flow, and update `pushInferenceHealthCheck`
to use that symbol instead of relying on implicit absence of `failureLabel`.
src/lib/actions/sandbox/doctor-inference.test.ts (1)

100-165: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Good boundary-level fail-closed coverage; two new branches remain untested.

These tests thoroughly exercise the new authoritative/non-authoritative composition (broken route + healthy upstream, healthy route + failed/throwing upstream, HTTP 503, null/throw probe unavailability). However, two branches introduced in doctor-inference.ts aren't covered by any test in this suite:

  • collectProviderHealthDiagnostics's provider === "unknown" path (doctor-inference.ts lines 120-122).
  • collectInferenceRouteProbe's sandboxReachable === false skip path (skippedInferenceGatewayProbe, doctor-inference.ts lines 53-62, 82), which resolves to status: "info" rather than "fail" — an easy regression to miss since it's the opposite of the unavailableInferenceGatewayProbe fail path that looks very similar.

Given the PR's emphasis on fail-closed regression coverage for this exact module, consider adding two more cases.

🧪 Suggested additional test cases
+  it("marks the provider route as unknown without a configured provider or model (`#6192`)", async () => {
+    const checks = await collectInferenceChecks(
+      "alpha",
+      { provider: "unknown", model: "unknown" },
+      true,
+      {
+        probeProviderHealthImpl: () => upstream(),
+        probeSandboxInferenceGatewayHealthImpl: async () => gateway(true),
+      },
+    );
+
+    expect(checks).toContainEqual(
+      expect.objectContaining({
+        label: "Provider health (upstream)",
+        status: "info",
+        detail: "provider route is unknown",
+      }),
+    );
+  });
+
+  it("skips the gateway probe instead of failing it when the sandbox is unreachable (`#6192`)", async () => {
+    const routeProbe = vi.fn(async () => gateway(true));
+    const checks = await collectInferenceChecks(
+      "alpha",
+      { provider: "nvidia-prod", model: "model" },
+      false,
+      {
+        probeProviderHealthImpl: () => upstream(),
+        probeSandboxInferenceGatewayHealthImpl: routeProbe,
+      },
+    );
+
+    expect(routeProbe).not.toHaveBeenCalled();
+    expect(checks).toContainEqual(
+      expect.objectContaining({ label: "Inference route (gateway)", status: "info" }),
+    );
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/actions/sandbox/doctor-inference.test.ts` around lines 100 - 165, Add
two missing test cases in doctor-inference.test.ts to cover the new branches in
collectInferenceChecks: one where the provider is "unknown" so
collectProviderHealthDiagnostics returns the unknown-provider path, and one
where sandboxReachable is false so collectInferenceRouteProbe takes the
skippedInferenceGatewayProbe path and reports an info status instead of fail.
Use the existing collectInferenceChecks helper and assert on the returned check
labels/statuses so the coverage matches the new branches in doctor-inference.ts.
src/lib/actions/sandbox/connect-inference-route-probe.ts (1)

64-109: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider relocating pure classification logic to domain/.

classifyInferenceRouteFailureLabel and parseSandboxInferenceRouteProbeResult are pure functions with no process/fs/OpenShell calls, but they live in actions/sandbox/. The README's inference-route guidance suggests transitional inference logic should sit under src/lib/inference/** (or a domain module), with actions limited to orchestration. Given connect.ts, inference-route-health.ts, and (per PR context) doctor-inference.ts all import this shared contract, a domain-level home would better match the stated layer ownership. Not blocking — the current placement keeps callers simple since they're all in actions/sandbox/.

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

In `@src/lib/actions/sandbox/connect-inference-route-probe.ts` around lines 64 -
109, Move the pure inference-route helpers out of actions/sandbox/ and into the
appropriate domain-level inference module so orchestration stays in actions
only. Relocate classifyInferenceRouteFailureLabel and
parseSandboxInferenceRouteProbeResult together with their shared contract types,
then update connect.ts, inference-route-health.ts, and any doctor-related caller
imports to use the new domain location. Keep buildSandboxInferenceRouteProbeArgs
in actions/sandbox/ since it performs sandbox command construction and is not
pure.

Source: Path instructions

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

Outside diff comments:
In `@docs/inference/use-local-inference.mdx`:
- Around line 273-275: The local inference reachability description in NemoClaw
is too strict and conflicts with the probe contract used by status and doctor.
Update the wording around the sandbox runtime check to match the same
reachability boundary as the authoritative probe, and make sure the logic
references the OpenShell bridge route and the https://inference.local/v1/models
check without narrowing success to only 2xx responses.

In `@src/lib/actions/sandbox/connect.ts`:
- Around line 799-807: The generic catch in connect.ts is using the default
repair messaging even when no repair was attempted, so update the error path
around the verify/repair flow to pass the correct flag into
printUnrecoverableInferenceRoute. Use the surrounding inference verification
logic in the connect flow to distinguish failures that happen before
repair-related work from those after repair, and call
printUnrecoverableInferenceRoute with repairAttempted set to false for
pre-repair exceptions so the output stays accurate.

---

Nitpick comments:
In `@docs/reference/commands.mdx`:
- Around line 1559-1561: Replace the em dash prose in the affected docs text
with standard punctuation, following the docs style guidance that forbids em
dashes in docs. Update the descriptive bullets in the command reference so the
`[user-added]`, `[source unverified]`, and related explanatory sentences use
colons, parentheses, or separate sentences instead of `—`, and apply the same
cleanup to any other nearby affected prose referenced by this comment.

In `@src/lib/actions/sandbox/connect-inference-route-probe.ts`:
- Around line 64-109: Move the pure inference-route helpers out of
actions/sandbox/ and into the appropriate domain-level inference module so
orchestration stays in actions only. Relocate classifyInferenceRouteFailureLabel
and parseSandboxInferenceRouteProbeResult together with their shared contract
types, then update connect.ts, inference-route-health.ts, and any doctor-related
caller imports to use the new domain location. Keep
buildSandboxInferenceRouteProbeArgs in actions/sandbox/ since it performs
sandbox command construction and is not pure.

In `@src/lib/actions/sandbox/doctor-inference.test.ts`:
- Around line 100-165: Add two missing test cases in doctor-inference.test.ts to
cover the new branches in collectInferenceChecks: one where the provider is
"unknown" so collectProviderHealthDiagnostics returns the unknown-provider path,
and one where sandboxReachable is false so collectInferenceRouteProbe takes the
skippedInferenceGatewayProbe path and reports an info status instead of fail.
Use the existing collectInferenceChecks helper and assert on the returned check
labels/statuses so the coverage matches the new branches in doctor-inference.ts.

In `@src/lib/actions/sandbox/doctor-inference.ts`:
- Around line 53-103: The skip vs unavailable distinction in
`skippedInferenceGatewayProbe`, `unavailableInferenceGatewayProbe`, and
`collectInferenceRouteProbe` currently depends on whether `failureLabel` is
present, which is easy to break. Make this intent explicit by adding a clear
comment or an explicit skipped/unavailable field in the `ProviderHealthStatus`
flow, and update `pushInferenceHealthCheck` to use that symbol instead of
relying on implicit absence of `failureLabel`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3b934609-2c11-4d6f-947e-c489af9c2ca1

📥 Commits

Reviewing files that changed from the base of the PR and between 6176034 and 130e74f.

📒 Files selected for processing (21)
  • docs/inference/use-local-inference.mdx
  • docs/monitoring/monitor-sandbox-activity.mdx
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • src/commands/sandbox/oclif-command-adapters.test.ts
  • src/lib/actions/sandbox/connect-flow.test.ts
  • src/lib/actions/sandbox/connect-inference-route-probe.test.ts
  • src/lib/actions/sandbox/connect-inference-route-probe.ts
  • src/lib/actions/sandbox/connect-route-repair-inconclusive.test.ts
  • src/lib/actions/sandbox/connect-route-repair.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/doctor-flow.test.ts
  • src/lib/actions/sandbox/doctor-inference.test.ts
  • src/lib/actions/sandbox/doctor-inference.ts
  • src/lib/actions/sandbox/doctor.ts
  • src/lib/actions/sandbox/inference-route-health.test.ts
  • src/lib/actions/sandbox/inference-route-health.ts
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/status-inference.test.ts
  • src/lib/actions/sandbox/status-snapshot.ts
💤 Files with no reviewable changes (5)
  • src/lib/actions/sandbox/status-inference.test.ts
  • src/lib/actions/sandbox/connect-route-repair.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/status-snapshot.ts
✅ Files skipped from review due to trivial changes (2)
  • docs/reference/troubleshooting.mdx
  • docs/monitoring/monitor-sandbox-activity.mdx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/commands/sandbox/oclif-command-adapters.test.ts
  • src/lib/actions/sandbox/connect-inference-route-probe.test.ts
  • src/lib/actions/sandbox/doctor.ts

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

# Conflicts:
#	test/langchain-deepagents-code-image.test.ts
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria apurvvkumaria enabled auto-merge (squash) July 8, 2026 20:52
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria apurvvkumaria merged commit 67114f5 into main Jul 8, 2026
43 checks passed
@apurvvkumaria apurvvkumaria deleted the fix/6192-authoritative-inference-route branch July 8, 2026 21:10
apurvvkumaria added a commit that referenced this pull request Jul 8, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prevent DCode login-shell startup output from impersonating
authoritative `inference.local` route-probe evidence. This post-merge
follow-up to #6412 keeps `connect` fail closed by suppressing profile
stdout until the real probe restores its capture descriptor and by
rejecting multiline or preamble-contaminated results.

## Related Issue

Follow-up to #6192 and merged PR #6412.

## Changes

- Preserve the probe capture stream on file descriptor 3 while
discarding DCode login-shell startup stdout.
- Restore stdout only inside the trusted inner probe before it emits
`OK` or `BROKEN` evidence.
- Require a single complete probe-result line after known OpenShell
framing normalization.
- Add adversarial regressions proving profile output and multiline
evidence cannot report false health, authorize repair, or open SSH.

## Type of Change

- [x] 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
<!-- 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:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: This tightens the existing
documented fail-closed trust boundary without changing commands, output
states, recovery guidance, or supported workflows.
- [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: A post-merge security
review of #6412 identified the startup-output spoof boundary; the fix
was reviewed as fail-closed and is covered by profile-spoof,
multiline-output, no-repair, and no-SSH regressions.
- [ ] 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 — 54 focused connect/probe tests and 18
status JSON/text integration tests passed.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] 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: Apurv Kumaria <akumaria@nvidia.com>


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

* **Bug Fixes**
* Improved sandbox connectivity/inference-route probing so login-shell
preamble output can’t be misread as the health check result.
* Tightened probe output validation to accept only a single, clean
`OK/BROKEN` status line (no extra text), reducing incorrect
“healthy/broken” determinations.
* **Tests**
* Added coverage for spoofing attempts via crafted shell and curl
configuration in an isolated temp home, including validation that marker
side effects do not occur.
* Extended parsing and preamble-boundary tests to ensure untrusted
composite outputs are classified as unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
cv pushed a commit that referenced this pull request Jul 8, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->
Make DCode inference-route health probes preserve managed observability
by running them through a side-effect-free, image-owned managed-exec
boundary. The new private launcher retains the trusted proxy and shell
hardening from #6497, while updated clients fail closed against older
images where the helper is absent.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->
Fixes #6504

Follow-up to #6497, #6412, and #6192.

## Changes
<!-- Bullet list of key changes. -->
- Install a root-owned, non-symlink `dcode-managed-exec` copy of the
reviewed DCode launcher and verify its ownership, mode, contents, and
real-path execution during image build.
- Route shared DCode status, doctor, rebuild-preflight, and connect
health probes through that side-effect-free boundary instead of the
stateful sandbox entrypoint.
- Preserve enabled and disabled observability marker state while
retaining managed proxy normalization, startup-file isolation, `curl
-q`, strict output parsing, and old-image fail-closed behavior.
- Add focused launcher, image-contract, shared health, and connect-flow
regression coverage.

## Type of Change

- [x] 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
<!-- 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:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: this restores configured
DCode observability across internal read-only route probes without
changing CLI syntax, output, configuration, or documented behavior.
- [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: nine-category security
review passed on the exact eight-file diff with no findings; exact-head
typed DCode and inference-routing live validation remain required before
merge.
- [ ] 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: `npx
vitest run --project cli` over the four route/connect/health files
passed 61 tests; `npx vitest run --project integration` over the
managed-exec/proxy/image files passed 33 tests.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not applicable; this
narrow boundary fix passed CLI build/typecheck, Bash syntax, test-size,
source-shape, title, project-membership, and scoped prek gates.
- [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)
- [ ] 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 doc 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: Apurv Kumaria <akumaria@nvidia.com>


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

* **New Features**
* Added a managed execution entrypoint for Deep Agents Code so route
checks and runtime probing use a dedicated, image-baked launcher path.

* **Bug Fixes**
* Improved the launcher’s behavior to avoid altering sandbox state
during route diagnostics and to fail safely when mis-invoked.
* Updated sandbox probe and health-check commands to use the managed
entrypoint consistently.

* **Tests**
* Added dedicated coverage for the managed entrypoint’s side effects and
failure handling.
* Extended image and sandbox contract tests to validate the managed
binary installation and command structure.
* Improved Deep Agents Code Tavily opt-in checks to reliably restore
observability state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
@cjagwani cjagwani mentioned this pull request Jul 9, 2026
21 tasks
cv pushed a commit that referenced this pull request Jul 9, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the user documentation for NemoClaw v0.0.78 by replacing the
unreleased section with release highlights and synchronizing the
affected inference, lifecycle, messaging, and CLI reference pages with
merged behavior.

## Changes

- Publish the v0.0.78 release-notes section with links to the most
specific user guides for each shipped behavior.
- Document authoritative Deep Agents route health, Nemotron Ultra
profile behavior, and Hermes compatible-endpoint context metadata.
- Document forced rebuild recovery after total backup failure and the
ownership-safe tunnel/full-stop behavior.
- Keep command examples and shared agent variants aligned with the
current OpenClaw, Hermes, and Deep Agents interfaces.

Source mapping:

- [#3787](#3787) ->
`docs/about/release-notes.mdx`: Record reliable workspace template
seeding during sandbox startup.
- [#4960](#4960) ->
`docs/about/release-notes.mdx`: Record safer detection of rewritten
OpenClaw gateway processes.
- [#5676](#5676) ->
`docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON
handling.
- [#5857](#5857) ->
`docs/about/release-notes.mdx`: Record synchronization of explicit
OpenClaw main-agent model state.
- [#5929](#5929) ->
`docs/about/release-notes.mdx`: Record copyable SSH port-forward
guidance for remote dashboards.
- [#6068](#6068) ->
`docs/about/release-notes.mdx`: Record custom-image plugin provenance
reconciliation.
- [#6116](#6116) ->
`docs/about/release-notes.mdx`: Record live-loopback dashboard-forward
recovery.
- [#6122](#6122) ->
`docs/about/release-notes.mdx`: Announce validated, round-trippable
policy YAML output.
- [#6211](#6211) ->
`docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild
--force` recovery boundary.
- [#6283](#6283) ->
`docs/about/release-notes.mdx`: Record Hermes WebUI port alignment.
- [#6293](#6293) ->
`docs/inference/switch-inference-providers.mdx`,
`docs/about/release-notes.mdx`: Document compatible-endpoint
context-length probing for Hermes.
- [#6320](#6320) ->
`docs/about/release-notes.mdx`: Record bounded gateway-recovery waits.
- [#6377](#6377) ->
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain
rebuild diagnostics and prepared MCP-destroy recovery.
- [#6412](#6412) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document authoritative agent-visible
inference route health.
- [#6421](#6421) ->
`docs/about/release-notes.mdx`: Record the longer quiet-pull window for
managed vLLM images.
- [#6431](#6431) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document the version-pinned Nemotron
Ultra profile plugin.
- [#6439](#6439) ->
`docs/about/release-notes.mdx`: Summarize the authenticated, pinned
credential-capture helper boundary.
- [#6450](#6450) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
host-forward cleanup and ownership-safe gateway-port release.
- [#6474](#6474) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/about/release-notes.mdx`: Record composable OpenClaw messaging
runtime loaders.
- [#6475](#6475) ->
`docs/about/release-notes.mdx`: Record removal of the unavailable Kimi
K2.6 production endpoint option.
- [#6480](#6480) ->
`docs/about/release-notes.mdx`: Record stderr routing for the plugin
registration banner.
- [#6481](#6481) ->
`docs/about/release-notes.mdx`: Record post-pull Ollama model discovery
checks.
- [#6482](#6482) ->
`docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon
restart.
- [#6486](#6486) ->
`docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep
Agents auto-approval boundary.
- [#6490](#6490) ->
`docs/about/release-notes.mdx`: Record diagnostics for custom images
missing the managed runtime.
- [#6494](#6494) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document nonempty tool-call content
preservation and placeholder rejection.
- [#6497](#6497) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document isolated Deep Agents
route-probe output.
- [#6506](#6506) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document observability-preserving
managed route probes.
- [#6508](#6508) ->
`docs/about/release-notes.mdx`: Link the new extension taxonomy and
SDK-readiness reference from the release summary.

Release-source verification: GitHub reports all 29 cited source PRs as
merged with base `main`, and every merge commit is an ancestor of
`origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No
source-mapping mismatches were found.

## Type of Change

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

## Quality Gates

<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: Documentation-only
release-prep changes; `npm run docs` validates variants, routes, and
Fern content.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: Tests
are not applicable to this documentation-only change set.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — exited
0 with zero errors; Fern reported the existing unauthenticated
redirect-check and light-mode contrast warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

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

---------

Signed-off-by: cjagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Make the in-sandbox `https://inference.local/v1/models` route
authoritative for inference health in `nemoclaw status`, `nemoclaw
doctor`, and `nemoclaw connect`. This supersedes NVIDIA#6203 and NVIDIA#6264 while
retaining credit for Harjoth's original implementation and Souvik's
typed test-seam contribution.

## Related Issue

Fixes NVIDIA#6192

## Changes

- Share one agent-aware `inference.local` probe and fail-closed parser
across connect, status, and doctor.
- Treat final HTTP 200-499 responses as route-reachable; treat interim
100-199 responses, HTTP 500-599, `000`, malformed output, timeout, and
unavailable probes as failing.
- Centralize route-failure labels and status exit decisions so text,
JSON, status, doctor, and connect cannot drift.
- Discard route-probe response bodies through `/dev/null` instead of a
persistent sandbox temp file.
- Verify route TLS with OpenShell's managed CA bundle; certificate
failures are authoritative unreachable results.
- Keep direct provider checks as explicitly labeled, non-authoritative
upstream diagnostics.
- Return nonzero status for unhealthy or unavailable inference routes in
text and JSON output.
- Add regression coverage for HTTP boundaries, unavailable probes,
framed OpenShell output, no-direct-probe providers, DCode, and CLI exit
behavior.
- Update command, monitoring, local-inference, and troubleshooting
documentation for the authoritative route semantics.

## Type of Change

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

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: [nine-category review
passed after the only hardening finding was
fixed](NVIDIA#6412 (comment)).
- [ ] 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 — `npx vitest run --project cli` over
the nine route/connect/status/doctor/recovery/adapter files: 163 passed;
`npx vitest run --project integration` over the eight changed
CLI/recovery files: 43 passed.
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: `npm run checks` passed;
the exact-head PR CI suite completed without failures; [typed OpenClaw
and DCode live
targets](https://github.com/NVIDIA/NemoClaw/actions/runs/28970519701)
passed; [inference-routing, diagnostics, and sandbox-operations live
jobs](https://github.com/NVIDIA/NemoClaw/actions/runs/28970503175)
passed.
- [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) — build
passed with 0 errors and two existing Fern warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)


## Architecture and Runtime-Boundary Review

- **Invalid state:** Host/provider checks can succeed while the
agent-visible `https://inference.local/v1/models` route is unusable.
This PR exposes that disagreement; it does not preserve or mask it.
- **Source boundary:** OpenShell owns sandbox exec, DNS, TLS CA
injection, and proxy provisioning. NemoClaw owns interpretation and
orchestration in `status`, `doctor`, and `connect`, so it probes the
exact in-sandbox route and fails closed when OpenShell cannot return
trusted `OK` or `BROKEN` evidence.
- **Source-fix constraint:** Read-only diagnostics cannot repair
OpenShell infrastructure, and an inconclusive result is inherently
lossy. `connect` must not open SSH or mutate route state on inconclusive
evidence. This fail-closed behavior is a permanent security boundary,
not a temporary workaround.
- **Regression and removal contract:** Checked-in parser, flow, CLI,
missing-CA, 401/403, DCode argv/proxy, and redaction tests cover
deterministic fault injection. The DCode wrapper may be removed only if
OpenShell provides an agent-independent structured route-health API that
preserves its CA and login-shell contract; fail-closed handling remains.
- **Runtime justification:** A separate standalone live artifact would
duplicate the repository's existing typed E2E lanes. Exact head
`130e74f3c520aa82db86fd80e830eff362390b08` passed the [required live
jobs](https://github.com/NVIDIA/NemoClaw/actions/runs/28970503175) and
[OpenClaw and DCode live
targets](https://github.com/NVIDIA/NemoClaw/actions/runs/28970519701);
exact-head macOS E2E and arm64 image/build checks also passed. Induced
broken-route, auth, and CA faults remain deterministic checked-in tests
to avoid destructive shared-state mutation.
- **PR sequencing:** NVIDIA#6412 is foundational. Merge it first, then rebase
NVIDIA#6465 and integrate its additive route-drift warning into the final
status-snapshot shape.

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

* **New Features**
* Added clearer, authoritative inference health checks and diagnostics
for sandbox status and doctor commands.
* `connect` now fails closed when the in-sandbox inference route cannot
be trusted, with safer redacted error details.

* **Bug Fixes**
* Improved handling of reachable, unhealthy, unreachable, and not-probed
inference states.
* Fixed status exit behavior so inference-route failures correctly
return a non-zero result.

* **Documentation**
* Updated troubleshooting and command docs to explain the new inference
health and proxy diagnostic output.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: harjoth <harjoth.khara@gmail.com>
Co-authored-by: Souvik Ghosh
<138186578+souvikDevloper@users.noreply.github.com>

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Co-authored-by: harjoth <harjoth.khara@gmail.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prevent DCode login-shell startup output from impersonating
authoritative `inference.local` route-probe evidence. This post-merge
follow-up to NVIDIA#6412 keeps `connect` fail closed by suppressing profile
stdout until the real probe restores its capture descriptor and by
rejecting multiline or preamble-contaminated results.

## Related Issue

Follow-up to NVIDIA#6192 and merged PR NVIDIA#6412.

## Changes

- Preserve the probe capture stream on file descriptor 3 while
discarding DCode login-shell startup stdout.
- Restore stdout only inside the trusted inner probe before it emits
`OK` or `BROKEN` evidence.
- Require a single complete probe-result line after known OpenShell
framing normalization.
- Add adversarial regressions proving profile output and multiline
evidence cannot report false health, authorize repair, or open SSH.

## Type of Change

- [x] 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
<!-- 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:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: This tightens the existing
documented fail-closed trust boundary without changing commands, output
states, recovery guidance, or supported workflows.
- [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: A post-merge security
review of NVIDIA#6412 identified the startup-output spoof boundary; the fix
was reviewed as fail-closed and is covered by profile-spoof,
multiline-output, no-repair, and no-SSH regressions.
- [ ] 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 — 54 focused connect/probe tests and 18
status JSON/text integration tests passed.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] 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: Apurv Kumaria <akumaria@nvidia.com>


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

* **Bug Fixes**
* Improved sandbox connectivity/inference-route probing so login-shell
preamble output can’t be misread as the health check result.
* Tightened probe output validation to accept only a single, clean
`OK/BROKEN` status line (no extra text), reducing incorrect
“healthy/broken” determinations.
* **Tests**
* Added coverage for spoofing attempts via crafted shell and curl
configuration in an isolated temp home, including validation that marker
side effects do not occur.
* Extended parsing and preamble-boundary tests to ensure untrusted
composite outputs are classified as unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->
Make DCode inference-route health probes preserve managed observability
by running them through a side-effect-free, image-owned managed-exec
boundary. The new private launcher retains the trusted proxy and shell
hardening from NVIDIA#6497, while updated clients fail closed against older
images where the helper is absent.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->
Fixes NVIDIA#6504

Follow-up to NVIDIA#6497, NVIDIA#6412, and NVIDIA#6192.

## Changes
<!-- Bullet list of key changes. -->
- Install a root-owned, non-symlink `dcode-managed-exec` copy of the
reviewed DCode launcher and verify its ownership, mode, contents, and
real-path execution during image build.
- Route shared DCode status, doctor, rebuild-preflight, and connect
health probes through that side-effect-free boundary instead of the
stateful sandbox entrypoint.
- Preserve enabled and disabled observability marker state while
retaining managed proxy normalization, startup-file isolation, `curl
-q`, strict output parsing, and old-image fail-closed behavior.
- Add focused launcher, image-contract, shared health, and connect-flow
regression coverage.

## Type of Change

- [x] 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
<!-- 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:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: this restores configured
DCode observability across internal read-only route probes without
changing CLI syntax, output, configuration, or documented behavior.
- [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: nine-category security
review passed on the exact eight-file diff with no findings; exact-head
typed DCode and inference-routing live validation remain required before
merge.
- [ ] 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: `npx
vitest run --project cli` over the four route/connect/health files
passed 61 tests; `npx vitest run --project integration` over the
managed-exec/proxy/image files passed 33 tests.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not applicable; this
narrow boundary fix passed CLI build/typecheck, Bash syntax, test-size,
source-shape, title, project-membership, and scoped prek gates.
- [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)
- [ ] 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 doc 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: Apurv Kumaria <akumaria@nvidia.com>


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

* **New Features**
* Added a managed execution entrypoint for Deep Agents Code so route
checks and runtime probing use a dedicated, image-baked launcher path.

* **Bug Fixes**
* Improved the launcher’s behavior to avoid altering sandbox state
during route diagnostics and to fail safely when mis-invoked.
* Updated sandbox probe and health-check commands to use the managed
entrypoint consistently.

* **Tests**
* Added dedicated coverage for the managed entrypoint’s side effects and
failure handling.
* Extended image and sandbox contract tests to validate the managed
binary installation and command structure.
* Improved Deep Agents Code Tavily opt-in checks to reliably restore
observability state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Prepares the user documentation for NemoClaw v0.0.78 by replacing the
unreleased section with release highlights and synchronizing the
affected inference, lifecycle, messaging, and CLI reference pages with
merged behavior.

## Changes

- Publish the v0.0.78 release-notes section with links to the most
specific user guides for each shipped behavior.
- Document authoritative Deep Agents route health, Nemotron Ultra
profile behavior, and Hermes compatible-endpoint context metadata.
- Document forced rebuild recovery after total backup failure and the
ownership-safe tunnel/full-stop behavior.
- Keep command examples and shared agent variants aligned with the
current OpenClaw, Hermes, and Deep Agents interfaces.

Source mapping:

- [NVIDIA#3787](NVIDIA#3787) ->
`docs/about/release-notes.mdx`: Record reliable workspace template
seeding during sandbox startup.
- [NVIDIA#4960](NVIDIA#4960) ->
`docs/about/release-notes.mdx`: Record safer detection of rewritten
OpenClaw gateway processes.
- [NVIDIA#5676](NVIDIA#5676) ->
`docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON
handling.
- [NVIDIA#5857](NVIDIA#5857) ->
`docs/about/release-notes.mdx`: Record synchronization of explicit
OpenClaw main-agent model state.
- [NVIDIA#5929](NVIDIA#5929) ->
`docs/about/release-notes.mdx`: Record copyable SSH port-forward
guidance for remote dashboards.
- [NVIDIA#6068](NVIDIA#6068) ->
`docs/about/release-notes.mdx`: Record custom-image plugin provenance
reconciliation.
- [NVIDIA#6116](NVIDIA#6116) ->
`docs/about/release-notes.mdx`: Record live-loopback dashboard-forward
recovery.
- [NVIDIA#6122](NVIDIA#6122) ->
`docs/about/release-notes.mdx`: Announce validated, round-trippable
policy YAML output.
- [NVIDIA#6211](NVIDIA#6211) ->
`docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`,
`docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild
--force` recovery boundary.
- [NVIDIA#6283](NVIDIA#6283) ->
`docs/about/release-notes.mdx`: Record Hermes WebUI port alignment.
- [NVIDIA#6293](NVIDIA#6293) ->
`docs/inference/switch-inference-providers.mdx`,
`docs/about/release-notes.mdx`: Document compatible-endpoint
context-length probing for Hermes.
- [NVIDIA#6320](NVIDIA#6320) ->
`docs/about/release-notes.mdx`: Record bounded gateway-recovery waits.
- [NVIDIA#6377](NVIDIA#6377) ->
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain
rebuild diagnostics and prepared MCP-destroy recovery.
- [NVIDIA#6412](NVIDIA#6412) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document authoritative agent-visible
inference route health.
- [NVIDIA#6421](NVIDIA#6421) ->
`docs/about/release-notes.mdx`: Record the longer quiet-pull window for
managed vLLM images.
- [NVIDIA#6431](NVIDIA#6431) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document the version-pinned Nemotron
Ultra profile plugin.
- [NVIDIA#6439](NVIDIA#6439) ->
`docs/about/release-notes.mdx`: Summarize the authenticated, pinned
credential-capture helper boundary.
- [NVIDIA#6450](NVIDIA#6450) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
host-forward cleanup and ownership-safe gateway-port release.
- [NVIDIA#6474](NVIDIA#6474) ->
`docs/manage-sandboxes/messaging-channels.mdx`,
`docs/about/release-notes.mdx`: Record composable OpenClaw messaging
runtime loaders.
- [NVIDIA#6475](NVIDIA#6475) ->
`docs/about/release-notes.mdx`: Record removal of the unavailable Kimi
K2.6 production endpoint option.
- [NVIDIA#6480](NVIDIA#6480) ->
`docs/about/release-notes.mdx`: Record stderr routing for the plugin
registration banner.
- [NVIDIA#6481](NVIDIA#6481) ->
`docs/about/release-notes.mdx`: Record post-pull Ollama model discovery
checks.
- [NVIDIA#6482](NVIDIA#6482) ->
`docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon
restart.
- [NVIDIA#6486](NVIDIA#6486) ->
`docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep
Agents auto-approval boundary.
- [NVIDIA#6490](NVIDIA#6490) ->
`docs/about/release-notes.mdx`: Record diagnostics for custom images
missing the managed runtime.
- [NVIDIA#6494](NVIDIA#6494) ->
`docs/inference/model-capability-audit.mdx`,
`docs/about/release-notes.mdx`: Document nonempty tool-call content
preservation and placeholder rejection.
- [NVIDIA#6497](NVIDIA#6497) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document isolated Deep Agents
route-probe output.
- [NVIDIA#6506](NVIDIA#6506) ->
`docs/get-started/quickstart-langchain-deepagents-code.mdx`,
`docs/about/release-notes.mdx`: Document observability-preserving
managed route probes.
- [NVIDIA#6508](NVIDIA#6508) ->
`docs/about/release-notes.mdx`: Link the new extension taxonomy and
SDK-readiness reference from the release summary.

Release-source verification: GitHub reports all 29 cited source PRs as
merged with base `main`, and every merge commit is an ancestor of
`origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No
source-mapping mismatches were found.

## Type of Change

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

## Quality Gates

<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: Documentation-only
release-prep changes; `npm run docs` validates variants, routes, and
Fern content.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: Tests
are not applicable to this documentation-only change set.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — exited
0 with zero errors; Fern reported the existing unauthenticated
redirect-check and light-mode contrast warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

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

---------

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

Labels

area: cli Command line interface, flags, terminal UX, or output area: inference Inference routing, serving, model selection, or outputs area: routing Request routing, policy routing, model selection, or fallback logic bug-fix PR fixes a bug or regression integration: dcode LangChain Deep Code integration behavior v0.0.78 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platforms][CLI&UX] nemoclaw status/doctor report inference "healthy" by probing the upstream, not the inference.local route the agent uses

6 participants