Skip to content

fix(status): wait for inference after gateway recovery - #8572

Open
jyaunches wants to merge 11 commits into
mainfrom
codex/e2e-sandbox-recovery
Open

fix(status): wait for inference after gateway recovery#8572
jyaunches wants to merge 11 commits into
mainfrom
codex/e2e-sandbox-recovery

Conversation

@jyaunches

@jyaunches jyaunches commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Sandbox status now waits for the authoritative inference route to converge after it automatically recovers a stopped agent gateway. Ordinary status checks remain single-probe, and persistent recovery failures still fail closed.

Changes

  • Retain whether status successfully recovered a previously stopped managed gateway.
  • Retry inference.local up to three times, with two-second delays, only after that recovery.
  • Cover successful convergence, persistent failure, and unchanged ordinary status behavior.

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: Existing command documentation already states that status restores gateway processes before probing inference; commands, configuration, output, and remediation remain unchanged.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: Independent review covered recovery qualification, bounded retry behavior, and fail-closed exhaustion.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: The change adds a bounded internal inference-health retry after managed gateway recovery. It does not change commands, flags, configuration, output, schema, or documented recovery steps; docs/reference/commands.mdx already states that status restores the gateway and host forwards before probing inference.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: Three focused status suites passed 32 tests; CLI typecheck, Biome, test-title, and diff checks passed.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Julie Yaunches jyaunches@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved sandbox status checks after managed gateway recovery.
    • Inference availability is rechecked up to three times, with brief delays between attempts, stopping once service is confirmed available.
    • Prevents temporary recovery delays from being incorrectly reported as an unreachable inference service.
    • Standard status checks remain fast, using a single availability probe without unnecessary waiting.
    • Recovery retries occur only when the managed gateway was stopped and successfully restored.

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@jyaunches jyaunches self-assigned this Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4617a8ed-6fe7-4af6-b3ec-530150746f55

📥 Commits

Reviewing files that changed from the base of the PR and between 4579f29 and 77c7293.

📒 Files selected for processing (1)
  • src/lib/onboard/setup-nim-flow.test.ts

📝 Walkthrough

Walkthrough

Sandbox status checks record successful managed-gateway recovery and retry the inference route up to three times with two-second delays. Tests cover recovery outcomes, ordinary status lookup, test timeouts, and the updated approval documentation fixture.

Changes

Inference recovery probing

Layer / File(s) Summary
Track managed-gateway recovery
src/lib/actions/sandbox/status-snapshot.ts
Adds recovery probe timing, delay injection, and state tracking for successful recovery of previously stopped gateways.
Retry authoritative inference probes
src/lib/actions/sandbox/status-snapshot.ts, src/lib/actions/sandbox/status-snapshot-inference-health.test.ts
Retries failed inference probes after recovery, stops on success, and preserves one probe for ordinary status checks.
Update supporting test setup
src/lib/shields/policy-transition.test.ts, test/repro-5324-operator-admin-approval-docs.test.ts, src/lib/onboard/setup-nim-flow.test.ts
Increases test timeouts and updates the approval documentation test fixture path and heading.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SandboxStatusSnapshot
  participant ManagedGateway
  participant InferenceRoute
  participant ProbeDelay
  ManagedGateway->>SandboxStatusSnapshot: complete successful recovery
  SandboxStatusSnapshot->>InferenceRoute: perform inference probe
  InferenceRoute-->>SandboxStatusSnapshot: return probe result
  SandboxStatusSnapshot->>ProbeDelay: wait two seconds after failure
  ProbeDelay-->>SandboxStatusSnapshot: allow next probe
Loading

Possibly related PRs

Suggested labels: area: inference, bug-fix

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: waiting for inference after gateway recovery.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/e2e-sandbox-recovery

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

@github-code-quality

github-code-quality Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 920a6f6 in the codex/e2e-sandbox-re... branch remains at 96%, unchanged from commit aeaaf1a in the main branch.


Updated August 08, 2026 03:28 UTC

@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 (1)
src/lib/actions/sandbox/status-snapshot.ts (1)

571-578: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the recovery probe loop into a private helper.

collectSandboxStatusSnapshot already owns several lifecycle paths. Move this retry loop to a focused helper that accepts sandboxName, recoveredManagedGateway, probe, and delay. Keep the action as the workflow owner.

