Skip to content

fix(onboard): prune dangling extra providers before sandbox create - #6518

Closed
nvshaxie wants to merge 4 commits into
mainfrom
fix/6501-prune-dangling-extra-providers
Closed

fix(onboard): prune dangling extra providers before sandbox create#6518
nvshaxie wants to merge 4 commits into
mainfrom
fix/6501-prune-dangling-extra-providers

Conversation

@nvshaxie

@nvshaxie nvshaxie commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

nemoclaw onboard fails at sandbox create with provider 'tavily-search' not found whenever the host registry still records an extra provider that no longer exists on the (reused) gateway — even when the user explicitly declined web search. This PR reconciles the registry-recorded extra providers against the gateway before they are passed to sandbox create --provider.

Related Issue

Fixes #6501

Changes

  • Add reconcileRegisteredExtraProviders in src/lib/onboard/extra-provider-reconciliation.ts (re-exported through sandbox-provider-cleanup.ts so the onboard entrypoint import stays net-zero): when the recorded set is non-empty, probe each recorded name with a gateway-scoped openshell provider get -g <gateway> <name> (the same existence check upsertProvider relies on). A record is pruned — skipped, warned about (with a nemoclaw credentials add recreate hint), and removed from the registry — only when the gateway explicitly answers with a provider-not-found diagnostic. Any other failure (gateway down, timeout, unexpected error) keeps the record — fail-open — so a real outage still surfaces through the existing sandbox-create diagnostics and a healthy provider is never silently dropped.
  • Wire it into the onboard entrypoint at the single extraProviders: production call site (net-zero line change in src/lib/onboard.ts).
  • Cover the new behavior in test/extra-provider-reconciliation.test.ts: empty-set short-circuit (no gateway probe), gateway-scoped confirm passthrough, not-found prune+warn+forget in both CLI and gRPC diagnostic orderings (the [NemoClaw][onboard][All Platforms] nemoclaw onboard fails creating sandbox when web search is disabled — tries to configure nonexistent tavily-search provider #6501 scenario), non-not-found fail-open, and Buffer diagnostic handling.
  • Add test/onboard-extra-provider-prune.test.ts: a spawn-level createSandbox integration test where the gateway reports the recorded tavily-search as not found — asserts the create command omits --provider tavily-search, the probe is gateway-scoped, the stale record is removed from the real registry state, and the user-facing warning is emitted. (Kept as a focused file to respect the test/onboard.test.ts size budget.)

Root cause note: credentials add records the provider name host-side (addExtraProvider), but gateway-side deletion paths can leave that record dangling; every subsequent onboard then attaches the stale name and OpenShell rejects the create. Probing at consumption time recovers regardless of how the desync happened.

Design history: the first revision consulted provider list --names and treated any exit-0 output as an authoritative snapshot. That pruned legitimately configured providers when a stub or degraded gateway answered success with an empty list — cli-test-shards (5) caught exactly that against the always-OK openshell test fixture. The per-name probe with an explicit not-found requirement removes that failure mode.

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: recovery-path fix; no documented workflow or command surface changes, only a new self-healing warning during onboard.
  • 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: pending — maintainer review requested (cv, ericksoa).
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result: npx vitest run --project integration test/extra-provider-reconciliation.test.ts test/sandbox-provider-cleanup.test.ts test/onboard-extra-provider-prune.test.ts → 34 tests passed; npx vitest run --project integration test/onboard.test.ts → 66 tests passed; npm run typecheck:cli clean.
  • 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)

Signed-off-by: Shawn Xie shaxie@nvidia.com

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Extra provider records are now reconciled with the current OpenShell gateway during sandbox setup, so only available providers are used.
    • Automatically prunes stale/dangling extra-provider records before sandbox creation.
  • Bug Fixes

    • Improved detection of “provider not found” from gateway diagnostics, including cases where output arrives as buffered text.
    • Now prunes only when a clear “not found” signal is observed, while preserving records when gateway probes fail for other reasons.
  • Tests

    • Added coverage for extra-provider reconciliation and pruning behavior.

