Skip to content

fix(onboard): gate the legacy gateway destroy verb on installed OpenShell support - #8270

Closed
AzeelSajjad wants to merge 8 commits into
NVIDIA:mainfrom
AzeelSajjad:fix/gateway-removal-hint-capability-gate
Closed

fix(onboard): gate the legacy gateway destroy verb on installed OpenShell support#8270
AzeelSajjad wants to merge 8 commits into
NVIDIA:mainfrom
AzeelSajjad:fix/gateway-removal-hint-capability-gate

Conversation

@AzeelSajjad

@AzeelSajjad AzeelSajjad commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Three onboard failure hints printed openshell gateway destroy -g <name>, a subcommand current OpenShell rejects with error: unrecognized subcommand 'destroy'. Each printed it unconditionally behind a prose caveat an operator reading a failure hint has no way to evaluate. All three now render their command block through a shared helper gated on gatewayCliSupportsLifecycleCommands, the probe the gateway execution paths already consumed, so the printed commands match the installed OpenShell.

Related Issue

Fixes #8139

Changes

  • Add src/lib/onboard/gateway-removal-hint.ts exporting gatewayRemovalHintLines(gatewayName, supportsLifecycleCommands). This is consolidation, not a new layer: it has three named current consumers, listed in its docblock, that previously duplicated the same three-line block. src/lib/onboard/gateway-removal-hint.test.ts protects the contract in both directions.
  • Gate the legacy verb in src/lib/onboard/gateway-start-failure.ts (gateway fails to start after all retries), src/lib/onboard/gpu-recovery.ts (GPU passthrough mismatch, no sandboxes registered), and src/lib/onboard/gateway-gpu-passthrough.ts (GPU passthrough mismatch, registry unreadable).
  • Thread supportsLifecycleCommands from the probe. src/lib/onboard/machine/handlers/gateway.ts already computed it for its own use and now forwards it to the reconcile call; src/lib/onboard.ts wires it into the start-failure handler. No new probe call is introduced.
  • The flag defaults to false at every layer, so a caller that has not run the probe prints only the verb current OpenShell accepts. The field on GatewayGpuReuseReconcileOptions is optional for the same reason: the other four construction sites keep compiling and passing untouched.
  • Retarget three pre-existing assertions that asserted the invalid verb was printed. Each retarget is paired with new coverage exercising both the gated and ungated directions, so no test is weakened into a bare negation.
  • Bump src/lib/onboard in ci/source-architecture-budget.json from 310 to 311 for the one new production file.

Known remaining, out of scope: scripts/install.sh:2428 prints openshell gateway remove X || openshell gateway destroy -g X. The || makes it self-correcting, so it cannot produce the unrecognized subcommand failure this PR fixes.

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: A documentation writer subagent searched docs/ and found no page quotes these hint strings. This change alters which commands NemoClaw prints, never which it runs, so the gateway-teardown prose in docs/deployment/gateway-lifecycle-authority.mdx and docs/reference/commands.mdx remains accurate.
  • 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: Requesting maintainer review of the onboarding-path change. No waiver is recorded and none is claimed.
  • 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: Searched docs/ for gateway destroy, gateway remove, lifecycle command, and unrecognized subcommand. No page quotes the onboard-hint strings from the changed files. Checked and confirmed still accurate: docs/reference/troubleshooting.mdx GPU-passthrough section (refers generically to "the commands printed by onboarding" without naming verbs); docs/reference/commands.mdx and docs/deployment/gateway-lifecycle-authority.mdx:190 (both describe execution behavior on separate, already-gated paths, not hint strings); two unrelated openshell gateway remove snippets in docs/reference/troubleshooting.mdx TLS/CoreDNS recovery that never carried the legacy verb. Review was rerun at head f853cb030 after the growth-guardrail commit; that commit only reformats one line in src/lib/onboard.ts with no behavior, string, or interface change.
  • Agent: Claude Code

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: npx vitest run --project cli src/lib/onboard/gateway-removal-hint.test.ts src/lib/onboard/gpu-recovery.test.ts src/lib/onboard/gateway-start-failure.test.ts src/lib/onboard/gateway-gpu-passthrough.test.ts src/lib/onboard/machine/handlers/gateway.test.ts → 63/63 passing. npx vitest run --project integration test/gateway-final-failure-cleanup.test.ts → 3/3 passing. Both rerun after rebasing onto current origin/main. npm run source-shape:check → exit 0, source_shape_cases=0.
  • 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: Azeel Sajjad aasajjad05@gmail.com

