Skip to content

fix(sandbox): recover managed gateway after protected start - #8682

Closed
souvikDevloper wants to merge 8 commits into
NVIDIA:mainfrom
souvikDevloper:fix/8662-shields-stop-start
Closed

fix(sandbox): recover managed gateway after protected start#8682
souvikDevloper wants to merge 8 commits into
NVIDIA:mainfrom
souvikDevloper:fix/8662-shields-stop-start

Conversation

@souvikDevloper

@souvikDevloper souvikDevloper commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Protected Docker stop/start now preserves one immutable container identity from lifecycle start through managed recovery, OpenShell readiness, required host-forward recovery, and a final authenticated managed-gateway probe.

The same change extends the existing OpenClaw and Hermes Shields live targets to exercise both Shields postures and emit redacted evidence for container identity, registered inference configuration, Shields receipts, protected filesystem state, readiness leases, PID 1, the managed process chain, and host forwards.

Related Issue

Fixes #8662

Changes

  • Pin Docker start, unpause, stop, privileged recovery, Shields startup repair, and final verification to the discovered immutable 64-character container ID.
  • Run the real authenticated managed recovery controller for built-in OpenClaw and Hermes sandboxes, preserve custom and terminal-agent behavior, and prohibit relaunch, rebuild, or replacement during lifecycle-owned recovery.
  • Return success only after managed gateway health, OpenShell Ready, required host forwards, inference-route reconciliation, any applicable best-effort pairing pass, and a final pinned authenticated probe all succeed.
  • Fail closed with layer-specific recover, shields up, doctor, or rebuild guidance while redacting private diagnostics.
  • Add a shared protected-restart E2E evidence collector to the existing shields-config and hermes-shields-config targets for Shields up and Shields down.
  • Document the managed Docker start contract, automatic unpause, success gates, and recovery guidance.

Acceptance Evidence

#8662 requirement Same-commit proof in this PR
OpenClaw, Shields up returns Ready Existing shields-config target now runs the public stop/start path under Shields up and asserts the full return barrier. Runtime result is pending vetted Linux/Docker CI on 13d6da02d.
Hermes, Shields up returns Ready Existing hermes-shields-config target now runs the same protected lifecycle and evidence contract. Runtime result is pending vetted Linux/Docker CI on 13d6da02d.
Both Shields-down paths continue to pass Both live targets run the identical evidence helper again after Shields down on the same commit. Runtime result is pending vetted Linux/Docker CI.
Success waits for gateway and forwards startSandbox consumes the real recovery result; connect-time verification requires OpenShell Ready and forwards; a final nonce-bound authenticated pinned probe runs after reconciliation. Unit tests prove ordering and fail-closed behavior.
Specific actionable failures Tests cover inspection, supervisor, gateway health, OpenShell readiness, secret boundary, MCP reconciliation, managed recovery, host forwards, expired Shields restore, malformed Docker discovery, and identity drift; raw private details are excluded.
No replace, rebuild, destroy, or workspace loss Docker lifecycle operations use the immutable ID, preserveContainer blocks relaunch, and live evidence asserts unchanged ID, name, creation timestamp, image, and workspace marker.
Configuration and inference unchanged Live evidence compares registry entry/inference hashes, Shields state and seal hashes, and protected config file hashes before and after each restart.
Shields-up owners and modes retained Live evidence records and compares owner, group, mode, type, link count, and content hash for required files/directories.
Seals, confidentiality, readiness, and PID 1 auth remain strong Evidence validates configuration seals/confidentiality roots, fresh PID 1-bound readiness leases, root-owned runtime boundaries, a non-root managed supervisor/gateway chain, matching PID namespace, and nonce-authenticated controller output without persisting the nonce.
Public start plus real managed recovery coverage start.test.ts drives public startSandbox through production restoreSandboxStartupState for both agents with an unavailable initial probe and asserts that the real pinned controller result reaches the public failure/success boundary.
Both live targets pass on one commit The two targets and their four posture cases are wired to 13d6da02d; NVIDIA runner execution is still required because the contributor PR is awaiting vetting and this Windows host has no Docker Desktop Linux engine.

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: The implementation was reviewed against immutable runtime identity, authenticated managed control, Shields locking/seals, credential redaction, readiness leases, PID 1 identity, and forward ownership. Recovery fails closed without raw diagnostic disclosure.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: The contributor PR still requires NVIDIA runner vetting; no waiver is claimed.

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: docs/manage-sandboxes/recover-rebuild-sandboxes.mdx, docs/manage-sandboxes/run-sandboxes.mdx, and docs/reference/commands.mdx; independently verified against the pinned lifecycle, managed recovery, forward recovery, Docker identity, Shields startup-access, unit/regression, and four-case live evidence contracts. No blocking documentation finding or unsupported changed-page claim remains.
  • Agent: Codex Desktop (/root/documentation_writer_review)