As per coding guidelines, “Keep function complexity low.”

🤖 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 571 - 578, Extract
the retry loop from collectSandboxStatusSnapshot into a private helper that
accepts sandboxName, recoveredManagedGateway, probe, and delay, and returns the
resulting gatewayChain. Replace the inline loop with a call to this helper while
keeping collectSandboxStatusSnapshot responsible for the surrounding workflow
and preserving the existing retry counts and delay behavior.

Source: Coding guidelines

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

Nitpick comments:
In `@src/lib/actions/sandbox/status-snapshot.ts`:
- Around line 571-578: Extract the retry loop from collectSandboxStatusSnapshot
into a private helper that accepts sandboxName, recoveredManagedGateway, probe,
and delay, and returns the resulting gatewayChain. Replace the inline loop with
a call to this helper while keeping collectSandboxStatusSnapshot responsible for
the surrounding workflow and preserving the existing retry counts and delay
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 63a3c6b7-59b9-4e76-b72a-70a8e5470db9

📥 Commits

Reviewing files that changed from the base of the PR and between b22f67b and ab4a337.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/status-snapshot-inference-health.test.ts
  • src/lib/actions/sandbox/status-snapshot.ts

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed after a partial review · low confidence · 0 blockers · 1 warning · 1 suggestion

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

3 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — inference route at src/lib/actions/sandbox/status-snapshot-inference-health.test.ts:87: Keep `inference route`; it is the established controlled term.
  • established — agent gateway at src/lib/actions/sandbox/status-snapshot-inference-health.test.ts:87: Keep `agent gateway` to distinguish the recovered service from the OpenShell gateway.
  • justified — post-recovery probe at src/lib/actions/sandbox/status-snapshot-inference-health.test.ts:135: Keep `post-recovery probe`; the modifier states the behaviorally relevant condition.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: onboard-repair, onboard-resume, rebuild-openclaw, state-backup-restore, ubuntu-repo-docker-post-reboot-recovery, cloud-onboard

1 optional E2E recommendation
  • inference-routing

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

prekshivyas added a commit that referenced this pull request Aug 8, 2026
)

## Summary