Onboarding fails with "provider 'tavily-search' not found" when the
host registry still records an extra provider that no longer exists on
the reused gateway, even though the user declined web search (#6501).
Reconcile the recorded set against the gateway's provider list at plan
time: names the gateway confirms are kept, provably dangling records
are skipped, warned about, and removed; if the list is unreadable the
recorded set passes through unchanged so a real gateway outage still
surfaces through the existing create diagnostics.

Fixes #6501

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Shawn Xie <shaxie@nvidia.com>
@nvshaxie
nvshaxie requested review from cv and ericksoa July 9, 2026 00:15
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Sandbox creation now reconciles recorded extra providers against the gateway before building the create plan. Stale provider records are pruned on provider-not-found diagnostics, and the helper is re-exported through cleanup plumbing. Tests cover the new reconciliation and onboarding path.

Changes

Provider reconciliation

Layer / File(s) Summary
Reconciliation helper
src/lib/onboard/extra-provider-reconciliation.ts, src/lib/onboard/sandbox-provider-cleanup.ts
Adds reconcileRegisteredExtraProviders, the provider-not-found matcher, default dependency adapters, and re-exports the helper and deps through cleanup plumbing.
Sandbox creation wiring
src/lib/onboard.ts
Switches sandbox create plan preparation to use reconciled extra providers from the gateway-aware helper.
Test coverage
test/extra-provider-reconciliation.test.ts, test/sandbox-provider-cleanup.test.ts, test/onboard-extra-provider-prune.test.ts
Adds unit coverage for reconciliation outcomes, widens the mock run result stdout type to accept buffers, and adds an onboarding-style prune test for stale tavily-search state.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: bug-fix, area: onboarding, area: sandbox

Suggested reviewers: laitingsheng, ericksoa

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change prevents stale tavily-search provider refs during sandbox creation and matches issue #6501's expected behavior.
Out of Scope Changes check ✅ Passed The refactor and tests stay focused on extra-provider reconciliation and sandbox-create behavior.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: pruning dangling extra providers before sandbox creation.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/6501-prune-dangling-extra-providers

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Informational

Merge posture: Informational / low confidence
Primary next action: Resolve or justify PRA-1: PR review advisor unavailable.
Open items: 0 required · 1 warning · 0 suggestions · 1 test follow-up
Top item: PR review advisor unavailable

Action checklist

  • PRA-1 Resolve or justify: PR review advisor unavailable
  • PRA-T1 Add or justify test follow-up: Runtime validation

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify correctness Re-run the PR Review Advisor or perform a manual review.
Review findings by urgency: 0 required fixes, 1 item to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

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

PRA-1 Resolve/justify — PR review advisor unavailable

  • Location: not file-specific
  • Category: correctness
  • Problem: The automated advisor could not complete: Could not parse JSON from PR review advisor output; see /home/runner/work/NemoClaw/NemoClaw/artifacts/pr-review-advisor-nemotron-ultra/pr-review-advisor-retry-raw-output.txt
  • Impact: Automated review evidence is incomplete, so human review must cover the changed code manually.
  • Recommended action: Re-run the PR Review Advisor or perform a manual review.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the workflow logs and raw advisor artifact for the execution failure.
  • Missing regression test: No regression test recommendation is available because the advisor did not complete.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the workflow logs and raw advisor artifact for the execution failure.
  • Evidence: Could not parse JSON from PR review advisor output; see /home/runner/work/NemoClaw/NemoClaw/artifacts/pr-review-advisor-nemotron-ultra/pr-review-advisor-retry-raw-output.txt

💡 In-scope improvements

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

  • None.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Add or identify targeted runtime/integration validation for the changed behavior; do not report external E2E job pass/fail here.. Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/onboard.ts, src/lib/onboard/extra-provider-reconciliation.ts, src/lib/onboard/sandbox-provider-cleanup.ts.

Workflow run details

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: cloud-onboard, brave-search
Optional E2E: messaging-providers, onboard-repair

Dispatch hint: cloud-onboard,brave-search

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • cloud-onboard: Required because the PR changes the full hosted onboarding sandbox-create path and the provider list passed into sandbox creation. This validates a real cloud onboarding flow still creates a working sandbox with hosted inference after the new provider reconciliation step.
  • brave-search: Required because the change specifically affects recorded extra provider reconciliation and pruning for web-search providers, including brave-search/tavily-style provider records. This validates a real assistant web-search provider opt-in path is not incorrectly pruned or omitted from sandbox creation.

Optional E2E

  • messaging-providers: Useful adjacent confidence because the touched sandbox-provider-cleanup module and extra-provider reconciliation both operate around OpenShell providers attached to sandboxes; messaging provider flows exercise additional real provider attach/detach behavior, but the PR is focused on recorded extra providers and web-search-style stale records.
  • onboard-repair: Optional adjacent coverage for recovery after drift in onboarding state and sandbox/provider state. The onboarding resume rule does not apply because this PR does not touch src/lib/onboard/machine or resume state transitions, but repair remains a useful follow-up if maintainers want extra confidence around drift handling.

New E2E recommendations

  • stale-extra-provider-reconciliation (medium): Existing live E2E coverage appears to validate normal provider opt-in paths, but not the exact drift scenario introduced here: the host registry records an extra provider that the OpenShell gateway no longer knows. A live test should seed or create an extra provider record, remove or simulate gateway-side provider deletion, run onboarding, and assert sandbox create omits the stale --provider while the local registry record is pruned.
    • Suggested test: Add a live E2E job or target for stale extra provider pruning during sandbox create.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: cloud-onboard,brave-search

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: cloud-onboard
Optional E2E targets: onboard-repair

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: medium

Required E2E targets

  • cloud-onboard: Changes alter the live onboarding sandbox-create path by reconciling registry-recorded extra providers against the OpenShell gateway before passing --provider arguments. The cloud-onboard live job is the smallest directly wired E2E job that runs the real onboard flow through OpenShell/Docker sandbox creation.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard

Optional E2E targets

  • onboard-repair: Adjacent persisted-session repair coverage: repair can recreate a missing recorded sandbox through the same sandbox-create/provider-attachment surface, but the PR does not primarily change resume state-machine repair policy.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair

Relevant changed files

  • src/lib/onboard.ts
  • src/lib/onboard/extra-provider-reconciliation.ts
  • src/lib/onboard/sandbox-provider-cleanup.ts

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: No advisor follow-up required beyond maintainer review.
Open items: 0 required · 0 warnings · 0 suggestions · 0 test follow-ups
Since last review: 0 prior items resolved · 0 still apply · 0 new items found

Workflow run details

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

@github-code-quality

github-code-quality Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

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

TypeScript / code-coverage/cli

The overall coverage in the fix/6501-prune-dangl... branch remains at 76%, unchanged from the main branch.

Show a code coverage summary of the most impacted files.
File main 94af5e2 fix/6501-prune-dangl... 392a473 +/-
src/lib/actions...e-validation.ts 90% 81% -9%
src/lib/actions...x/mcp-bridge.ts 44% 35% -9%
src/lib/actions...lution-probe.ts 94% 88% -6%
src/lib/messagi.../persistence.ts 95% 92% -3%
src/lib/credentials/store.ts 61% 59% -2%
src/lib/actions...ridge-policy.ts 64% 62% -2%
src/lib/security/redact.ts 95% 97% +2%
src/lib/actions...-add-restart.ts 14% 19% +5%
src/lib/runner.ts 73% 80% +7%
src/lib/onboard...conciliation.ts 0% 62% +62%

Updated July 09, 2026 05:36 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

nvshaxie and others added 3 commits July 9, 2026 05:02
The initial reconcile queried 'provider list --names' and treated any
exit-0 response as an authoritative snapshot, which pruned legitimately
configured providers whenever a stub or degraded gateway answered
success with an empty list — cli-test-shards (5) caught exactly that
against the always-OK openshell test fixture. Probe each recorded name
with 'provider get -g <gateway> <name>' instead (the same existence
check upsertProvider relies on), prune only on an explicit
provider-not-found diagnostic, and fail open on any other failure so a
gateway outage can never silently drop a healthy provider.

Also adds a spawn-level onboard integration test covering the prune
path end-to-end: a dangling tavily-search record is skipped, warned
about, and removed while sandbox create proceeds without the flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Shawn Xie <shaxie@nvidia.com>
… module

PR Review Advisor flagged sandbox-provider-cleanup.ts monolith growth
(PRA-2, required): reconciliation is a fourth responsibility next to
detach, pre-delete cleanup, and delete recovery. Move
reconcileRegisteredExtraProviders to
src/lib/onboard/extra-provider-reconciliation.ts with a re-export from
the cleanup module so the onboard entrypoint import stays net-zero;
the cleanup module shrinks below its pre-PR line count.

Also folds in the advisor's hardening asks: SOURCE_OF_TRUTH_REVIEW
block documenting the drift's origin and removal condition (PRA-6),
a debug note when the fail-open path keeps a record after a
non-not-found probe failure (PRA-4), and a forget() guard so a
registry write failure cannot abort onboarding (PRA-5). Unit tests
move to test/extra-provider-reconciliation.test.ts alongside the
module.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Shawn Xie <shaxie@nvidia.com>
@nvshaxie

nvshaxie commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Pushed two follow-up commits addressing the shard-5 CI failure and the PR Review Advisor findings.

CI failure (cli-test-shards (5)), root cause and fix — ff4a96e23. The first revision consulted provider list --names and treated any exit-0 response as an authoritative snapshot of the gateway. The always-OK writeOkOpenshell fixture answers every command with exit 0 and empty stdout, so the reconcile read "empty gateway" and pruned the tavily-search record that test/onboard.test.ts legitimately configured — exactly the plausible-but-wrong behavior a degraded real gateway could trigger. The reconcile now probes each recorded name with a gateway-scoped provider get -g <gateway> <name> (the same existence check upsertProvider relies on) and prunes only on an explicit provider-not-found diagnostic (both provider 'X' not found and NotFound: provider "X" orderings); every other failure fails open. The previously failing test passes unchanged. The CodeQL check failures on the prior run were the repo-wide upload-sarif 4.36.2/4.37.0 mismatch (fixed on main via #6526); this branch has main merged in, so they should clear on the current run.

Advisor findings — 392a473df:

  • PRA-2 (required, monolith growth): reconcileRegisteredExtraProviders moved to a new src/lib/onboard/extra-provider-reconciliation.ts with unit tests in test/extra-provider-reconciliation.test.ts; sandbox-provider-cleanup.ts re-exports it (keeps src/lib/onboard.ts net-zero) and now sits below its pre-PR line count.
  • PRA-1 / PRA-6 / PRA-T6 (source-of-truth review): added a SOURCE_OF_TRUTH_REVIEW block on the helper — invalid state (registry records a provider the gateway no longer knows), origin (gateway-side provider delete / rebuilt gateway, with no provider-deletion signal OpenShell exposes for the CLI to observe), regression proof (test/extra-provider-reconciliation.test.ts, test/onboard-extra-provider-prune.test.ts), and removal condition (OpenShell exposing a structured provider-deletion event).
  • PRA-T1–T4 (runtime validation): test/onboard-extra-provider-prune.test.ts exercises the production createSandbox path end-to-end: a dangling tavily-search record is probed gateway-scoped, skipped, warned about, and removed from real registry state while sandbox create proceeds without the flag.
  • PRA-4 (fail-open observability): the fail-open branch now emits a console.debug note naming the kept provider, matching the console.debug diagnosability pattern used in onboard/not-ready-recreate.ts.
  • PRA-5 (forget() mid-iteration throw): forget() is now guarded; a registry write failure keeps the record skipped for the current run without aborting onboarding, and the next run re-prunes.
  • PRA-3, PRA-7, PRA-T5 (gateway list validation / CRLF parsing): moot after the rework — no gateway list output is parsed anymore. Probe targets come exclusively from the host registry, whose write path already enforces EXTRA_PROVIDER_NAME_PATTERN (src/lib/state/extra-providers.ts), and the per-name probe result is only ever interpreted as exit status + not-found match.

Verification: npx vitest run --project integration test/extra-provider-reconciliation.test.ts test/sandbox-provider-cleanup.test.ts test/onboard-extra-provider-prune.test.ts → 34 passed; full test/onboard.test.ts → 65 passed; cli project → 2423 passed; npm run typecheck:cli clean. All commits Verified, src/lib/onboard.ts stays at +2/−2.

@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/onboard/sandbox-provider-cleanup.ts (1)

401-417: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Diagnostics are console-only; consider surfacing as a state result.

warn defaults to console.warn, so the pruning outcome is only observable via stdout/stderr. Per src/lib/onboard/machine/README.md, the target architecture "Prefer[s] explicit state results returned by handlers and applied by OnboardRuntime ... rather than relying on console output as the only observable diagnostic." If this helper is invoked from within onboarding state-handler code (rather than purely ad-hoc CLI plumbing), consider returning pruned/kept provider names as part of a state result so OnboardRuntime can persist/redact them, instead of console output being the sole record.

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

In `@src/lib/onboard/sandbox-provider-cleanup.ts` around lines 401 - 417, The
provider cleanup in the sandbox helper is currently only observable through
warn/console output, which does not match the explicit-state-result pattern used
by onboarding handlers. Update the logic around the runOpenshell check, warn,
and forgetExtraProvider flow so the pruning decision is returned as structured
state (for example, pruned vs kept provider names) that OnboardRuntime can
consume and persist/redact, instead of relying on console.warn as the only
diagnostic channel.

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 `@src/lib/onboard/sandbox-provider-cleanup.ts`:
- Around line 401-417: The provider cleanup in the sandbox helper is currently
only observable through warn/console output, which does not match the
explicit-state-result pattern used by onboarding handlers. Update the logic
around the runOpenshell check, warn, and forgetExtraProvider flow so the pruning
decision is returned as structured state (for example, pruned vs kept provider
names) that OnboardRuntime can consume and persist/redact, instead of relying on
console.warn as the only diagnostic channel.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f616200d-844b-47dd-90a6-86b5ff277a67

📥 Commits

Reviewing files that changed from the base of the PR and between 3f45f5a and ff4a96e.

📒 Files selected for processing (4)
  • src/lib/onboard.ts
  • src/lib/onboard/sandbox-provider-cleanup.ts
  • test/onboard-extra-provider-prune.test.ts
  • test/sandbox-provider-cleanup.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/lib/onboard/extra-provider-reconciliation.ts (1)

115-120: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Silent swallow on forget() failure — consider a debug note.

Other fail-open branches in this file log via console.debug for diagnosability (lines 106-109), but a registry write failure here is swallowed with only a code comment. Not blocking, but adding a similar debug line would keep the diagnosability story consistent.

♻️ Optional
     try {
       forget(name);
-    } catch {
+    } catch (err) {
       // A registry write failure must not abort onboarding — the dangling
       // record is still skipped for this run and re-pruned on the next one.
+      console.debug(
+        `reconcileRegisteredExtraProviders: failed to forget stale provider '${name}': ${err}`,
+      );
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard/extra-provider-reconciliation.ts` around lines 115 - 120, Add
a non-blocking debug log in the `forget(name)` failure branch inside
`extra-provider-reconciliation` so this fail-open path is diagnosable like the
nearby `console.debug` handling; update the `try/catch` around `forget(name)` to
capture the thrown error and emit a concise `console.debug` message with the
provider name and error details, while keeping onboarding uninterrupted.
test/extra-provider-reconciliation.test.ts (1)

24-132: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Missing test for the forget()-throws hardening.

The commit description calls out a new guard so that a registry write failure inside forget() doesn't abort onboarding (production lines 115-120), but no test here exercises that path. Given this was explicitly added as hardening for a real failure mode, a regression test would lock in the guarantee.

✅ Suggested addition
it("keeps onboarding running when forgetting a stale provider throws (registry write failure)", () => {
  const responses = new Map<string, RunResult>([
    ["provider get tavily-search", { status: 1, stderr: "provider 'tavily-search' not found\n" }],
  ]);
  const { runOpenshell } = buildRunOpenshell(responses);
  const forget = vi.fn(() => {
    throw new Error("disk full");
  });
  const warn = vi.fn();

  const result = reconcileRegisteredExtraProviders({
    runOpenshell,
    listExtraProviders: () => ["tavily-search"],
    forgetExtraProvider: forget,
    warn,
  });

  expect(result).toEqual([]);
  expect(forget).toHaveBeenCalledWith("tavily-search");
});

Want me to open this as a follow-up or add it directly?

🤖 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/extra-provider-reconciliation.test.ts` around lines 24 - 132, The
reconciliation test suite for reconcileRegisteredExtraProviders is missing
coverage for the new forget()-throws hardening path. Add a test that stubs
forgetExtraProvider to throw during stale-provider cleanup, then verify
reconcileRegisteredExtraProviders still returns the pruned result and does not
abort onboarding; use the existing buildRunOpenshell, listExtraProviders, warn,
and forget setup patterns to exercise the failure mode.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard/extra-provider-reconciliation.ts`:
- Around line 20-27: The provider-not-found detection in PROVIDER_NOT_FOUND_RE
is still too broad because the second branch can match gateway-related
diagnostics; tighten the regex in extra-provider-reconciliation so it only
matches when the “provider” subject is the thing reported as not found, or add
an explicit guard to exclude gateway/sandbox diagnostics. Update the matching
logic around PROVIDER_NOT_FOUND_RE and verify the reconciliation flow that uses
it only prunes providers for true provider-not-found errors.

---

Nitpick comments:
In `@src/lib/onboard/extra-provider-reconciliation.ts`:
- Around line 115-120: Add a non-blocking debug log in the `forget(name)`
failure branch inside `extra-provider-reconciliation` so this fail-open path is
diagnosable like the nearby `console.debug` handling; update the `try/catch`
around `forget(name)` to capture the thrown error and emit a concise
`console.debug` message with the provider name and error details, while keeping
onboarding uninterrupted.

In `@test/extra-provider-reconciliation.test.ts`:
- Around line 24-132: The reconciliation test suite for
reconcileRegisteredExtraProviders is missing coverage for the new
forget()-throws hardening path. Add a test that stubs forgetExtraProvider to
throw during stale-provider cleanup, then verify
reconcileRegisteredExtraProviders still returns the pruned result and does not
abort onboarding; use the existing buildRunOpenshell, listExtraProviders, warn,
and forget setup patterns to exercise the failure mode.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cccbb1c7-944b-4333-bd2f-b83f9cf03cb7

📥 Commits

Reviewing files that changed from the base of the PR and between ff4a96e and 392a473.

📒 Files selected for processing (4)
  • src/lib/onboard/extra-provider-reconciliation.ts
  • src/lib/onboard/sandbox-provider-cleanup.ts
  • test/extra-provider-reconciliation.test.ts
  • test/sandbox-provider-cleanup.test.ts
💤 Files with no reviewable changes (1)
  • test/sandbox-provider-cleanup.test.ts

Comment on lines +20 to +27
/**
* Diagnostic shapes for "the probed provider does not exist": both the CLI's
* `provider 'X' not found` and the gRPC-style `NotFound: provider "X"`
* orderings. Anchored to the word "provider" on the same line so missing-
* sandbox or missing-gateway errors never count as a provider-not-found.
*/
const PROVIDER_NOT_FOUND_RE =
/provider[^\n]{0,200}?(?:\bNotFound\b|\bnot\s+found\b)|(?:\bNotFound\b|\bnot\s+found\b)(?::|\s)[^\n]{0,200}?\bprovider\b/i;

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file and nearby tests/usages first.
git ls-files 'src/lib/onboard/extra-provider-reconciliation.ts' \
  'src/lib/onboard/**' \
  'src/**/__tests__/**' \
  'src/**/test/**' \
  'test/**' | sed -n '1,200p'

echo
echo "== outline =="
ast-grep outline src/lib/onboard/extra-provider-reconciliation.ts --view expanded || true

echo
echo "== search for regex/tests/usages =="
rg -n "PROVIDER_NOT_FOUND_RE|provider not found|NotFound: provider|not found.*provider|gateway|sandbox" src/lib/onboard src test -S || true

echo
echo "== file excerpt =="
wc -l src/lib/onboard/extra-provider-reconciliation.ts
sed -n '1,220p' src/lib/onboard/extra-provider-reconciliation.ts

Repository: NVIDIA/NemoClaw

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== extra-provider-reconciliation.ts =="
sed -n '1,220p' src/lib/onboard/extra-provider-reconciliation.ts

echo
echo "== nearby tests/usages =="
rg -n "PROVIDER_NOT_FOUND_RE|reconcileRegisteredExtraProviders|forget\\(|provider-not-found|provider not found|NotFound: provider|not found.*provider" \
  src/lib/onboard src/lib -g '!**/dist/**' -g '!**/build/**' -S

echo
echo "== regex behavior probe =="
python3 - <<'PY'
import re

pattern = re.compile(r'provider[^\n]{0,200}?(?:\bNotFound\b|\bnot\s+found\b)|(?:\bNotFound\b|\bnot\s+found\b)(?::|\s)[^\n]{0,200}?\bprovider\b', re.I)

samples = [
    'provider "alpha" not found',
    'NotFound: provider "alpha"',
    'gateway "nemoclaw" not found while listing provider records',
    'sandbox "foo" not found; provider "alpha" is cached',
    'missing-gateway: provider "alpha" not found',
    'NotFound: gateway "nemoclaw" not found while listing provider records',
    'provider "alpha" NotFound',
]

for s in samples:
    print(f"{pattern.search(s) is not None!s:5}  {s}")
PY

Repository: NVIDIA/NemoClaw

Length of output: 9941


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== extra-provider reconciliation tests =="
fd -a 'extra-provider-reconciliation.test.ts|onboard-extra-provider-prune.test.ts|rebuild-provider-preflight.test.ts' test src || true

echo
echo "== extra-provider-reconciliation.test.ts =="
sed -n '1,240p' test/extra-provider-reconciliation.test.ts

echo
echo "== onboard-extra-provider-prune.test.ts =="
sed -n '1,260p' test/onboard-extra-provider-prune.test.ts

echo
echo "== gateway / outage related samples in tests =="
rg -n "gateway.*not found|not found.*gateway|provider not found|provider-not-found|fail-open|keep.*provider|skip.*provider|reconcileRegisteredExtraProviders" \
  test src/lib -S

Repository: NVIDIA/NemoClaw

Length of output: 27725


Tighten the provider-not-found match The second branch still matches diagnostics like NotFound: gateway ... not found while listing provider records, so a gateway outage can prune a healthy provider record. Narrow it to the provider subject itself or add a gateway-down regression case.

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

In `@src/lib/onboard/extra-provider-reconciliation.ts` around lines 20 - 27, The
provider-not-found detection in PROVIDER_NOT_FOUND_RE is still too broad because
the second branch can match gateway-related diagnostics; tighten the regex in
extra-provider-reconciliation so it only matches when the “provider” subject is
the thing reported as not found, or add an explicit guard to exclude
gateway/sandbox diagnostics. Update the matching logic around
PROVIDER_NOT_FOUND_RE and verify the reconciliation flow that uses it only
prunes providers for true provider-not-found errors.

cv pushed a commit that referenced this pull request Jul 9, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Reconcile registry-recorded extra providers against the authoritative
OpenShell gateway list before sandbox creation. This prevents a stale
`tavily-search` record from breaking onboarding while preserving every
healthy gateway-wide user provider. The PR replaces #6531, preserves Ho
Lim's original issue work, and credits Shawn Xie's
provider-reconciliation direction from #6518.

## Related Issue

Fixes #6501.

## Changes

- Query `provider list -g <gateway> --names` once when registry extras
exist.
- Attach only exact provider names returned by a successful
authoritative list.
- Preserve all recorded providers if the gateway query fails or throws,
avoiding silent user-state loss during an outage.
- Keep local registry state unchanged; reconciliation affects only the
current sandbox-create plan.
- Preserve healthy bare `brave-search`, `tavily-search`, custom, and
bridge providers without treating their names as NemoClaw-owned.
- Add focused and spawn-level regressions for healthy providers, stale
records, exact-name matching, gateway scoping, and fail-open behavior.

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

- [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 silently restores the
documented provider source-of-truth contract without adding or changing
a command, option, output, configuration, or remediation step.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — exact-name gateway reconciliation was independently audited;
it avoids diagnostic regexes, preserves healthy user-owned providers,
fails open on gateway-list failure, and does not mutate registry state.
- [ ] 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] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior — 17 focused
reconciliation tests and all 65 onboard integration tests passed.
- [ ] Full `npm test` passes (broad runtime changes only)
- [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)

Additional exact-head validation: CLI type-check, file/commit/push
hooks, commitlint, test-size/source-shape budgets, secret scan, and `npm
run check:diff` passed. Documentation review found no update required.
`src/lib/onboard.ts` is net-neutral.

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


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

## Summary by CodeRabbit

* **New Features**
* Sandbox creation now better matches configured providers to what’s
actually available, reducing unexpected provider options during
onboarding.

* **Bug Fixes**
* Fixed cases where stale or unavailable extra providers could still
appear in sandbox setup.
* Improved behavior when provider lookup fails, helping preserve
previously configured choices instead of removing them unexpectedly.

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

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Ho Lim <subhoya@gmail.com>
Co-authored-by: Shawn Xie <shaxie@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Superseded by #6596. The replacement carries forward Shawn Xie’s per-provider probe design and credits @nvshaxie as co-author, while preserving the non-destructive registry behavior from merged #6587. It also closes the remaining gaps found during comparison: byte-exact provider identity, whole-diagnostic fail-open handling, provider counts beyond 100, bounded aggregate latency, and gateway/transport/authentication regressions. Thank you, Shawn, for the core reconciliation design and tests preserved in the replacement.

cv added a commit that referenced this pull request Jul 10, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Fixes the post-merge #6587 gap where one paginated provider-list page
could omit healthy registry extras beyond entry 100. Reconciliation now
uses bounded, gateway-scoped per-provider probes, recognizes the exact
wrapped OpenShell #6501 diagnostic, and preserves every indeterminate
result.

## Related Issue
Follow-up to #6501 and #6587. Supersedes #6518.

## Changes
- Probe every recorded extra with argv-safe `provider get -g <gateway>
<name>` instead of treating one list page as authoritative.
- Omit only exit-1 diagnostics that bind the exact, case-sensitive
quoted provider name to a tightly anchored not-found shape, including
the wrapped not-found-and-unrecognized form reported in #6501.
- Fail open on gateway, transport, authentication, timeout, signal,
ambiguous, name-mismatched, or command-spoofed output.
- Read canonical stderr/stdout without duplicating Node's composite
`output` array, and treat process errors or capture-limit diagnostics as
indeterminate.
- Bound each probe to 5 seconds and 64 KiB, cap total reconciliation
time at 15 seconds, and never mutate the local registry.
- Cover stale providers after index 100, the literal wrapped issue
diagnostic in a realistic `spawnSync` result, capture truncation,
mixed-case names, multi-line diagnostic spoofing, gateway failures,
aggregate timeout, and stable repeated sandbox-create provider
arguments.

The create-time filter is intentionally non-destructive. A provider
omitted from one sandbox create remains in the user-owned registry for a
later retry; `--fresh` does not purge it. Indeterminate probes preserve
the attachment, and the final `sandbox create` remains authoritative and
reports any concrete attachment failure. This avoids deleting healthy
user configuration because of a transient gateway or transport failure.

## 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: internal provider-state
reconciliation only; no CLI, prompt, configuration, policy, or required
user action changes.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: independent
nine-category security review passed after exact-name, whole-diagnostic,
subprocess-bound, and fail-open checks.
- [ ] 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: CLI
unit 14/14 and spawn integration 1/1 passed; the spawn test uses a
realistic composite process result, executes two create attempts, and
proves identical filtered provider arguments.
- [ ] 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 to this
focused reconciliation change; `npm run typecheck:cli`, `npm run
check:diff`, source-shape, test-size, and test-conditional scans 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)
- [ ] 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)

Exact-head live validation for `onboard-repair`, `onboard-resume`, and
`cloud-onboard` passed at [workflow run
29048610487](https://github.com/NVIDIA/NemoClaw/actions/runs/29048610487)
for head `a0ea6e60f98c6e15a6084dba7a5ba9ff1e89215a`.

---
<!-- 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**
* Onboarding and repair now detect and remove stale extra-provider
records.
* Resume operations can explicitly recreate an existing sandbox while
preserving its registry entry.
* Sandbox creation and retries now use a consistent, deduplicated
provider list.

* **Bug Fixes**
* Providers are retained when availability checks are inconclusive,
preventing accidental removal.
* Reconciliation now avoids relying on potentially stale provider-list
snapshots and handles diagnostic variations more reliably.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Shawn Xie <shaxie@nvidia.com>
Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Reconcile registry-recorded extra providers against the authoritative
OpenShell gateway list before sandbox creation. This prevents a stale
`tavily-search` record from breaking onboarding while preserving every
healthy gateway-wide user provider. The PR replaces NVIDIA#6531, preserves Ho
Lim's original issue work, and credits Shawn Xie's
provider-reconciliation direction from NVIDIA#6518.

## Related Issue

Fixes NVIDIA#6501.

## Changes

- Query `provider list -g <gateway> --names` once when registry extras
exist.
- Attach only exact provider names returned by a successful
authoritative list.
- Preserve all recorded providers if the gateway query fails or throws,
avoiding silent user-state loss during an outage.
- Keep local registry state unchanged; reconciliation affects only the
current sandbox-create plan.
- Preserve healthy bare `brave-search`, `tavily-search`, custom, and
bridge providers without treating their names as NemoClaw-owned.
- Add focused and spawn-level regressions for healthy providers, stale
records, exact-name matching, gateway scoping, and fail-open behavior.

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

- [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 silently restores the
documented provider source-of-truth contract without adding or changing
a command, option, output, configuration, or remediation step.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — exact-name gateway reconciliation was independently audited;
it avoids diagnostic regexes, preserves healthy user-owned providers,
fails open on gateway-list failure, and does not mutate registry state.
- [ ] 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] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior — 17 focused
reconciliation tests and all 65 onboard integration tests passed.
- [ ] Full `npm test` passes (broad runtime changes only)
- [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)

Additional exact-head validation: CLI type-check, file/commit/push
hooks, commitlint, test-size/source-shape budgets, secret scan, and `npm
run check:diff` passed. Documentation review found no update required.
`src/lib/onboard.ts` is net-neutral.

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


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

## Summary by CodeRabbit

* **New Features**
* Sandbox creation now better matches configured providers to what’s
actually available, reducing unexpected provider options during
onboarding.

* **Bug Fixes**
* Fixed cases where stale or unavailable extra providers could still
appear in sandbox setup.
* Improved behavior when provider lookup fails, helping preserve
previously configured choices instead of removing them unexpectedly.

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

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Ho Lim <subhoya@gmail.com>
Co-authored-by: Shawn Xie <shaxie@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Fixes the post-merge NVIDIA#6587 gap where one paginated provider-list page
could omit healthy registry extras beyond entry 100. Reconciliation now
uses bounded, gateway-scoped per-provider probes, recognizes the exact
wrapped OpenShell NVIDIA#6501 diagnostic, and preserves every indeterminate
result.

## Related Issue
Follow-up to NVIDIA#6501 and NVIDIA#6587. Supersedes NVIDIA#6518.

## Changes
- Probe every recorded extra with argv-safe `provider get -g <gateway>
<name>` instead of treating one list page as authoritative.
- Omit only exit-1 diagnostics that bind the exact, case-sensitive
quoted provider name to a tightly anchored not-found shape, including
the wrapped not-found-and-unrecognized form reported in NVIDIA#6501.
- Fail open on gateway, transport, authentication, timeout, signal,
ambiguous, name-mismatched, or command-spoofed output.
- Read canonical stderr/stdout without duplicating Node's composite
`output` array, and treat process errors or capture-limit diagnostics as
indeterminate.
- Bound each probe to 5 seconds and 64 KiB, cap total reconciliation
time at 15 seconds, and never mutate the local registry.
- Cover stale providers after index 100, the literal wrapped issue
diagnostic in a realistic `spawnSync` result, capture truncation,
mixed-case names, multi-line diagnostic spoofing, gateway failures,
aggregate timeout, and stable repeated sandbox-create provider
arguments.

The create-time filter is intentionally non-destructive. A provider
omitted from one sandbox create remains in the user-owned registry for a
later retry; `--fresh` does not purge it. Indeterminate probes preserve
the attachment, and the final `sandbox create` remains authoritative and
reports any concrete attachment failure. This avoids deleting healthy
user configuration because of a transient gateway or transport failure.

## 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: internal provider-state
reconciliation only; no CLI, prompt, configuration, policy, or required
user action changes.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: independent
nine-category security review passed after exact-name, whole-diagnostic,
subprocess-bound, and fail-open checks.
- [ ] 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: CLI
unit 14/14 and spawn integration 1/1 passed; the spawn test uses a
realistic composite process result, executes two create attempts, and
proves identical filtered provider arguments.
- [ ] 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 to this
focused reconciliation change; `npm run typecheck:cli`, `npm run
check:diff`, source-shape, test-size, and test-conditional scans 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)
- [ ] 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)

Exact-head live validation for `onboard-repair`, `onboard-resume`, and
`cloud-onboard` passed at [workflow run
29048610487](https://github.com/NVIDIA/NemoClaw/actions/runs/29048610487)
for head `a0ea6e60f98c6e15a6084dba7a5ba9ff1e89215a`.

---
<!-- 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**
* Onboarding and repair now detect and remove stale extra-provider
records.
* Resume operations can explicitly recreate an existing sandbox while
preserving its registry entry.
* Sandbox creation and retries now use a consistent, deduplicated
provider list.

* **Bug Fixes**
* Providers are retained when availability checks are inconclusive,
preventing accidental removal.
* Reconciliation now avoids relying on potentially stale provider-list
snapshots and handles diagnostic variations more reliably.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Shawn Xie <shaxie@nvidia.com>
Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
@wscurran wscurran added area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression

Projects

None yet

3 participants