Skip to content

fix(sandbox): catch McpBridgeError in destroy MCP bridge path (#8103) - #8313

Merged
jyaunches merged 6 commits into
mainfrom
codex/pr8298-verified
Aug 5, 2026
Merged

fix(sandbox): catch McpBridgeError in destroy MCP bridge path (#8103)#8313
jyaunches merged 6 commits into
mainfrom
codex/pr8298-verified

Conversation

@apurvvkumaria

@apurvvkumaria apurvvkumaria commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

This replacement preserves the implementation and contributor attribution from #8298 while removing an unverified commit from the published history. Sandbox destruction now returns a structured, redacted failure when MCP bridge preparation or finalization fails instead of exposing an uncaught stack trace.

Related Issue

Refs #8103

Supersedes #8298 after this replacement passes all repository gates.

Changes

  • Catch McpBridgeError before destructive work starts and return its redacted failure result.
  • Catch McpBridgeError after sandbox deletion and preserve the registry state required for retry.
  • Rethrow other error types and add negative-path tests for both MCP bridge failure stages.
  • Preserve Yanyun Liao as the implementation author and Carlos Villela as the architecture-budget update author.
  • Ratchet the affected source architecture budgets to the values measured by the replacement branch.

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 sandbox lifecycle documentation covers MCP preparation failures, retry-state preservation, post-deletion cleanup, and rerunning destroy. This change returns the documented structured failure instead of an uncaught stack trace.
  • 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: The nine-category maintainer security review passed with no findings: fix(sandbox): catch McpBridgeError in destroy MCP bridge path (#8103) #8313 (comment)
  • 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: docs/security/best-practices.mdx already defines the CLI redaction contract, and docs/manage-sandboxes/manage-mcp-servers.mdx already documents preserved recovery state and rerunning destroy. The change adds no command, option, configuration, lifecycle boundary, or supported user procedure.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit: Not applicable; scripts/prepare-dgx-station-host.sh is unchanged.
  • Station profile/scenario: Not applicable.
  • Result: Not applicable.
  • Supporting evidence: Not applicable.

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 — npx vitest run --project cli src/lib/actions/sandbox/destroy-flow.test.ts passed 27 tests.
  • Applicable broad gate passed — npm run typecheck:cli, npm run source-shape:check, and npx prek run --from-ref origin/main --to-ref HEAD passed.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: yanyunl1991 mzhong@nvidia.com
Signed-off-by: Yanyun Liao yanyunl@nvidia.com
Signed-off-by: Carlos Villela cvillela@nvidia.com
Signed-off-by: Apurv Kumaria akumaria@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Sandbox destruction now handles MCP bridge failures gracefully instead of exposing unhandled errors.
    • Preparation failures stop deletion and cleanup safely.
    • Finalization failures return clear failure results, redact sensitive details, and preserve required sandbox and gateway state.
    • Retrying after a finalization failure now completes cleanup successfully.
  • Tests

    • Added coverage for MCP bridge failures during sandbox destruction, including exit codes, redaction, retries, and state preservation.

yanyunl1991 and others added 2 commits August 5, 2026 02:10
…ze in destroy path (#8103)

`executeSandboxDestroy` called `prepareMcpDestroy` and `finalizeMcpDestroy`
with no `McpBridgeError` guard. When a managed MCP server is present and the
gateway becomes unreachable, `inspectExactMcpDestroyProvider` throws
`McpBridgeError("Could not inspect OpenShell provider…")` which propagated
uncaught, crashing `destroy --yes` with a stack trace instead of a clean
exit-1 message. The same uncaught escape existed for `finalizeMcpDestroy`'s
internal re-throw after post-delete cleanup fails.

Both call sites now catch `McpBridgeError` and return `{ ok: false, … }`,
letting the existing failure-path rendering in `destroy.ts` surface the error
cleanly and exit with the error's own `exitCode`.

Signed-off-by: yanyunl1991 <yanyunl@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria apurvvkumaria added the v0.0.103 Release target label Aug 5, 2026
@apurvvkumaria apurvvkumaria self-assigned this Aug 5, 2026
@apurvvkumaria

apurvvkumaria commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Security review: PASS, no findings

Updated after the review-feedback changes on the current branch.

  1. Secrets and credentials: MCP finalization diagnostics now pass through full destroy-error redaction before logging. The regression test proves a raw secret marker never reaches console error output.
  2. Input validation and sanitization: The change adds no parser, interpolation, or command construction. It handles the existing typed McpBridgeError boundary.
  3. Authentication and authorization: Managed MCP ownership checks remain unchanged. Preparation failures still stop before sandbox deletion.
  4. Dependencies and supply chain: The change adds no dependency, package source, workflow, or build input.
  5. Error handling and logging: Preparation and finalization bridge failures return structured redacted results. The internal post-delete diagnostic is now also redacted before emission. Other error types still propagate.
  6. Cryptography and data protection: Not applicable. The change adds no cryptographic operation or data format.
  7. Configuration and secure defaults: The change adds no policy, network exposure, container permission, or security-header behavior.
  8. Security testing: Tests prove preparation failure prevents deletion, finalization follows confirmed deletion, raw secret material is absent from logs, and retained state converges on retry.
  9. Holistic security posture: The change fails closed before deletion, preserves retry authority after confirmed deletion, and proves the retry retires registry, session, and applicable gateway state.

Validation:

  • Focused destroy-flow suite passed all 28 tests.
  • CLI type-check, source-shape, test-title, formatting, lint, repository, environment-documentation, secret-scan, and test-size checks passed.
  • GitHub reports all three signed commits as Verified.

Contributor attribution remains preserved for Yanyun Liao and Carlos Villela.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Sandbox destruction now handles McpBridgeError during MCP preparation and finalization as structured failures. Tests cover abort, redaction, retained state, and retry cleanup. Architecture budget thresholds were updated for registry and onboard paths.

Changes

Sandbox destruction error handling

Layer / File(s) Summary
MCP bridge failure handling
src/lib/actions/sandbox/destroy-execution.ts
destroySandbox returns structured failure results for MCP preparation and finalization errors, redacts finalization output, and rethrows other errors.
MCP failure test coverage
test/helpers/destroy-flow-test-harness.ts, test/helpers/destroy-flow-test-assertions.ts, src/lib/actions/sandbox/destroy-flow.test.ts
The harness injects MCP bridge failures. Tests verify preparation aborts before deletion, finalization redacts secrets, state remains available, and retry cleanup succeeds.

Architecture budget updates

Layer / File(s) Summary
Budget thresholds
ci/source-architecture-budget.json
Fan-in, fan-out, and root-file limits were updated for registry and onboard paths.

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

Sequence Diagram(s)

sequenceDiagram
  participant destroySandbox
  participant MCPBridge
  participant SandboxState
  destroySandbox->>MCPBridge: Prepare MCP state
  MCPBridge-->>destroySandbox: Return McpBridgeError
  destroySandbox-->>SandboxState: Retain state and return failure
  destroySandbox->>MCPBridge: Finalize MCP state
  MCPBridge-->>destroySandbox: Return redacted failure
  destroySandbox-->>SandboxState: Preserve retryable state
Loading

Possibly related PRs

Suggested labels: area: sandbox, bug-fix, v0.0.103

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: catching McpBridgeError in the sandbox destruction MCP bridge path.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/pr8298-verified

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

@github-code-quality

github-code-quality Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit ec94feb in the codex/pr8298-verifie... branch remains at 96%, unchanged from commit 28fdd78 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit ec94feb in the codex/pr8298-verifie... branch remains at 81%, unchanged from commit 28fdd78 in the main branch.

Show a code coverage summary of the most impacted files.
File main 28fdd78 codex/pr8298-verifie... ec94feb +/-
src/lib/sandbox...rce-identity.ts 87% 87% 0%
src/lib/credentials/store.ts 55% 56% +1%
src/lib/actions...oy-execution.ts 89% 92% +3%

Updated August 05, 2026 10:48 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.

Actionable comments posted: 2

🤖 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/actions/sandbox/destroy-execution.ts`:
- Around line 343-357: Update finalizeMcpDestroy error logging to pass the error
through redactDestroyError before logging its details, ensuring secret markers
never reach console.error. Add a regression test for the destroy flow that
triggers an MCP cleanup failure and asserts console.error receives the redacted
output rather than the secret marker.

In `@test/helpers/destroy-flow-test-assertions.ts`:
- Around line 232-237: Update expectMcpFinalizeBridgeErrorReturnsFailure to
capture the invocation index of the sandbox delete spy and assert that
finalizeMcpBridgesAfterSandboxDeleteSpy was called afterward. Preserve the
existing assertions that finalization occurs and cleanup spies are not called.
🪄 Autofix

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: d7ab7629-02d2-49b0-93a5-3360bd612b78

📥 Commits

Reviewing files that changed from the base of the PR and between 3a39ff3 and 28e1df0.

📒 Files selected for processing (5)
  • ci/source-architecture-budget.json
  • src/lib/actions/sandbox/destroy-execution.ts
  • src/lib/actions/sandbox/destroy-flow.test.ts
  • test/helpers/destroy-flow-test-assertions.ts
  • test/helpers/destroy-flow-test-harness.ts

Comment thread src/lib/actions/sandbox/destroy-execution.ts
Comment thread test/helpers/destroy-flow-test-assertions.ts Outdated
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / low confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: PR review advisor failed: PR review advisor SDK execution failed: session: terminology-review-analysis omitted required analysis; turn: terminology-review-analysis: terminology-review-analysis omitted required analysis

Model lanes

  • GPT-5.6 Terra (primary): Failed
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions

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

E2E guidance

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

Recommended E2E: 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.

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

Copy link
Copy Markdown
Collaborator Author

Addressed PRA-1 in the latest branch revision. A new two-attempt destroy-flow test makes MCP finalization fail after deletion, verifies the retained local state, marks the remote sandbox absent, retries destroy, and confirms finalization plus registry, onboarding-session, and applicable gateway cleanup converge. The focused destroy-flow suite passes all 28 tests.

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

cv commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Maintainer merge-train review of PR commit adf49fd8c857b30be48d5f93d0f7968075fd3c5a:

This PR is not approval-ready.

  • Refresh the branch from current main at a82887e8b3263b206d001e3109315fad7d2588c0.
  • CLI shard 4 fails at src/lib/actions/sandbox/destroy-flow.test.ts:419. The retry calls destroy with yes: true but expects final gateway cleanup. If the test is intended to prove cleanup, pass cleanupGateway: true on that retry.
  • Build and type-check jobs also fail because the package-contract fixture on current main does not copy nemoclaw/dist/shared/openshell-policy-boundary.cjs. That inherited main regression needs a separate fix.
  • Tighten the preparation invariant comment to: MCP preparation must succeed before sandbox deletion begins.

Compared with #8324, this branch is closer to approval because it already covers redacted finalization errors, delete-before-finalize ordering, and retry retirement. Its automated-review threads are also resolved. Neither PR satisfies the broader rebuild, recreate, and recorded-or-live drift acceptance criteria in #8103, so keeping Refs #8103 is correct.

After the refresh and fixes, rerun the focused destroy-flow tests and repository PR validation. Refresh the documentation writer and security reviews for the resulting PR commit. Then let the required checks complete.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator Author

Addressed the CLI shard-4 failure in revision 5934ec1a0.

The retry-convergence test asserted that the shared gateway was cleaned up, but its second destroy call did not request gateway cleanup. That passed in an interactive local environment because the test prompt defaulted to “yes”; CI correctly preserves the gateway in non-interactive mode unless cleanup is explicit.

The second call now sets cleanupGateway: true, matching the state transition the test asserts. The focused destroy-flow suite passes all 28 tests with CI=1, and the normal commit and push hooks passed. The documentation writer confirmed this is test-only and requires no documentation change; the PR receipt is refreshed for the new revision.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator Author

The completed CLI run has two independent failures:

  • Shard 8 is the current-main timing-manifest regression tracked by #8327: the manifest still names the deleted test/pr-review-advisor.test.ts path. This is deterministic and unrelated to the destroy-flow change.
  • Shard 3 timed out in src/lib/inference/vllm-install-storage.test.ts while waiting on unrelated gateway startup output. That file is unchanged by this PR. The focused suite passes all 27 tests under CI=1 on the current branch, with the full suite completing in about two seconds, so this failure is classified as transient runner contention.

I am not rerunning the full failed job set while the deterministic shard-8 base failure remains. After #8327 merges, the branch can refresh and run one clean gate that also supersedes the transient timeout result.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator Author

The one permitted rerun of the Terra advisor lane also failed in the advisor runtime while verifying its analysis outcome. The Nemotron lane and publisher passed, and the branch has 39 passing checks with no pending checks or unresolved review threads. I will not rerun the same transient lane again without new evidence. The documented external advisor failure and independent approval remain the merge blockers.

@jyaunches
jyaunches merged commit ac24de0 into main Aug 5, 2026
76 of 78 checks passed
@jyaunches
jyaunches deleted the codex/pr8298-verified branch August 5, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.0.103 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants