Skip to content

fix(sandbox): honor recovery wait override - #7897

Closed
deepujain wants to merge 4 commits into
NVIDIA:mainfrom
deepujain:fix/7893-recovery-wait-precedence
Closed

fix(sandbox): honor recovery wait override#7897
deepujain wants to merge 4 commits into
NVIDIA:mainfrom
deepujain:fix/7893-recovery-wait-precedence

Conversation

@deepujain

@deepujain deepujain commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Managed recovery now applies NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS
consistently to both gateway-health and recreated-sandbox readiness waits.
The two recreate-readiness production paths use the shared 120-second default
instead of bypassing it with the unrelated 180-second onboarding budget.

Related Issue

Fixes #7893

Changes

  • Give the operator recovery-wait override precedence over an explicit internal
    timeout in both recovery wait functions.
  • Remove the explicit sandbox-readiness timeout from onboarding finalization and
    supervisor relaunch readiness checks.
  • Cover override precedence and the production supervisor call shape with
    regression tests.
  • Document the 120-second managed-recovery default and its environment override.
  • Lower the measured source fan-out budget after removing the unused dependency.

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: Codex Desktop reviewed operator-override precedence, both production recreate-readiness call sites, zero-value handling, managed-health pinning, and the unchanged fail-closed readiness result.
  • 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: Reviewed the recovery timeout table, command reference, and rebuild recovery guidance against the implementation. The pages consistently describe the 120-second default, operator override precedence, and separation from onboarding readiness.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit: Not applicable
  • 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 src/lib/actions/sandbox/process-recovery.test.ts src/lib/onboard/finalization-deps.test.ts test/process-recovery-supervisor-relaunch.test.ts (57 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 was bounded after approximately 7 minutes; the focused production-path integration and required equivalent gates 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) — result: passed with 0 errors and 2 existing Fern warnings.
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Additional exact-head evidence:

  • npm run validate:pr: passed.
  • npm run build:cli: passed.
  • npm run typecheck:cli: passed.
  • npm run lint: passed.
  • npm run docs: passed with 0 errors.
  • git diff --check: passed.
  • E2E-equivalent: the production supervisor relaunch regression proves its
    recreated-readiness call omits the bypassing timeout, while the direct
    readiness regression proves an operator override replaces an explicit
    internal budget.

Signed-off-by: Deepak Jain deepujain@gmail.com

Summary by CodeRabbit

  • New Features
    • Added/extended NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS to control the recovery wall-clock wait for gateway health and OpenShell re-registration, with override precedence over NEMOCLAW_SANDBOX_READY_TIMEOUT.
    • During transactional rebuild recover, the system waits 120 seconds by default before starting the primary dashboard/API forwarding.
  • Documentation
    • Refined timeout guidance: NEMOCLAW_SANDBOX_READY_TIMEOUT now applies only to post-create readiness; added clearer recovery examples and when to set the gateway recovery wait variable.
  • Bug Fixes
    • Recreated-sandbox readiness timing now consistently honors the gateway recovery wait override.
  • Tests
    • Updated readiness-budget/probing expectations to reflect the new override behavior.
  • Chores
    • Minor CI architecture budget adjustment.

@copy-pr-bot

copy-pr-bot Bot commented Jul 30, 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 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

Sandbox recovery now applies NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS to recreated-sandbox readiness, uses conditional managed health probing, updates delegation and tests, and documents the revised timeout behavior.

Changes

Sandbox recovery readiness

Layer / File(s) Summary
Recovery timeout resolution
src/lib/actions/sandbox/process-recovery.ts, ci/source-architecture-budget.json
Recreated-sandbox readiness now resolves its timeout through NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS, and the architecture budget is reduced from 22 to 21.
Managed relaunch wiring and validation
src/lib/onboard/finalization-deps.ts, src/lib/onboard/finalization-deps.test.ts, src/lib/actions/sandbox/process-recovery.ts, src/lib/actions/sandbox/process-recovery.test.ts, test/process-recovery-supervisor-relaunch.test.ts
Finalization uses a shared lazy loader, managed relaunch conditionally supplies beforeProbe, and tests verify timeout precedence and readiness options.
Timeout documentation updates
docs/inference/configure-inference-timeouts.mdx, docs/manage-sandboxes/recover-rebuild-sandboxes.mdx, docs/reference/commands.mdx
Documentation describes recovery timeout scope, the 120-second wait, override precedence, and recovery command usage.

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

Sequence Diagram(s)

sequenceDiagram
  participant FinalizationHandler
  participant ProcessRecovery
  participant ManagedHealth
  participant OpenShell
  FinalizationHandler->>ProcessRecovery: invoke recreated-sandbox readiness
  ProcessRecovery->>ManagedHealth: run conditional beforeProbe
  ManagedHealth-->>ProcessRecovery: return health result
  ProcessRecovery->>OpenShell: probe OpenShell re-registration
Loading

Possibly related PRs

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

