Skip to content

fix(sandbox): continue destroy when pre-delete shields hardening fails (#7727) - #7886

Merged
senthilr-nv merged 17 commits into
mainfrom
fix/7727-destroy-after-shields-failure
Aug 4, 2026
Merged

fix(sandbox): continue destroy when pre-delete shields hardening fails (#7727)#7886
senthilr-nv merged 17 commits into
mainfrom
fix/7727-destroy-after-shields-failure

Conversation

@yimoj

@yimoj yimoj commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

When .config-hash is removed from a locked OpenClaw sandbox, the config guard fails closed by design: shields down cannot unlock, its rollback cannot re-lock, and shields up refuses the tampered baseline. The pre-delete shieldsUp call in wipeAndHardenLiveSandbox ran with throwOnError and no failure handling, so that same failure escaped executeSandboxDestroy and nemoclaw <name> destroy --yes exited 1 with the sandbox still registered. Destroy now warns and continues with deletion when that pre-delete re-lock fails, so the stranded sandbox is removable without manually reconstructing trusted config state. Shields tamper detection is unchanged.

Related Issue

Fixes #7727

Changes

  • src/lib/actions/sandbox/destroy-execution.ts: wipeAndHardenLiveSandbox catches only the pre-delete shieldsUp failure, warns with the guard's own redacted detail, and returns hardenedForDelete: false so the delete-abort path does not open a bounded shields-down rollback window it never closed. The auto-restore timer stays authoritative until deletion succeeds, matching the reason shieldsUp holds it through its own commit; revoking it earlier would turn a delete that then fails into an unbounded mutable window.
  • src/lib/actions/sandbox/destroy-execution.ts / destroy.ts: a failed re-lock now also disables the --force local-cleanup shortcut when the gateway is unreachable. The timer is then the only authority that can lock the config again, so discarding the local record would revoke it for a sandbox whose deletion the gateway never confirmed. The new shieldsRelockRequiresGateway result drives a specific recovery message instead of the generic "re-run with --force" hint.
  • src/lib/actions/sandbox/destroy-flow.test.ts, test/helpers/destroy-flow-test-assertions.ts, test/helpers/destroy-flow-test-harness.ts: regression coverage for delete-proceeds-after-failed-hardening (including warning text and wipe → harden → delete → timer-cleanup ordering), MCP restore without a rollback window when delete then fails, and the --force refusal above. The harness now exposes warnSpy.
  • docs/reference/commands.mdx: the destroy reference documented the old refusal; it now states the warn-and-continue behavior, what happens if that deletion fails, and that a failed pre-delete lock disables the local-only --force fallback.
  • src/lib/actions/sandbox/mcp-bridge-status-state.test.ts: declare the 15 s budget the sibling mcp-bridge-status-removal suite already uses. Every case there spawns a Node child that loads the registry and MCP bridge module graph; ci/cli-test-timing-hints.json records the file at 5515 ms, above the 5000 ms default testTimeout. Adding two destroy-flow cases to the same shard was enough to tip it, failing cli-test-shards (4) three times in a row on this PR while other pull requests passed. Verified by running the whole shard locally (npx vitest run --project cli --shard=4/8 → 140 files / 1710 tests passed).

No new flag, configuration, or fallback layer: the reporter's command is destroy --yes, and it works unchanged.

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:
  • 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: Shields tamper detection is untouched. shields up, shields down, verify-lock.ts, relock-reconfirm.ts, and scripts/openclaw-config-guard.py still fail closed on a missing .config-hash, proven in the macOS E2E below where steps 4–6 keep failing closed on the fixed build. The only behavior change is that an explicit destroy of that sandbox is no longer blocked, and the --force guard above prevents the failed-relock path from discarding the auto-restore authority for an unconfirmed deletion. Nine-category security review is PASS: the current-main sync and provider-neutral comment correction add no feature-scope command, secret, authentication, authorization, input, integrity, egress, or dependency risk; error detail remains redacted and unsafe forced cleanup remains fail-closed. Feature-diff fingerprint: 6df29299cbacf9d01ba97c254872f5a02354dabe17d057ba58c2b86b6fd800c2.
  • 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: docs-updated
  • Evidence: docs/reference/commands.mdx accurately documents failed pre-delete re-lock behavior, timer and local-state preservation after failed destroy, lockdown retry behavior, and the disabled local-only fallback. The documentation writer review covered terminology, structure, voice, and code-sample presentation at exact head 99315ca94. Focused changed suites passed 54/54. npm run docs passed with 0 errors and 2 pre-existing Fern warnings. CLI type-checking, repository checks, and commit hooks passed.
  • Agent: Codex Desktop documentation writer subagent

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 — npm run validate:pr after git fetch origin main: all prek pre-commit hooks, commitlint, and pre-push hooks Passed (exit 0)
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: reviewed revision: focused destroy/MCP/shields suites 96/96 passed; npm run typecheck:cli, npm run checks, and changed-file hooks passed
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: npm test → 22655 passed, 15 failed, all pre-existing or load-induced and unrelated to this change. Re-running exactly those files with this change stashed reproduces 11 of them on the untouched baseline (test/install-station-dgx-os.test.ts, test/install-station-host-preparation.test.ts, test/install-station-package-transaction.test.ts, src/lib/onboard/docker-gpu-patch-rollback.test.ts, test/issue-5667-hosted-inference-model-namespace.test.ts). The other 4 are 17–30 s timeouts under full-suite parallel load that pass in isolation (test/langchain-deepagents-code-image-credentials.test.ts, test/rebuild-credential-preflight.test.ts ×2, test/gateway-state-reconcile-2276.test.ts).
  • 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) — exit 0, 0 errors; 2 pre-existing environment warnings noted above
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Reporter-workflow E2E (macOS arm64, real worktree CLI)

Host h7yr45lq41.dyn.nvidia.com: macOS 26.5.2, arm64 (M4 Pro), Docker 29.3.1 (Colima), OpenShell 0.0.85, live OpenClaw sandbox on gateway nemoclaw-8091. All commands run the worktree CLI (node ./bin/nemoclaw.js), never a global nemoclaw.

Before the fix (worktree built at main 4dcb89ea1), reporter steps 1–7 on live sandbox sb-7430-clone:

$ node ./bin/nemoclaw.js sb-7430-clone shields up            # Lockdown is already active.  (exit 0)
$ docker exec <c> stat -c '%U:%G %a %n' /sandbox/.openclaw/openclaw.json /sandbox/.openclaw/.config-hash
root:root 444 /sandbox/.openclaw/openclaw.json
root:root 444 /sandbox/.openclaw/.config-hash
$ docker exec --user root <c> rm -f /sandbox/.openclaw/.config-hash
$ node ./bin/nemoclaw.js sb-7430-clone shields down
  CRITICAL: OpenClaw lock rollback could not restore the trusted posture. ... [stat-failed] .config-hash ... after 3 pair attempts
  Config remains unlocked — manual intervention required.
exit4=1
$ node ./bin/nemoclaw.js sb-7430-clone shields up            # same [stat-failed] failure, exit5=1
$ node ./bin/nemoclaw.js sb-7430-clone shields status
  Shields: DOWN (temporarily unlocked)   Policy: permissive     # while openclaw.json is still root:root 444
$ node ./bin/nemoclaw.js sb-7430-clone destroy --yes
  ERROR: Config not locked: OpenClaw config guard lock [stat-failed] /sandbox/.openclaw/.config-hash ...
exit7=1

nemoclaw list and openshell sandbox list both still showed sb-7430-clone — the reporter's Actual Result reproduced exactly.

After the fix (worktree rebuilt from validated PR revision ba66d0407, fresh sandbox sb-7727-final restored from a snapshot, identical steps 1–6 still failing closed):

$ node ./bin/nemoclaw.js sb-7727-final destroy --yes
  Restoring restrictive policy from snapshot...
  CRITICAL: OpenClaw lock rollback could not restore the trusted posture. ... [stat-failed] .config-hash ... after 3 pair attempts
  ERROR: Config not locked: OpenClaw config guard lock [stat-failed] /sandbox/.openclaw/.config-hash ...
  ⚠ Could not re-lock shields for 'sb-7727-final' before delete: Config not locked: OpenClaw config guard lock [stat-failed] ...
  Continuing with delete — 'sb-7727-final' and its unguarded config are removed together. If the delete fails, the auto-restore timer keeps retrying the lock until it succeeds or the sandbox is deleted or rebuilt.
  ✓ Sandbox 'sb-7727-final' destroyed
exit7=0

After that run nemoclaw list and openshell sandbox list show only the unrelated sb-7430, and the sandbox's shields state and timer marker are gone (leftover_shields_artifacts=0), confirming the post-delete timer/shields cleanup still runs. Steps 4–6 on the fixed build still exit 1 with the same tamper evidence, so the fail-closed boundary the issue explicitly preserves is intact.


Signed-off-by: Yimo Jiang yimoj@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Sandbox deletion now proceeds safely when hardening fails, while preserving protections needed to re-lock configuration.
    • Forced cleanup is refused when deletion cannot be confirmed or gateway access is required.
    • Improved warnings and recovery guidance for unreachable gateways.
    • Expired protection timers now correctly restore lockdown and clean up transition state.
  • Tests

    • Added coverage for hardening failures, failed deletion recovery, MCP restoration, and timer expiration.
    • Increased timeout coverage for cross-agent MCP status checks.

#7727)

When `.config-hash` is removed from a locked OpenClaw sandbox, the config
guard fails closed by design: `shields down` cannot unlock, its rollback
cannot re-lock, and `shields up` refuses the tampered baseline. The
pre-delete `shieldsUp` call in `wipeAndHardenLiveSandbox` ran with
`throwOnError` and no failure handling, so that same failure escaped
`executeSandboxDestroy` and `destroy --yes` exited 1. The sandbox stayed
registered with no supported recovery path short of manually restoring
trusted config state.

Catch only that pre-delete hardening failure, warn with the guard's own
detail, and continue with deletion. Tamper detection is unchanged: shields
still fails closed, and `hardenedForDelete: false` keeps the delete-abort
path from opening a bounded rollback window it never closed.

A failed re-lock leaves the auto-restore timer as the only authority that
can lock the config again, so `--force` no longer takes the local-cleanup
shortcut when the gateway is unreachable after a failed re-lock. Discarding
the record there would revoke that authority for a sandbox whose deletion
the gateway never confirmed.

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

destroy sandbox now continues after shield hardening failure when deletion succeeds, preserves local recovery state when deletion fails, and rejects unsafe forced cleanup. Tests cover deletion, MCP restoration, expired timer ownership, and related timing.

Changes

Sandbox destroy behavior

Layer / File(s) Summary
Post-wipe hardening and cleanup
src/lib/actions/sandbox/destroy-execution.ts
Destroy execution records shield re-lock failures, preserves valid timer state, continues deletion when permitted, and blocks forced local cleanup when hardening fails.
Destroy failure reporting and documentation
src/lib/actions/sandbox/destroy.ts, docs/reference/commands.mdx
Destroy reports gateway-dependent re-lock failures, preserves automatic recovery state, and documents retry and force restrictions.
Scenario coverage and state recovery
src/lib/actions/sandbox/destroy-flow.test.ts, test/helpers/destroy-flow-test-assertions.ts, src/lib/shields/flow.test.ts, src/lib/actions/sandbox/mcp-bridge-status-state.test.ts
Tests cover continued deletion, refused forced cleanup, MCP restoration, expired timer ownership recovery, and increased MCP test timeout tolerance.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant destroySandbox
  participant shields
  participant Sandbox
  Operator->>destroySandbox: destroy sandbox
  destroySandbox->>shields: re-lock configuration
  shields-->>destroySandbox: re-lock failure
  destroySandbox->>Sandbox: attempt deletion
  Sandbox-->>destroySandbox: deletion result
  destroySandbox-->>Operator: report deletion or preserved recovery state
Loading

Possibly related issues

Possibly related PRs

  • NVIDIA/NemoClaw#5476: This PR extends the same destroy-flow harness and tests for hardening failures, forced cleanup refusal, and MCP restoration.
  • NVIDIA/NemoClaw#8074: Both address Shields auto-restore timer state and persisted recovery behavior.
  • NVIDIA/NemoClaw#8130: Both cover Shields timer expiry and lifecycle-lock handling.

Suggested labels: area: security

Suggested reviewers: senthilr-nv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes support the linked issue, but the MCP bridge suite timeout adjustment is unrelated maintenance. Move the MCP bridge timeout change to a separate pull request unless it is required to validate this fix.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes provide the linked issue's required destroy recovery path while preserving timer state, fail-closed behavior, and force-cleanup safeguards [#7727].
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: continuing sandbox destruction when pre-delete Shields hardening fails.
✨ 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/7727-destroy-after-shields-failure

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

@github-code-quality

github-code-quality Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 99315ca in the fix/7727-destroy-aft... branch remains at 96%, unchanged from commit b724932 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 99315ca in the fix/7727-destroy-aft... branch remains at 81%, unchanged from commit 643a4ab in the main branch.

Show a code coverage summary of the most impacted files.
File main 643a4ab fix/7727-destroy-aft... 99315ca +/-
src/lib/actions...oy-execution.ts 95% 89% -6%
src/lib/platform.ts 89% 84% -5%
src/lib/shields/index.ts 70% 70% 0%
src/lib/actions...dbox/destroy.ts 89% 89% 0%
src/lib/messagi...nnels/policy.ts 100% 100% 0%
src/lib/sandbox...rce-identity.ts 88% 88% 0%
src/lib/state/config-io.ts 93% 93% 0%
src/lib/tunnel/services.ts 76% 76% 0%

Updated August 04, 2026 06:39 UTC

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 30, 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.
6 terminology differences from the second opinion

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

  • lockdown at docs/reference/commands.mdx:1788: selected only by the second-opinion lane as established.
  • hardening at src/lib/actions/sandbox/destroy-execution.ts:141: selected only by the second-opinion lane as established.
  • shields-down rollback at src/lib/actions/sandbox/destroy-execution.ts:153: selected only by the second-opinion lane as established.
  • delete-abort at src/lib/actions/sandbox/destroy-execution.ts:152: selected only by the second-opinion lane as justified.
  • tamper laundering at src/lib/actions/sandbox/destroy-execution.ts:138: selected only by the second-opinion lane as justified.
  • unguarded config at docs/reference/commands.mdx:1786: 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.

  • sandbox-survival: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • security-posture: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • ubuntu-repo-cloud-openclaw: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • ubuntu-repo-docker-post-reboot-recovery: 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.

3 semantic terminology decisions

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

  • justified — pre-delete re-lock at docs/reference/commands.mdx:1785: Keep the term. The surrounding text states the failure and retry behavior.
  • established — local-only fallback at docs/reference/commands.mdx:1811: Keep the established term and its expanded failed-re-lock constraint.
  • justified — unguarded configuration at docs/reference/commands.mdx:1786: Keep the term. The adjacent sentences define deletion and timer-recovery outcomes.

E2E guidance

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

Recommended E2E: onboard-repair, onboard-resume

2 optional E2E recommendations
  • sandbox-operations
  • shields-config

Workflow run details

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

yimoj and others added 4 commits July 30, 2026 07:32
…lock (#7727)

The destroy reference and the CLI warning said the config stays unlocked
until the sandbox is deleted or rebuilt when the delete fails after a
failed pre-delete lock. That omitted the auto-restore timer this path
deliberately preserves, which keeps retrying the lock and can restore it
once the sandbox is reachable again (PR Review Advisor PRA-1).

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each case in this suite spawns a Node child that loads the registry and
MCP bridge module graph. `ci/cli-test-timing-hints.json` records the file
at 5515ms, above the 5000ms default `testTimeout`, so the suite fails on
timing alone whenever its shard is busy. Adding two destroy-flow cases to
the same shard was enough to tip it, failing `cli-test-shards (4)` three
times in a row while other pull requests passed.

Declare the same 15s budget the sibling `mcp-bridge-status-removal` suite
already uses for its child-process cases.

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…7727)

The failed-hardening fallback described the invalid state and the
immediate behavior but not why the missing integrity sidecar cannot be
repaired at its source, or when the fallback can be removed (PR Review
Advisor PRA-1).

State the boundary in the repository's SOURCE_OF_TRUTH form: host root
removes the sidecar out of band, the locked-posture refusal belongs to
the config guard and is deliberate tamper evidence that #7727 keeps, and
the fallback goes away once the guard gains a supported authenticated
repair for a missing sidecar in the locked posture.

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Refresh the branch against origin/main so the pull request tests the
current base.

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@apurvvkumaria apurvvkumaria self-assigned this Jul 30, 2026
@yimoj

yimoj commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
(cherry picked from commit a4f2b3433f0647f0b69ca009f9722ac146fa1aec)
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@wscurran wscurran added area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression labels Jul 31, 2026
apurvvkumaria and others added 2 commits July 31, 2026 12:59
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 1, 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.

@github-actions github-actions Bot added v0.0.102 Release target and removed v0.0.101 labels Aug 3, 2026
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

@apurvvkumaria apurvvkumaria 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.

Approved after reviewing revision 4c6be5775.

Sensitive-path security review: PASS with no findings across the repository's nine categories:

  1. Secrets and credentials: no credential sources, values, or persistence change; the caught error remains redacted before logging.
  2. Input validation and sanitization: sandbox-name handling and existing validated timer-token handling are unchanged.
  3. Authentication and authorization: OpenShell deletion authority and runtime-provider cleanup authority remain required; the corrected early failure result performs no deletion.
  4. Dependencies and third-party libraries: no dependency or workflow changes.
  5. Error handling and logging: pre-delete re-lock failure is reported without leaking sensitive detail; the runtime-provider-authority failure now returns the complete typed failure shape.
  6. Cryptography and data protection: the config guard's tamper-evidence behavior remains fail-closed; no hash or cryptographic behavior changes.
  7. Configuration and security controls: deletion may proceed only after the explicit destroy request; if deletion is unconfirmed after re-lock failure, local shields state and the auto-restore timer remain authoritative and forced local cleanup is refused.
  8. Security testing: focused destroy, shields, MCP, and runtime-provider tests pass (96/96); CLI type-check and repository checks pass.
  9. System security: successful deletion removes the unguarded configuration with the sandbox, while failed deletion retains recovery authority and avoids creating an unbounded mutable window.

The documentation writer reviewed the completed change, and the documentation build passes with 0 errors. No administrator bypass or gate waiver is used.

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

@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.

Approved at 99315ca. This is in scope as a fix to the existing destroy lifecycle. Focused tests, CLI type-checking, repository checks, docs build, security review, and documentation writer review pass.

@senthilr-nv
senthilr-nv enabled auto-merge (squash) August 4, 2026 06:34
@senthilr-nv
senthilr-nv merged commit 6774bec into main Aug 4, 2026
69 of 70 checks passed
@senthilr-nv
senthilr-nv deleted the fix/7727-destroy-after-shields-failure branch August 4, 2026 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression v0.0.102 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[macOS][Sandbox] missing .config-hash in locked posture blocks destroy --yes after a failed Shields rollback

4 participants