DGX Station Hardware Evidence

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

Verification

  • PR description includes a Signed-off-by: line and every new commit is SSH-signed; GitHub verification will be visible after push
  • 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 — 193 focused CLI tests plus all 3 focused Shields-up stop/start regression leaves OpenClaw and Hermes sandboxes unready #8662 connect-flow tests passed
  • Applicable broad gates passed — npx tsc -p tsconfig.src.json, semantic E2E phase coverage (125 tests across 81 files), source-shape/test-size budgets, Biome, and the test-conditional scan passed
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed — gitleaks and private-key detection passed
  • 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)

Documentation validation passed agent-variant generation, published-route checks, and Fern with zero errors. The full docs/repository umbrella stops on pre-existing CRLF in untouched docs/resources/starter-prompt.md. Local protected live runs could not start because Docker Desktop's Linux engine is unavailable on this Windows host; the same-commit NVIDIA runner results remain the final acceptance gate.


Signed-off-by: souvikDevloper 138186578+souvikDevloper@users.noreply.github.com

Summary by CodeRabbit

  • New Features

    • Sandbox recovery now preserves existing containers and verifies their runtime identity during startup and restart.
    • Added stronger readiness, gateway health, host-forward, and Shields recovery checks.
    • Recovery results now provide structured status and sanitized, actionable failure details.
    • Docker operations now use immutable container identities for safer inspection and recovery.
  • Documentation

    • Updated sandbox recovery and start guidance, including container preservation and Shields restoration steps.
  • Tests

    • Expanded coverage for recovery, identity validation, readiness, diagnostics, and protected restarts.

Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>
@copy-pr-bot

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

Sandbox recovery now pins immutable container identity, preserves existing containers, validates managed gateway and OpenShell readiness, and returns structured failures. Docker lifecycle, Shields handling, forward recovery, tests, E2E evidence, and documentation were updated.

Changes

Protected sandbox recovery