First incremental step on #6014. The Ollama auth proxy now independently
verifies that the Ollama backend is listening only on loopback before
declaring itself ready, with a structured exit signal the host CLI
renders as a specific actionable remediation. Leaves the existing
root-level systemd loopback override (#5996, #5716) in place for this
PR.

## Why an independent probe in the proxy

The proxy currently trusts the systemd drop-in to keep Ollama bound to
`127.0.0.1`. If a user manually edits `OLLAMA_HOST` to `0.0.0.0`, the
proxy still forwards to `127.0.0.1:11434` successfully (Ollama listens
there too) but Ollama is ALSO publicly reachable on `0.0.0.0:11434`,
bypassing the proxy's bearer-token check entirely.

The new probe runs before `server.listen` and refuses to start with exit
code 2 if it sees any non-loopback listener on the backend port. This
moves bind-policy enforcement off the root-coupled systemd path and onto
the proxy itself; the systemd drop-in becomes pure defense-in-depth that
subsequent PRs can retire.

## Changes

- `scripts/ollama-auth-proxy.mts`:
- Independently enumerates backend listeners through `/proc/net/tcp{,6}`
with an `lsof` fallback and refuses any non-loopback listener before
`server.listen`.
- Recognizes the full `127.0.0.0/8`, `::1`, and IPv4-mapped IPv6
loopback shapes both in listener classification and in deciding whether
a local backend URL requires the probe.
- Writes structured startup failure status for host-side remediation and
retains the explicit audited operator override.
- Is fully checked by `tsconfig.cli.json`; no `@ts-nocheck` suppression
remains.
- Keeps side effects inside `main()`, gated by `import.meta.main`, while
exporting typed helpers for focused tests.

- `src/lib/inference/ollama/proxy.ts`:
- Persist a sentinel path (`~/.nemoclaw/ollama-auth-proxy.status`) and
pass it to the spawned proxy via env
- On proxy spawn, unlink any stale status file so a later read sees the
new proxy's reason
- When the readiness loop observes the proxy gone, read the status file
via `readProxyExitStatus` and render specific remediation via
`printProxyStartupReason` for the `backend-not-loopback` reason; fall
back to existing port-conflict or generic message when no status file is
present

- `test/ollama-auth-proxy-bind-probe.test.ts`: 40 Vitest cases cover
listener parsing, all supported loopback encodings, explicit rejects,
local-versus-remote backend trigger selection, the exit-code contract,
and Linux `/proc` integration.

## What this does NOT do (follow-up PRs per #6014)

- Does not delete `ensureOllamaLoopbackSystemdOverride`. The systemd
drop-in still runs on Linux and stays the authority for Ollama's bind on
a fresh install. The probe is independent enforcement on top, not a
replacement.
- Does not relocate `OLLAMA_CONTEXT_LENGTH` or the Spark
`OLLAMA_LLM_LIBRARY=cuda_v13` overrides off the systemd drop-in. Those
are load-bearing for non-security reasons and belong in a follow-up that
moves them to a config-only path before the drop-in writer can be
deleted.
- Does not add periodic re-probing during proxy lifetime; the current PR
only checks at startup. A follow-up could probe periodically to catch
mid-run bind changes.
- Does not cover Docker-Desktop topologies (WSL + Windows-host Ollama,
WSL + WSL-local Ollama). Those bypass the proxy entirely via
`containerCanReachHostLoopback()` and are out of scope per #6014.

## Verification

- `npx vitest run test/ollama-auth-proxy-bind-probe.test.ts` — 38
passed, 2 platform skips on macOS
- Eight focused Ollama proxy suites — 110 passed, 2 platform skips
- `npm run typecheck:cli` — passed with the proxy script fully
type-checked
- `npm run checks:repository` — repository architecture and source-shape
checks passed
- `npm run docs` — 0 errors, 2 existing warnings
- `src/lib/shields/policy-transition.test.ts` carries the exact one-line
setup-hook stabilization from upstream PR #8572 (commit `78f681e72`)
after current-main CI reproduced the 10-second hook timeout three times
on this PR.


## Related

- Issue #6014 (architectural follow-up)
- PR #5996 (the symptom fix that opened #6014)
- Issue #5716 (the user-visible bug)

## 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)

## Documentation Writer Review
<!-- Required for code and documentation changes after the changes and
applicable validation are complete. Keep one review checkbox and one
instance of each visible or hidden field. For Evidence, list changed
documentation paths. For documentation-only changes, also state that the
writing rules and documentation style were reviewed. For other results,
explain why no documentation change is needed or why the review is
blocked. For Agent, use a consistent product and surface name, such as
Codex Desktop, Codex CLI, Claude Code, or Cursor. After committing all
review changes, put `git rev-parse --short HEAD` and `git rev-parse
--short HEAD:AGENTS.md` in the hidden metadata below. Rerun the review
and refresh that metadata after any new commit. This receipt is advisory
during the data-collection pilot. -->
- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `SECURITY.md`. Independent Codex Desktop review passed for
exact head `74431d39a`. The threat model accurately documents the Ollama
auth proxy loopback bind probe, its full `127.0.0.0/8`, `::1`, and
IPv4-mapped IPv6 loopback coverage, non-loopback refusal, operator
override, unavailable-probe fallback, startup-only enforcement,
regression coverage, and scope limits. Removing `@ts-nocheck` preserves
behavior, the broadened trigger aligns all recognized loopback backend
hostnames with that documented guarantee, and the Vitest setup-hook
timeout change requires no additional documentation.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 74431d3 -->
<!-- docs-review-agents-blob-sha: 12ad395 -->

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

* **New Features**
* Added structured proxy startup failure “status file” and clearer
readiness-loop diagnostics.
* Enhanced the Ollama auth proxy with Bearer-token authentication and
loopback-only backend enforcement.
* **Bug Fixes**
* Improved startup failure reporting by surfacing a specific
“backend-not-loopback” reason and remediation guidance when
misconfigured.
* Improved proxy forwarding error responses with consistent HTTP status
handling.
* **Tests**
* Added Vitest coverage for loopback bind/probe detection, address
classification (proc/net and lsof), and contract constant assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

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

---------

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Prekshi Vyas <34834085+prekshivyas@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant