fix(status): make inference route health authoritative#6412
Conversation
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>
|
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. |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage remains at 96%, unchanged from the branch. TypeScript / code-coverage/cliThe overall coverage in the branch remains at 76%, unchanged from the branch. Show a code coverage summary of the most impacted files.
Updated |
|
🌿 Preview your docs: https://nvidia-preview-pr-6412.docs.buildwithfern.com/nemoclaw |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR makes an in-sandbox probe of ChangesInference route authority fix
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
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)
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
E2E Target RecommendationRequired E2E targets: Dispatch required E2E targets:
Full E2E target advisor summaryE2E Target AdvisorBase: Required E2E targets
Optional E2E targets
Relevant changed files
|
PR Review Advisor — Changes requestedMerge posture: Do not merge yet Action checklist
Findings index
Review findings by urgency: 0 required fixes, 2 items to resolve/justify, 0 in-scope improvements
|
PR Review Advisor (Nemotron Ultra) — Changes requestedMerge posture: Do not merge yet Action checklist
Findings index
🚨 Required before mergeAddress these before merging unless a maintainer explicitly overrides the advisor with rationale.
|
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>
Sensitive-path security review — PASSI reviewed the full PR diff against the nine-category NemoClaw security checklist. The authoritative, fail-closed The first pass found one low-severity hardening issue: the shared probe wrote response bodies to a fixed sandbox A later advisor pass found that the probe still used curl's The final advisor pass identified that an interim HTTP 1xx response was accepted as healthy even though Final-head live diagnostics then proved that removing
Verification after the hardening changes:
Files reviewed: |
There was a problem hiding this comment.
🧹 Nitpick comments (6)
docs/inference/use-local-inference.mdx (1)
162-163: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTerminology drift from the authoritative state table.
This section uses "reachable" and "broken" for the sandbox probe outcomes, but
docs/reference/commands.mdxanddocs/reference/commands-nemohermes.mdxdefine the authoritative states ashealthy,unhealthy,unreachable,not probed, andnot 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 winTest duplicates the production shell-script literal instead of importing it.
INFERENCE_ROUTE_PROBE_SCRIPThere is a hand-copied duplicate of the script string owned byconnect-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. forbuildSandboxInferenceRouteProbeArgs) 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.tsand 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 valueDuplicate stub block repeated across tests.
The same 4-line "sandbox exec → OK 200" fallback is copy-pasted into four separate
openshellstub scripts in this file. Consider extracting a small helper (similar to howcreateDoctorTestSetupcentralizes this inhelpers.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 valueMock-call argv assertion tests implementation shape, not behavior.
This test asserts the exact array passed to
captureOpenshellImplrather than an observable effect ofprobeSandboxInferenceGatewayHealth. 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 winInference-health failure predicate duplicated between JSON and text paths.
This inline condition (
inferenceHealth && (!probed || !ok)) is logically the same "is inference unhealthy" check asinferenceHealthExitCodeinstatus-text.ts, implemented independently. As per path instructions, behavior/orchestration decisions belong insrc/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 winDuplicate HTTP-status boundary classification across files.
buildSandboxInferenceRouteHealthre-derivesgateway.httpStatus >= 500 && gateway.httpStatus < 600to pick"unhealthy"vs"unreachable", butprobeSandboxInferenceGatewayHealthinprocess-recovery.tsalready encodes the exact same 500-599 boundary independently to build itsdetailwording. Since this PR's whole point is making the 100-499/500-599/000 boundary consistent and authoritative acrossstatus,doctor, andconnect, 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
📒 Files selected for processing (24)
docs/inference/use-local-inference.mdxdocs/monitoring/monitor-sandbox-activity.mdxdocs/reference/commands-nemohermes.mdxdocs/reference/commands.mdxdocs/reference/troubleshooting.mdxsrc/commands/sandbox/oclif-command-adapters.test.tssrc/commands/sandbox/status.tssrc/lib/actions/sandbox/connect-inference-route-probe.test.tssrc/lib/actions/sandbox/connect-inference-route-probe.tssrc/lib/actions/sandbox/connect-route-repair.test.tssrc/lib/actions/sandbox/connect.tssrc/lib/actions/sandbox/doctor-flow.test.tssrc/lib/actions/sandbox/doctor.tssrc/lib/actions/sandbox/process-recovery.test.tssrc/lib/actions/sandbox/process-recovery.tssrc/lib/actions/sandbox/status-flow.test.tssrc/lib/actions/sandbox/status-snapshot.tssrc/lib/actions/sandbox/status-text.tssrc/lib/actions/sandbox/status.test.tstest/cli/helpers.tstest/cli/sandbox-status-json.test.tstest/cli/sandbox-status-text.test.tstest/cli/status-gateway-lifecycle.test.tstest/support/status-flow-test-harness.ts
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>
E2E Target Results — ✅ All selected jobs passedRun: 28886806104
|
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>
E2E Target Results — ✅ All requested jobs passedRun: 28886806227
|
E2E Target Results — ✅ All selected jobs passedRun: 28887240249
|
E2E Target Results — ❌ Some jobs failedRun: 28887240238
|
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
E2E Target Results — ✅ All selected jobs passedRun: 28887940694
|
E2E Target Results — ❌ Some jobs failedRun: 28887945371
|
E2E Target Results — ✅ All requested jobs passedRun: 28969901801
|
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
E2E Target Results — ✅ All selected jobs passedRun: 28970519701
|
E2E Target Results — ✅ All requested jobs passedRun: 28970503175
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
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 winUse the same reachability boundary here.
This sentence conflicts with the authoritative probe contract above.
statusanddoctortreat final200–499responses as reachable, so this should not narrow success to2xx.♻️ 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 winGeneric catch defaults to “repair attempted” messaging even when no repair ran.
printUnrecoverableInferenceRouteis called here without{ repairAttempted: false }, so it defaults totrueand prints "...after DNS and route repair" / "known to be broken." But exceptions reaching this generic catch (e.g., a failure in theinference getcall orparseGatewayInferencebeforerepairSandboxInferenceRouteIfNeededeven 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 winReplace em dashes with standard punctuation.
These changed lines use em dashes (
—) in prose, e.g. "[user-added]— anything else: presets applied later throughpolicy-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 winFail-closed vs. skip distinction relies on an implicit
failureLabelpresence check.
skippedInferenceGatewayProbeandunavailableInferenceGatewayProbeboth setprobed: false, but only the latter setsfailureLabel, which is what makespushInferenceHealthCheckrender 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., addingfailureLabelto the skip path, or refactoringfailedinpushInferenceHealthCheck, would silently flip a "sandbox unreachable" skip into a false failure or vice versa). Consider a short comment noting why one path setsfailureLabeland the other doesn't, or making the distinction explicit (e.g., askipped: truefield) 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 winGood 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.tsaren't covered by any test in this suite:
collectProviderHealthDiagnostics'sprovider === "unknown"path (doctor-inference.tslines 120-122).collectInferenceRouteProbe'ssandboxReachable === falseskip path (skippedInferenceGatewayProbe,doctor-inference.tslines 53-62, 82), which resolves tostatus: "info"rather than"fail"— an easy regression to miss since it's the opposite of theunavailableInferenceGatewayProbefail 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 tradeoffConsider relocating pure classification logic to
domain/.
classifyInferenceRouteFailureLabelandparseSandboxInferenceRouteProbeResultare pure functions with no process/fs/OpenShell calls, but they live inactions/sandbox/. The README's inference-route guidance suggests transitional inference logic should sit undersrc/lib/inference/**(or a domain module), with actions limited to orchestration. Givenconnect.ts,inference-route-health.ts, and (per PR context)doctor-inference.tsall 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 inactions/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
📒 Files selected for processing (21)
docs/inference/use-local-inference.mdxdocs/monitoring/monitor-sandbox-activity.mdxdocs/reference/commands.mdxdocs/reference/troubleshooting.mdxsrc/commands/sandbox/oclif-command-adapters.test.tssrc/lib/actions/sandbox/connect-flow.test.tssrc/lib/actions/sandbox/connect-inference-route-probe.test.tssrc/lib/actions/sandbox/connect-inference-route-probe.tssrc/lib/actions/sandbox/connect-route-repair-inconclusive.test.tssrc/lib/actions/sandbox/connect-route-repair.test.tssrc/lib/actions/sandbox/connect.tssrc/lib/actions/sandbox/doctor-flow.test.tssrc/lib/actions/sandbox/doctor-inference.test.tssrc/lib/actions/sandbox/doctor-inference.tssrc/lib/actions/sandbox/doctor.tssrc/lib/actions/sandbox/inference-route-health.test.tssrc/lib/actions/sandbox/inference-route-health.tssrc/lib/actions/sandbox/process-recovery.test.tssrc/lib/actions/sandbox/process-recovery.tssrc/lib/actions/sandbox/status-inference.test.tssrc/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>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
<!-- 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>
<!-- 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>
<!-- 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>
<!-- 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>
<!-- 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>
<!-- 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>
<!-- 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>
Summary
Make the in-sandbox
https://inference.local/v1/modelsroute authoritative for inference health innemoclaw status,nemoclaw doctor, andnemoclaw 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
inference.localprobe and fail-closed parser across connect, status, and doctor.000, malformed output, timeout, and unavailable probes as failing./dev/nullinstead of a persistent sandbox temp file.Type of Change
Quality Gates
Verification
Verifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpx vitest run --project cliover the nine route/connect/status/doctor/recovery/adapter files: 163 passed;npx vitest run --project integrationover the eight changed CLI/recovery files: 43 passed.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run checkspassed; 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.npm run docsbuilds without warnings (doc changes only) — build passed with 0 errors and two existing Fern warnings.Architecture and Runtime-Boundary Review
https://inference.local/v1/modelsroute is unusable. This PR exposes that disagreement; it does not preserve or mask it.status,doctor, andconnect, so it probes the exact in-sandbox route and fails closed when OpenShell cannot return trustedOKorBROKENevidence.connectmust not open SSH or mutate route state on inconclusive evidence. This fail-closed behavior is a permanent security boundary, not a temporary workaround.130e74f3c520aa82db86fd80e830eff362390b08passed 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.Summary by CodeRabbit
New Features
connectnow fails closed when the in-sandbox inference route cannot be trusted, with safer redacted error details.Bug Fixes
Documentation
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