Layer / File(s) Summary
Immutable runtime identity and lifecycle
src/lib/onboard/docker-driver-sandbox-recovery.ts, src/lib/onboard/runtime-provider/*
Docker discovery, start, stop, unpause, rename, inspection, and readiness checks use validated full container IDs.
Managed recovery and readiness verification
src/lib/actions/sandbox/process-recovery.ts, src/lib/actions/sandbox/connect.ts
Recovery pins identity, preserves containers, retries supervisor startup states, validates managed health, waits for OpenShell readiness, and reports sanitized failures.
Forward and Shields recovery guards
src/lib/actions/sandbox/forward-recovery.ts, src/lib/shields/index.ts
Forward mutations use managed health callbacks. Pinned Shields restoration disables inline auto-restore when required.
Startup integration
src/lib/actions/sandbox/start.ts, src/lib/actions/sandbox/start.test.ts
Startup propagates recovery options, validates structured recovery before readiness checks, and verifies the final managed gateway and forwards.
Protected restart evidence
test/e2e/live/shields-restart-recovery-evidence.ts, test/e2e/live/shields-config.test.ts, test/e2e/live/hermes-shields-config.test.ts
E2E checks capture container identity, readiness, managed control, forwards, Shields posture, protected files, and restart-state preservation.
Recovery documentation and tests
docs/manage-sandboxes/*, docs/reference/commands.mdx, src/lib/actions/sandbox/*test.ts, src/lib/onboard/*test.ts
Documentation and tests cover non-destructive recovery, identity pinning, failure guidance, retries, ordering, and diagnostic redaction.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

Suggested labels: bug-fix, area: sandbox, platform: container, area: security

Suggested reviewers: apurvvkumaria, cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.63% 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 [#8662] with identity-preserving recovery, readiness and gateway checks, forward restoration, fail-closed diagnostics, and protected restart coverage.
Out of Scope Changes check ✅ Passed The code, tests, documentation, and E2E evidence changes directly support the protected sandbox stop/start recovery objectives.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: recovering the managed gateway after a protected sandbox start.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@souvikDevloper
souvikDevloper marked this pull request as ready for review August 10, 2026 05:13

@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/start.test.ts`:
- Around line 213-274: Update the parameterized test around startSandbox to
verify that the secret-boundary case also redacts its private detail. Use a
shared row-specific private-detail sentinel or assert each case’s corresponding
reason/detail is absent from the thrown error message, while preserving the
existing expected public-message assertions.

In `@src/lib/actions/sandbox/start.ts`:
- Around line 151-152: Update startSandbox so assertSandboxStartupRecovery is
invoked only when managed recovery is required, while preserving the default
OpenClaw path when resolved.sandbox.agent is unset. Keep custom-agent startup
flowing to verifyGateway and add coverage for an inconclusive recovery result
with a successful readiness probe.
🪄 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: c0a7f5b4-0d2f-4de0-b12a-0813b4bcbd95

📥 Commits

Reviewing files that changed from the base of the PR and between 44e8bc4 and 34ba1cf.

📒 Files selected for processing (3)
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/start.test.ts
  • src/lib/actions/sandbox/start.ts

Comment thread src/lib/actions/sandbox/start.test.ts Outdated
Comment thread src/lib/actions/sandbox/start.ts Outdated
Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 10, 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): Failed after a partial review · low confidence · 1 blocker · 2 warnings · 1 suggestion

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

4 semantic terminology decisions

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

  • established — managed recovery at docs/manage-sandboxes/recover-rebuild-sandboxes.mdx:29: Keep `managed recovery`; repository history uses the term with this meaning.
  • justified — immutable runtime identity at docs/reference/commands.mdx:1543: Keep `immutable runtime identity` and retain the Docker-driver and existing-container context at first use.
  • replace — protected restart at test/e2e/live/shields-config.test.ts:403: Replace `protected restart` with `stop/start recovery that preserves the existing container` in the E2E contract.
  • replace — protected restart at test/e2e/live/hermes-shields-config.test.ts:210: Replace `protected restart` with `stop/start recovery that preserves the existing container` in the Hermes E2E contract.

E2E guidance

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

Recommended E2E: cloud-inference, cloud-onboard, managed-image-multiarch-startup, managed-image-protected-runtime, security-posture, hermes-shields-config, onboard-repair, onboard-resume, shields-config, ubuntu-repo-docker-post-reboot-recovery

Workflow run details

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

@souvikDevloper

Copy link
Copy Markdown
Contributor Author

@apurvvkumaria can you please take a look. @cv can i get the ci now

Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>
Co-authored-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>

@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 (6)
src/lib/shields/index.ts (1)

2633-2655: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add pinned startup-access propagation coverage.

startSandbox passes result.runtimeHandle through processRecovery to restoreStoppedSandboxStartupState. Add a test that passes expectedContainerId and asserts that restoreLockedStartupAccess receives it. Current tests cover only the undefined case, while startSandbox tests replace the restoration bridge with a mock.

🤖 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/shields/index.ts` around lines 2633 - 2655, Add test coverage for the
pinned-container path through startSandbox, verifying that result.runtimeHandle
is propagated by processRecovery into restoreStoppedSandboxStartupState and
ultimately passed as expectedContainerId to restoreLockedStartupAccess. Extend
the existing restoration-bridge mock assertions while preserving the current
undefined-case coverage.

Source: Path instructions

src/lib/actions/sandbox/connect.ts (1)

252-276: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Strip control characters before redaction.

sanitizeSandboxStartupRecoveryDetail calls redactFull first, then removes C0/C1 control characters. A secret-shaped token that contains an embedded control character therefore reaches redactFull in split form and can escape the redaction patterns. It then becomes contiguous after the control characters are replaced with spaces.

Reverse the order so redaction runs on normalized text.

🛡️ Proposed reordering
 export function sanitizeSandboxStartupRecoveryDetail(raw: string): string {
-  return redactFull(raw)
-    .replace(/[\u0000-\u001f\u007f-\u009f]/gu, " ")
-    .replace(/\s+/gu, " ")
-    .trim()
-    .slice(0, 240);
+  const normalized = raw
+    .replace(/[\u0000-\u001f\u007f-\u009f]/gu, " ")
+    .replace(/\s+/gu, " ")
+    .trim();
+  return redactFull(normalized).slice(0, 240);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/actions/sandbox/connect.ts` around lines 252 - 276, Update
sanitizeSandboxStartupRecoveryDetail so C0/C1 control characters are removed or
normalized before calling redactFull, ensuring secret-shaped tokens become
contiguous before redaction; preserve the existing whitespace normalization,
trimming, and length limit.
src/lib/actions/sandbox/process-recovery.ts (1)

1150-1195: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the shared OpenShell readiness resolution.

This block and the relaunch readiness block at lines 1831-1852 repeat the same structure: build RecreatedSandboxOpenShellReadyOptions with a beforeProbe managed-health guard, branch on whether the injected impl is the default to pick waitForRecreatedSandboxOpenShellReadyResult, and then map the failure through recreatedSandboxOpenShellReadinessFailureDetail.

The two copies differ only in the guard closure and the captured health detail. Extract one helper that accepts the guard and a health-detail accessor. This keeps the impl-identity branch in a single place.

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

In `@src/lib/actions/sandbox/process-recovery.ts` around lines 1150 - 1195,
Extract the duplicated OpenShell readiness resolution from
managedStartupOpenShellReadinessFailureDetail and the relaunch readiness block
into a shared helper. Have the helper accept the beforeProbe guard and
managed-health-detail accessor, construct RecreatedSandboxOpenShellReadyOptions,
centralize the waitForRecreatedSandboxOpenShellReady versus injected
implementation branch, and map failures through
recreatedSandboxOpenShellReadinessFailureDetail while preserving each caller’s
distinct guard behavior and captured detail.
test/process-recovery-supervisor-relaunch.test.ts (1)

736-741: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Improve the failure output of the per-call assertion.

The .every(...) form collapses six calls into one boolean. On failure Vitest reports only expected false to be true. It does not name which call used the wrong action or the wrong container ID.

Compare the projected tuples instead. The count assertion on Line 736 stays, and a failure then shows the actual action and container ID per call.

♻️ Proposed assertion change
     expect(requestPinnedGatewaySupervisorAction).toHaveBeenCalledTimes(6);
-    expect(
-      requestPinnedGatewaySupervisorAction.mock.calls.every(
-        (call: unknown[]) => call[1] === "probe" && call[3] === "replacement-container-id",
-      ),
-    ).toBe(true);
+    expect(
+      requestPinnedGatewaySupervisorAction.mock.calls.map((call: unknown[]) => [call[1], call[3]]),
+    ).toEqual(Array.from({ length: 6 }, () => ["probe", "replacement-container-id"]));
🤖 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/process-recovery-supervisor-relaunch.test.ts` around lines 736 - 741,
Replace the boolean .every assertion on
requestPinnedGatewaySupervisorAction.mock.calls with an assertion comparing each
call’s projected action and container-ID tuple against the expected tuples,
while retaining the existing call-count assertion. Ensure failures display the
actual values for each call.
test/e2e/live/shields-restart-recovery-evidence.ts (1)

972-1130: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider splitting the restart assertion phases.

expectProtectedStopStartRecovery runs about 160 lines and four distinct verification phases: pre-stop state, post-stop state, post-start state, and managed-control authentication. Each phase already has its own evidence object and assertion group.

Extract assertBeforeStopState, assertStoppedState, and assertAfterStartState helpers that receive the captured StageEvidence. The diagnostics capture and the summary write stay in the orchestrator. This keeps each unit readable without changing behavior or coverage.

🤖 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/e2e/live/shields-restart-recovery-evidence.ts` around lines 972 - 1130,
Split expectProtectedStopStartRecovery into assertBeforeStopState,
assertStoppedState, and assertAfterStartState helpers, each accepting the
relevant StageEvidence and required context needed by its existing assertions.
Move only the pre-stop, post-stop, and post-start assertion groups into those
helpers; keep command execution, diagnostics capture, managed-control
authentication, and summary writing in the orchestrator, preserving behavior and
coverage.
test/e2e/live/shields-config.test.ts (1)

700-722: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Migrate the remaining phase-12 call site to expectProtectedStopStartRecovery. expectStopStartRecovery is still called at test/e2e/live/shields-config.test.ts:1132; delete the local helper after migration.

🤖 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/e2e/live/shields-config.test.ts` around lines 700 - 722, Update the
remaining phase-12 recovery test call site around expectStopStartRecovery to use
expectProtectedStopStartRecovery with the equivalent configuration and
assertions. After all references are migrated, remove the now-unused local
expectStopStartRecovery helper.

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.

Inline comments:
In `@src/lib/actions/sandbox/start.ts`:
- Around line 199-201: Update requiresManagedStartupRecovery to reuse the
authoritative shouldUseManagedStartupRecovery predicate so startup and process
recovery make the same decision for persisted managed agents with custom session
agents and null gateway inspection. Preserve the resulting managed-recovery
behavior and add a regression test covering this mismatch through startSandbox.

---

Nitpick comments:
In `@src/lib/actions/sandbox/connect.ts`:
- Around line 252-276: Update sanitizeSandboxStartupRecoveryDetail so C0/C1
control characters are removed or normalized before calling redactFull, ensuring
secret-shaped tokens become contiguous before redaction; preserve the existing
whitespace normalization, trimming, and length limit.

In `@src/lib/actions/sandbox/process-recovery.ts`:
- Around line 1150-1195: Extract the duplicated OpenShell readiness resolution
from managedStartupOpenShellReadinessFailureDetail and the relaunch readiness
block into a shared helper. Have the helper accept the beforeProbe guard and
managed-health-detail accessor, construct RecreatedSandboxOpenShellReadyOptions,
centralize the waitForRecreatedSandboxOpenShellReady versus injected
implementation branch, and map failures through
recreatedSandboxOpenShellReadinessFailureDetail while preserving each caller’s
distinct guard behavior and captured detail.

In `@src/lib/shields/index.ts`:
- Around line 2633-2655: Add test coverage for the pinned-container path through
startSandbox, verifying that result.runtimeHandle is propagated by
processRecovery into restoreStoppedSandboxStartupState and ultimately passed as
expectedContainerId to restoreLockedStartupAccess. Extend the existing
restoration-bridge mock assertions while preserving the current undefined-case
coverage.

In `@test/e2e/live/shields-config.test.ts`:
- Around line 700-722: Update the remaining phase-12 recovery test call site
around expectStopStartRecovery to use expectProtectedStopStartRecovery with the
equivalent configuration and assertions. After all references are migrated,
remove the now-unused local expectStopStartRecovery helper.

In `@test/e2e/live/shields-restart-recovery-evidence.ts`:
- Around line 972-1130: Split expectProtectedStopStartRecovery into
assertBeforeStopState, assertStoppedState, and assertAfterStartState helpers,
each accepting the relevant StageEvidence and required context needed by its
existing assertions. Move only the pre-stop, post-stop, and post-start assertion
groups into those helpers; keep command execution, diagnostics capture,
managed-control authentication, and summary writing in the orchestrator,
preserving behavior and coverage.

In `@test/process-recovery-supervisor-relaunch.test.ts`:
- Around line 736-741: Replace the boolean .every assertion on
requestPinnedGatewaySupervisorAction.mock.calls with an assertion comparing each
call’s projected action and container-ID tuple against the expected tuples,
while retaining the existing call-count assertion. Ensure failures display the
actual values for each call.
🪄 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: 9a2ac76e-eaab-40ec-9f1d-ecd9b2c7416f

📥 Commits

Reviewing files that changed from the base of the PR and between 5e81fe9 and 271f26b.

📒 Files selected for processing (23)
  • docs/manage-sandboxes/recover-rebuild-sandboxes.mdx
  • docs/manage-sandboxes/run-sandboxes.mdx
  • docs/reference/commands.mdx
  • src/lib/actions/sandbox/connect-flow.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/docker-health.test.ts
  • src/lib/actions/sandbox/forward-recovery.ts
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/start.test.ts
  • src/lib/actions/sandbox/start.ts
  • src/lib/actions/sandbox/stop.test.ts
  • src/lib/onboard/docker-driver-sandbox-recovery.test.ts
  • src/lib/onboard/docker-driver-sandbox-recovery.ts
  • src/lib/onboard/runtime-provider/contract.ts
  • src/lib/onboard/runtime-provider/docker.ts
  • src/lib/onboard/runtime-provider/podman.test.ts
  • src/lib/shields/index.ts
  • src/lib/shields/startup-access.test.ts
  • test/e2e/live/hermes-shields-config.test.ts
  • test/e2e/live/shields-config.test.ts
  • test/e2e/live/shields-restart-recovery-evidence.ts
  • test/process-recovery-supervisor-relaunch.test.ts

Comment thread src/lib/actions/sandbox/start.ts Outdated
Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>

@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

🤖 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/start.ts`:
- Around line 263-268: Update the pinnedManagedStartupRecovery selection in the
startup flow to pass preserveContainer: true, then fail startup before
verifyStarted when managed recovery is selected but result.runtimeHandle is
absent. Preserve the existing managed identity checks for valid handles, and add
a regression test covering a managed OpenClaw or Hermes sandbox without a
runtime handle.
🪄 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: bfadb2b6-cdba-4390-b573-a7b0174f6d09

📥 Commits

Reviewing files that changed from the base of the PR and between 271f26b and c73beb9.

📒 Files selected for processing (5)
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/start.test.ts
  • src/lib/actions/sandbox/start.ts
  • test/process-recovery-supervisor-relaunch.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/process-recovery-supervisor-relaunch.test.ts
  • src/lib/actions/sandbox/start.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/process-recovery.ts

Comment thread src/lib/actions/sandbox/start.ts
Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: souvikDevloper <138186578+souvikDevloper@users.noreply.github.com>
@souvikDevloper

Copy link
Copy Markdown
Contributor Author

@cv can i get the ci now

1 similar comment
@souvikDevloper

Copy link
Copy Markdown
Contributor Author

@cv can i get the ci now

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.

Shields-up stop/start regression leaves OpenClaw and Hermes sandboxes unready

2 participants