Suggested reviewers: cv, prekshivyas

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: honoring the recovery wait override in sandbox recovery.
Linked Issues check ✅ Passed The PR routes recovery waits through the shared env override and removes the explicit 180s onboarding timeout from recreated-sandbox readiness paths.
Out of Scope Changes check ✅ Passed The changes are limited to recovery timing logic, related docs/tests, and a budget update tied to the refactor; no unrelated scope is evident.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/actions/sandbox/process-recovery.ts (1)

1321-1321: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not turn an absent health guard into an inconclusive guard.

null causes the readiness loop to skip the OpenShell probe and wait again (Lines 756-765). When confirmRelaunchedManagedHealth is unavailable, this callback always returns null, so managed relaunch can never execute the readiness probe and eventually times out. Omit beforeProbe when the confirmer is absent, and add a regression test for that path.

Suggested fix
-            beforeProbe: (timeoutMs) => confirmRelaunchedManagedHealth?.(timeoutMs) ?? null,
+            ...(confirmRelaunchedManagedHealth
+              ? { beforeProbe: (timeoutMs) => confirmRelaunchedManagedHealth(timeoutMs) }
+              : {}),
🤖 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` at line 1321, Update the managed
relaunch setup around beforeProbe so the callback is only provided when
confirmRelaunchedManagedHealth is available; do not return null for the
absent-confirmation case. Preserve the existing timeout behavior when the
confirmer exists, and add a regression test covering readiness proceeding
without beforeProbe.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard/finalization-deps.ts`:
- Line 13: Keep the timeout behavior in finalization-deps.ts unchanged. Update
docs/inference/configure-inference-timeouts.mdx and docs/reference/commands.mdx
so post-policy OpenShell re-registration is documented under
NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS, with the 120-second default, rather than
NEMOCLAW_SANDBOX_READY_TIMEOUT.

---

Outside diff comments:
In `@src/lib/actions/sandbox/process-recovery.ts`:
- Line 1321: Update the managed relaunch setup around beforeProbe so the
callback is only provided when confirmRelaunchedManagedHealth is available; do
not return null for the absent-confirmation case. Preserve the existing timeout
behavior when the confirmer exists, and add a regression test covering readiness
proceeding without beforeProbe.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3ff89923-9f58-4083-ba9e-0161cb04487f

📥 Commits

Reviewing files that changed from the base of the PR and between 4dcb89e and 6fe6ed6.

📒 Files selected for processing (8)
  • ci/source-architecture-budget.json
  • docs/inference/configure-inference-timeouts.mdx
  • docs/manage-sandboxes/recover-rebuild-sandboxes.mdx
  • docs/reference/commands.mdx
  • src/lib/actions/sandbox/process-recovery.test.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/onboard/finalization-deps.ts
  • test/process-recovery-supervisor-relaunch.test.ts

Comment thread src/lib/onboard/finalization-deps.ts Outdated
@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 · medium confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed after a partial review · low confidence · 1 blocker · 2 warnings · 0 suggestions

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

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

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

Workflow run details

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

@deepujain

Copy link
Copy Markdown
Contributor Author

Addressed both review findings in 95a4c71. The health guard is now omitted defensively when unavailable, and the timeout docs match the finalization path.

@deepujain

Copy link
Copy Markdown
Contributor Author

Added the advisor-requested onboarding adapter regression in 40ecdc5. It verifies both timeout env vars still delegate to the recovery helper without an explicit timeout; focused coverage is now 57/57.