Summary by CodeRabbit

  • Bug Fixes

    • Updated gateway recovery and failure messages to recommend the modern gateway remove command.
    • Legacy gateway destroy guidance now appears only when supported by the installed CLI.
    • Improved GPU passthrough recovery and cleanup instructions across supported scenarios.
  • Tests

    • Added regression coverage for modern and legacy gateway command handling, including unreadable registry and startup failure cases.

AzeelSajjad and others added 7 commits August 4, 2026 18:36
…8139)

Pass an explicit supportsLifecycleCommands: () => false override in the
pre-existing production-wired test so it no longer falls through to the real
openshell binary probe, which can process.exit(1) the vitest worker when no
openshell binary is resolvable. Add a deps-level test in
gateway-start-failure.test.ts that constructs the handler with
supportsLifecycleCommands in deps and no per-call override, covering the
deps ?? (() => false) fallthrough that was previously only reached
incidentally.
…A#8139)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lag forward (NVIDIA#8139)

Add the missing supportsLifecycleCommands override to the second
handleFinalGatewayStartFailure test in
test/gateway-final-failure-cleanup.test.ts: without it, the call falls
through to the live gatewayCliSupportsLifecycleCommands probe, which
calls process.exit(1) inside the vitest worker on a runner without an
openshell binary (killing the rest of that worker's tests).

Add a test asserting handleGatewayState forwards
gatewayCliSupportsLifecycleCommands()'s result unchanged to
reconcileGatewayGpuReuseForGpuIntent, guarding against a wrong
(inverted or hardcoded) value compiling clean.

Document why the abort-with-recovery supportsLifecycleCommands
argument in gateway-gpu-passthrough.ts is dead but intentionally kept
for uniformity with its sibling call.
@copy-pr-bot

copy-pr-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Gateway cleanup hints now use openshell gateway remove. They include gateway destroy only when lifecycle-command support is detected. The capability flows through GPU recovery, gateway reconciliation, and gateway start-failure handling.

Changes

Gateway lifecycle hint handling

Layer / File(s) Summary
Shared removal hint generation
src/lib/onboard/gateway-removal-hint.ts, src/lib/onboard/gateway-removal-hint.test.ts, ci/source-architecture-budget.json
Added shared lifecycle-aware hint generation and coverage for supported, unsupported, and unknown capability states.
Recovery and failure propagation
src/lib/onboard/gpu-recovery.ts, src/lib/onboard/gateway-gpu-passthrough.ts, src/lib/onboard/gateway-start-failure.ts, src/lib/onboard/machine/handlers/gateway.ts, src/lib/onboard.ts
Propagated lifecycle-command support through GPU recovery, gateway reconciliation, and final gateway start-failure handling.
Capability-specific regression coverage
src/lib/onboard/gpu-recovery.test.ts, src/lib/onboard/gateway-gpu-passthrough.test.ts, src/lib/onboard/gateway-start-failure.test.ts, src/lib/onboard/machine/handlers/gateway.test.ts, test/gateway-final-failure-cleanup.test.ts
Added assertions for modern removal hints and conditional legacy destroy hints across recovery and cleanup flows.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLIProbe
  participant GatewayHandler
  participant Recovery
  participant HintHelper
  CLIProbe->>GatewayHandler: detect lifecycle-command support
  GatewayHandler->>Recovery: pass supportsLifecycleCommands
  Recovery->>HintHelper: request gateway removal hints
  HintHelper-->>Recovery: return gateway remove and optional gateway destroy commands
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#8188: Extends related gateway-destroy hint changes with lifecycle capability detection.

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

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% 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 changes address issue #8139 by using gateway remove by default and gating gateway destroy on detected CLI support.
Out of Scope Changes check ✅ Passed The changes remain within scope, including capability propagation, recovery hints, tests, and the required architecture budget update.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: conditionally enabling the legacy gateway destroy command based on installed OpenShell support.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

github-actions Bot commented Aug 4, 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 · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections differ; severity counts match.
3 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • legacy verb at src/lib/onboard/gateway-removal-hint.ts:11: selected only by the second-opinion lane as established.
  • destroy-verb at src/lib/onboard/gateway-gpu-passthrough.test.ts:171: selected only by the second-opinion lane as established.
  • removal hint at src/lib/onboard/gateway-gpu-passthrough.ts:10: selected only by the second-opinion lane as justified.
4 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • full-e2e: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • double-onboard: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • gpu-double-onboard: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • openshell-gateway-upgrade: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

2 semantic terminology decisions

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

  • established — lifecycle commands at src/lib/onboard/gateway-removal-hint.ts:27: Keep the established term. The surrounding output states the capability condition.
  • established — legacy gateway at src/lib/onboard/gateway-gpu-passthrough.test.ts:171: Keep the established term. The changed test names the contrasted command behavior.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-onboard, onboard-repair, onboard-resume

Workflow run details

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

@senthilr-nv senthilr-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed exact head f853cb0.

Security review: PASS with no findings across secrets, input handling, authorization, dependencies, logging, cryptography, configuration, security testing, and lifecycle safety.

I cannot approve the architecture as written. Current main still limits src/lib/onboard to 310 root files and pins the supported OpenShell range to exactly 0.0.85, where gateway destroy is not a valid command. This PR raises the transitional root-file ratchet to 311, adds a helper to preserve pre-0.0.44 guidance, threads that compatibility flag through the onboarding FSM, and compresses an unrelated diagnostics call to stay within another budget. That is additional compatibility and dependency debt without a current supported consumer.

The accepted behavior can be implemented by retaining gateway remove and deleting the obsolete gateway destroy hint at the three affected sites. PR #8188 already provides that smaller independent implementation, so duplicating it here would not be a useful maintainer fix.

Validation on this head: 63 focused CLI tests passed, 3 focused integration tests passed, CLI typecheck passed, source-shape passed, git diff --check passed, and the independent documentation-writer verdict is no-docs-needed. Required GitHub checks are green except E2E / PR Gate, which is pending; the branch also trails current main.

Please either justify an accepted current consumer for the legacy compatibility path without raising the architecture ratchet, or prefer #8188 for the minimal supported-version fix.

@senthilr-nv
senthilr-nv requested a review from cv August 5, 2026 05:01
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Addressing the review feedback: I agree with the smaller supported-version fix.

The configured OpenShell range has no current consumer for the legacy gateway destroy guidance. #8188 removes that unsupported line from the same three onboarding failure paths, adds regression coverage for each behavior, and leaves the intentional executable compatibility fallbacks unchanged. It also avoids the new helper, capability propagation, unrelated formatting change, and onboarding architecture-budget increase in this branch.

#8188 is approved and currently has two checks still running. I will close this PR as superseded only after #8188 merges, and the closing note will link the merged replacement.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Closing as conclusively superseded by #8188, which has merged and implements the accepted scope for #8139: remove the obsolete openshell gateway destroy operator guidance while retaining the supported openshell gateway remove guidance. The maintainer review on this PR explains why the additional legacy compatibility path is not supported by a current consumer and explicitly prefers #8188: #8270 (review). The replacement passed its required CI, selected onboarding E2E scenarios, DCO, commit verification, documentation receipt, and review gates before merge. Thank you for investigating the failure path and contributing an alternative implementation.

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.

[All Platforms][CLI&UX] nemoclaw <sandbox> destroy recommends openshell gateway destroy, which is not a valid subcommand

3 participants