@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/onboard/finalization-deps.test.ts`:
- Around line 18-28: Update the test to exercise the exported
finalizationHandlerDeps.waitForSandboxControlPlaneReady through a
module-boundary mock rather than calling a separately created factory instance.
Ensure the mocked recovery helper reads the configured environment variables and
assert the effective timeout resolution, including override precedence, while
still verifying the sandbox identifier is forwarded.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8834fb41-b8df-4ef8-a01c-d4b6ae8811ff

📥 Commits

Reviewing files that changed from the base of the PR and between 95a4c71 and 40ecdc5.

📒 Files selected for processing (2)
  • src/lib/onboard/finalization-deps.test.ts
  • src/lib/onboard/finalization-deps.ts

Comment thread src/lib/onboard/finalization-deps.test.ts
@deepujain
deepujain force-pushed the fix/7893-recovery-wait-precedence branch from f40bf42 to ac797e3 Compare July 30, 2026 15:25
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased onto current main. Focused tests and npm run validate:pr pass; all commits remain verified.

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
@deepujain
deepujain force-pushed the fix/7893-recovery-wait-precedence branch from ac797e3 to 1c08080 Compare July 31, 2026 06:11
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and resolved the recovery-doc conflict. Recovery, finalization, and PR validation all pass.

@wscurran wscurran added area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression labels Jul 31, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for the PR. This fixes sandbox recovery wait behavior by honoring the NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS override consistently across gateway-health and recreated-sandbox readiness waits. Maintainers will review the override precedence logic, test coverage, and documentation updates.


Related open issues:


Related open issues:

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Superseded by #8182.

The replacement carries the same effective recovery-timeout behavior on current main, preserves Deepak Jain as the commit author with the original DCO declaration, and adds the maintainer DCO declaration and verified signature. Its local validation passed 77 focused tests, CLI build and type checking, repository checks, documentation validation, the independent documentation review, and the pre-commit security scan.

The original fork branch could not accept a normal current-main merge commit because the local security scan evaluated an unrelated test fixture inherited from main. No security control was bypassed. #8182 must still pass every remote gate and required review before merge.

senthilr-nv pushed a commit that referenced this pull request Aug 4, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Managed recovery now applies `NEMOCLAW_GATEWAY_RECOVERY_WAIT_SECONDS`
consistently to gateway-health and recreated-sandbox readiness waits. A
valid operator override takes precedence over the caller's internal
budget.
Without one, OpenClaw gateway health uses 30 seconds, Hermes gateway
health uses
90 seconds, and recreated-sandbox OpenShell registration uses 120
seconds when
no other budget is supplied.

This preserves Deepak Jain as the commit author while refreshing the
effective
change from #7897 onto current `main`. The original fork branch could
not accept
a normal merge commit because the local secret scan evaluated an
unrelated test
fixture inherited from `main`; no security check was bypassed.

## Related Issue

Fixes #7893
Supersedes #7897 with the same effective behavior on current `main`.

## Changes

- Give the recovery-wait environment override precedence over internal
timeout
  values.
- Remove the unrelated onboarding-readiness timeout from the two managed
  recreation paths.
- Preserve readiness-before-commit ordering, immediate managed-health
failure,
  rollback behavior, and the stopped primary forward after failure.
- Cover override precedence and production call shapes with regression
tests.
- Document the distinct parser contracts and command timing for
onboarding and
  recovery settings.
- Lower the measured source fan-out budget after removing the unused
dependency.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Codex Desktop completed
a fresh nine-category security review of the nine-file pull-request diff
at current branch revision `379fead30`: PASS in all categories with no
findings. The current-main merge preserved the reviewed patch and
accepted behavior. Recovery-wait input remains finite and nonnegative,
the managed-health identity guard still runs before every readiness
probe, failures remain fail-closed with rollback before any primary
forward starts, no command or credential boundary changed, and no
dependency was added. Gitleaks and private-key scans passed; 57 focused
CLI tests and 20 focused integration tests passed.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue: No exception requested;
all required checks must pass.

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: Reviewed `docs/inference/configure-inference-timeouts.mdx`,
`docs/manage-sandboxes/recover-rebuild-sandboxes.mdx`, and
`docs/reference/commands.mdx` against current main, the recovery and
onboarding-finalization implementations, focused tests, and the OpenClaw
and Hermes manifests. Confirmed the 30-second OpenClaw health, 90-second
Hermes health, and 120-second recreated-sandbox OpenShell registration
fallbacks; finite nonnegative override precedence with fractional values
preserved; immediate definitive managed-health failure; rollback
behavior; and the stopped primary forward after failure. Fresh
verification passed: 57 CLI tests, 20 integration tests, `npm run
typecheck:cli`, `npm run typecheck`, test-title style, diff validation,
and generated OpenClaw, Hermes, and Deep Agents variants. `npm run docs`
completed with 0 errors and 2 warnings. The worktree remained clean.
- Agent: Codex Desktop documentation writer subagent
<!-- docs-review-head-sha: 379fead -->
<!-- docs-review-agents-blob-sha: 3dd7c24 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested revision: Not applicable
- Station profile/scenario: Not applicable
- Result: Not applicable
- Supporting evidence: Not applicable

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed
- [x] Targeted behavior tests pass for the current change set — 77 tests
passed across process recovery, finalization dependencies, and
supervisor relaunch coverage
- [x] Applicable broad gate passed — `npm run checks:repository` passed
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — passed
with 0 errors and 2 existing warnings
- [x] Doc pages follow the style guide (doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Additional validation:

- `npm run build:cli`: passed
- `npm run typecheck:cli`: passed
- `git diff --check`: passed
- Pre-commit secret scan: passed

---

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


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

* **Bug Fixes**
* Improved sandbox recovery with a dedicated gateway re-registration
timeout.
* Recovery failures now roll back cleanly while keeping the primary
dashboard or API stopped.
* Explicit recovery timeout settings override default readiness limits.
* Improved timeout validation, including fractional values and fallback
handling.

* **Documentation**
* Added configuration guidance, command examples, and phase-specific
recovery timeout defaults.
* Clarified sandbox recreation, onboarding readiness, and recovery
behavior.

* **Tests**
* Expanded coverage for timeout selection, delegation, and sandbox
readiness behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Deepak Jain <deepujain@gmail.com>
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(sandbox): the recreate readiness-wait default and its env override do not reach the paths they target

3 participants