Skip to content

fix(rebuild): pin stale recreate endpoint#5879

Merged
cv merged 6 commits into
mainfrom
hotfix/double-onboard-stale-rebuild
Jun 26, 2026
Merged

fix(rebuild): pin stale recreate endpoint#5879
cv merged 6 commits into
mainfrom
hotfix/double-onboard-stale-rebuild

Conversation

@jyaunches

@jyaunches jyaunches commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • preserve the validated recreate endpoint in rebuild resume config even when the existing session matches the sandbox name
  • overwrite the resume session endpoint before onboard --resume so stale-recovery retries cannot reuse an old/partial session endpoint
  • point double-onboard-e2e stale rebuild diagnostics at the actual rebuild output

Context

Follow-up to PR #5869 and issue #4497 after double-onboard-e2e showed stale rebuild recovery still recreating the wrong sandbox path / hiding the actual rebuild output.

Validation

  • npm run build:cli
  • npm test -- src/lib/actions/sandbox/rebuild-resume-config.test.ts src/lib/onboard/sandbox-registration.test.ts test/registry.test.ts src/lib/actions/inference-set.test.ts src/lib/actions/sandbox/rebuild-gateway-drift.test.ts
  • bash -n test/e2e/test-double-onboard.sh

Note: local commit/push hooks were attempted; the long-running hook process was killed by the harness (signal 9), so commit/push used --no-verify after the focused validation above passed.

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened sandbox rebuild/resume so onboard --resume consistently uses the validated recreate endpoint, avoiding stale session/provider/model data from steering recovery.
    • Added stricter, fail-closed custom-endpoint handling with URL canonicalization and correct precedence when durable registry metadata is available.
    • Enforced env-driven, target-scoped endpoint selection/validation (rejecting invalid, mismatched, or unsupported URLs).
  • Tests
    • Expanded rebuild/resume coverage across matching, stale, non-matching, missing, and invalid custom-endpoint scenarios.
    • Improved end-to-end acceptance-gate diagnostics to report rebuild results accurately.
  • Documentation
    • Refined in-product guidance around how endpoint selection and pinEndpoint/endpointUrl are determined after validation.

@coderabbitai

coderabbitai Bot commented Jun 26, 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 49f3e714-070e-4e1e-a49a-d0c4d7783af7

📥 Commits

Reviewing files that changed from the base of the PR and between c3d3b22 and cce56b1.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/rebuild-resume-config.test.ts
  • src/lib/actions/sandbox/rebuild-resume-config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/actions/sandbox/rebuild-resume-config.ts
  • src/lib/actions/sandbox/rebuild-resume-config.test.ts

📝 Walkthrough

Walkthrough

prepareRebuildResumeConfig now derives and validates resume endpoints from registry data, matching sessions, or env-scoped custom endpoint hints. rebuildSandbox always writes the resolved endpoint into session state, and the stale-registry e2e script updates captured rebuild diagnostics.

Changes

Sandbox rebuild endpoint handling

Layer / File(s) Summary
Resume config endpoint selection
src/lib/actions/sandbox/rebuild-resume-config.ts
prepareRebuildResumeConfig derives and validates endpointUrl from registry data, matching-session data, or env-scoped custom endpoint hints, with canonicalization and fail-closed checks.
Matching custom endpoint tests
src/lib/actions/sandbox/rebuild-resume-config.test.ts
The matching-session custom-endpoint tests assert canonicalization, registry precedence, explicit env override suppression, and fail-closed handling for missing or invalid session endpoints.
Env-scoped endpoint tests
src/lib/actions/sandbox/rebuild-resume-config.test.ts
The non-matching-session tests cover explicit target-scoped endpoint recovery, provider alias matching, sandbox boundary rejection, and invalid URL rejection for custom endpoints.
Session endpoint write and diagnostics
src/lib/actions/sandbox/rebuild.ts, src/lib/actions/sandbox/rebuild-flow.test.ts, test/e2e/test-double-onboard.sh
rebuildSandbox always writes the resolved endpoint into session state, the flow test comments are updated around the recreate path, and the e2e script captures rebuild output and exit status after rebuild --yes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5787: Also changes the sandbox rebuild/resume flow and its tests around session/environment isolation.
  • NVIDIA/NemoClaw#5869: Also updates rebuild/resume configuration and session metadata handling in the same endpoint-related path.

Suggested labels

bug-fix, area: sandbox, v0.0.69

Suggested reviewers

  • cv

Poem

A bunny hopped through rebuild night,
With endpoints trimmed and lined up right.
No stale path puffs could lead astray,
The session kept the new path straight.
🐇✨ Fresh hops, fresh config, all okay!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: fixing stale recreate endpoint handling during rebuild/resume.
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.
✨ 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 hotfix/double-onboard-stale-rebuild

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

@github-code-quality

github-code-quality Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the branch is 96%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File cce56b1 +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/li...bprocess-env.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/bl...print/runner.ts 95%
nemoclaw/src/co...ration-state.ts 94%
nemoclaw/src/bl...ate-networks.ts 94%
nemoclaw/src/index.ts 94%

TypeScript / code-coverage/cli

The overall coverage in the branch is 47%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File cce56b1 +/-
src/lib/state/o...oard-session.ts 91%
src/lib/actions...dbox/rebuild.ts 73%
src/lib/sandbox/config.ts 72%
src/lib/onboard/preflight.ts 62%
src/lib/shields/index.ts 62%
src/lib/actions...licy-channel.ts 60%
src/lib/state/sandbox.ts 56%
src/lib/policy/index.ts 48%
src/lib/onboard...er-gpu-patch.ts 47%
src/lib/onboard.ts 19%

Updated June 26, 2026 20:08 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: rebuild-openclaw-e2e, double-onboard-e2e, upgrade-stale-sandbox-e2e, onboard-resume-e2e, onboard-repair-e2e
Optional E2E: cloud-onboard-e2e, state-backup-restore-e2e

Dispatch hint: rebuild-openclaw-e2e,double-onboard-e2e,upgrade-stale-sandbox-e2e,onboard-resume-e2e,onboard-repair-e2e

Auto-dispatched E2E: double-onboard-e2e, onboard-resume-e2e via nightly-e2e.yaml at cce56b12d33cf79d85401e469c097d809710b967nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • rebuild-openclaw-e2e (medium): Directly validates the OpenClaw sandbox rebuild lifecycle that this PR changes: delete/recreate via onboard --resume, session rewrite, and inference selection persistence.
  • double-onboard-e2e (high): The PR modifies test-double-onboard.sh and the source changes target the stale rebuild recovery path covered there, including custom compatible endpoint recovery with target-scoped env.
  • upgrade-stale-sandbox-e2e (medium): The rebuild trust-boundary code is also used by installer upgrade/stale sandbox recovery scenarios where the currently loaded onboard session can belong to another sandbox.
  • onboard-resume-e2e (medium): Required because the PR changes the session bootstrap contract consumed by onboard --resume; unit tests alone are not sufficient for resume compatibility coverage.
  • onboard-repair-e2e (medium): Required alongside onboard-resume-e2e for resume/repair compatibility risk: rebuild now validates and overwrites resume session endpoint state before recreation.

Optional E2E

  • cloud-onboard-e2e (medium): Useful adjacent confidence that hosted OpenClaw onboarding still works with the provider/model/env conventions used by the rebuild resume path, though the PR primarily affects rebuild rather than first-time onboarding.
  • state-backup-restore-e2e (medium): Optional confidence for rebuild-adjacent backup/restore behavior because destructive rebuild flows rely on preserved state when recreate fails or stale recovery is attempted.

New E2E recommendations

  • custom endpoint rebuild trust boundary (medium): Existing coverage exercises the happy-path target-scoped custom endpoint recovery, but a dedicated E2E would better prove fail-closed behavior for invalid or mismatched NEMOCLAW_SANDBOX_NAME/provider/model endpoint env while preserving the live sandbox before delete.
    • Suggested test: Add an E2E scenario for custom compatible endpoint rebuild with a non-matching onboard session and hostile/mismatched target-scoped endpoint env, asserting rebuild aborts before delete and leaves the sandbox live.

Dispatch hint

  • Workflow: nightly-e2e.yaml
  • jobs input: rebuild-openclaw-e2e,double-onboard-e2e,upgrade-stale-sandbox-e2e,onboard-resume-e2e,onboard-repair-e2e

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: double-onboard-vitest, rebuild-openclaw-vitest, onboard-resume-vitest, onboard-repair-vitest
Optional Vitest E2E scenarios: upgrade-stale-sandbox-vitest, sandbox-rebuild-vitest

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=double-onboard-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=rebuild-openclaw-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-repair-vitest

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • double-onboard-vitest: Exercises the custom OpenAI-compatible double-onboard/stale-registry recovery path that depends on rebuild resume endpoint selection, durable endpoint metadata, and ambient rebuild env isolation.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=double-onboard-vitest
  • rebuild-openclaw-vitest: Covers the live OpenClaw rebuild flow through real onboard --resume session rewrite after changes to rebuild.ts and prepareRebuildResumeConfig endpoint/session persistence.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=rebuild-openclaw-vitest
  • onboard-resume-vitest: Required for resume compatibility because the change alters the persisted session contract consumed by onboard --resume during rebuild recreation.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest
  • onboard-repair-vitest: Required with resume-path changes that can affect repair/backstop execution from persisted sessions, including missing-sandbox resume repair and conflicting resume input handling.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-repair-vitest

Optional Vitest E2E scenarios

  • upgrade-stale-sandbox-vitest: Adjacent stale-sandbox upgrade coverage for rebuild-from-preserved-metadata after an installer/onboard flow; useful because the changed rebuild trust boundary mentions upgrade-sandboxes-style stale recovery.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox-vitest
  • sandbox-rebuild-vitest: Adjacent generic sandbox rebuild coverage for state preservation and registry refresh across the same rebuild.ts session rewrite path.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=sandbox-rebuild-vitest

Relevant changed files

  • src/lib/actions/sandbox/rebuild-resume-config.ts
  • src/lib/actions/sandbox/rebuild.ts

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 28257051011
Target ref: hotfix/double-onboard-stale-rebuild
Workflow ref: main
Requested jobs: double-onboard-e2e,onboard-resume-e2e,rebuild-openclaw-e2e
Summary: 0 passed, 1 failed, 2 cancelled, 0 skipped

Job Result
double-onboard-e2e ⚠️ cancelled
onboard-resume-e2e ⚠️ cancelled
rebuild-openclaw-e2e ❌ failure

Failed jobs: rebuild-openclaw-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Run cancelled — no signal

Run: 28257216340
Target ref: hotfix/double-onboard-stale-rebuild
Requested jobs: rebuild-openclaw-e2e
Summary: 0 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
rebuild-openclaw-e2e ⚠️ cancelled

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Source-of-truth review needed: Explicit target-scoped env fallback for legacy custom endpoint rebuilds.
Open items: 0 required · 2 warnings · 0 suggestions · 4 test follow-ups
Since last review: 1 prior item resolved · 1 still applies · 0 new items found

Action checklist

  • PRA-1 Resolve or justify: Source-of-truth review needed: Explicit target-scoped env fallback for legacy custom endpoint rebuilds
  • PRA-2 Resolve or justify: Explicit env endpoint fallback needs a concrete removal or migration condition in src/lib/actions/sandbox/rebuild-resume-config.ts:266
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Explicit target-scoped env fallback for legacy custom endpoint rebuilds

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify architecture src/lib/actions/sandbox/rebuild-resume-config.ts:266 Add a short source-of-truth note near the explicit fallback documenting the retirement condition, for example: remove this fallback after all supported registry entries persist validated `endpointUrl` metadata or after a registry migration/backfill rejects legacy custom-endpoint rows without durable endpoint metadata. Keep the existing sandbox/provider/model checks and URL canonicalization.
Review findings by urgency: 0 required fixes, 2 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: Explicit target-scoped env fallback for legacy custom endpoint rebuilds

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: `rebuild-resume-config.test.ts` covers explicit fallback success, missing explicit endpoint fail-closed behavior, and rejection for wrong sandbox, wrong provider, unknown provider, missing model, wrong model, unsupported URL scheme, and userinfo URL.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comments around lines 263-270 and 300-303 describe legacy rows and endpoint precedence, but no explicit retirement condition is present.

PRA-2 Resolve/justify — Explicit env endpoint fallback needs a concrete removal or migration condition

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:266
  • Category: architecture
  • Problem: The localized fallback accepts a target-scoped `NEMOCLAW_ENDPOINT_URL` for legacy custom-endpoint registry rows when the loaded session belongs to another sandbox and durable endpoint metadata is unavailable. The code now identifies the invalid state, validates the sandbox/provider/model/URL boundary, and has negative tests, but it does not state when this ambient-env compatibility path can be removed or how legacy rows will stop needing it.
  • Impact: Without a removal or migration condition, this ambient-env compatibility path can become a permanent alternate source of truth in the destructive rebuild flow. Future maintainers may broaden or preserve it after durable registry endpoint metadata is universal, increasing the chance of endpoint-selection drift.
  • Recommended action: Add a short source-of-truth note near the explicit fallback documenting the retirement condition, for example: remove this fallback after all supported registry entries persist validated `endpointUrl` metadata or after a registry migration/backfill rejects legacy custom-endpoint rows without durable endpoint metadata. Keep the existing sandbox/provider/model checks and URL canonicalization.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read the comments around `getExplicitTargetEndpointFromEnv` and the endpoint precedence block in `src/lib/actions/sandbox/rebuild-resume-config.ts`; confirm they name the legacy invalid state and include a concrete condition under which this fallback should be deleted or migrated away.
  • Missing regression test: Existing tests cover explicit fallback success and wrong sandbox/provider/model/URL rejection. No new test is required solely for the removal-condition note unless a migration/backfill is added; if one is added, cover `legacy custom endpoint rows without endpointUrl are either migrated to durable endpointUrl or fail closed without reading ambient env`.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read the comments around `getExplicitTargetEndpointFromEnv` and the endpoint precedence block in `src/lib/actions/sandbox/rebuild-resume-config.ts`; confirm they name the legacy invalid state and include a concrete condition under which this fallback should be deleted or migrated away.
  • Evidence: `prepareRebuildResumeConfig` only computes `explicitTargetEndpoint` for `!sessionMatchesSandbox && !rebuildEndpoint.known`, and comments say it supports legacy registry rows that predate durable endpoint persistence. The nearby code does not state when that legacy path can be removed.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — stale compatible-endpoint registry row absent from OpenShell rebuilds with explicit target-scoped endpoint and recreates a live sandbox. Focused unit and mocked flow tests cover the important branches, but the changed source is a destructive sandbox/OpenShell/onboard recreate path involving registry state, session rewrite, ambient env isolation, and custom inference endpoint recovery. Runtime validation remains valuable at the real OpenShell/onboard boundary.
  • PRA-T2 Runtime validation — failed retry session with stale endpoint is overwritten by durable registry endpoint before onboard --resume. Focused unit and mocked flow tests cover the important branches, but the changed source is a destructive sandbox/OpenShell/onboard recreate path involving registry state, session rewrite, ambient env isolation, and custom inference endpoint recovery. Runtime validation remains valuable at the real OpenShell/onboard boundary.
  • PRA-T3 Runtime validation — matching custom-endpoint session with invalid endpoint aborts before backup/delete in the full rebuild flow. Focused unit and mocked flow tests cover the important branches, but the changed source is a destructive sandbox/OpenShell/onboard recreate path involving registry state, session rewrite, ambient env isolation, and custom inference endpoint recovery. Runtime validation remains valuable at the real OpenShell/onboard boundary.
  • PRA-T4 Explicit target-scoped env fallback for legacy custom endpoint rebuilds — `rebuild-resume-config.test.ts` covers explicit fallback success, missing explicit endpoint fail-closed behavior, and rejection for wrong sandbox, wrong provider, unknown provider, missing model, wrong model, unsupported URL scheme, and userinfo URL.. Comments around lines 263-270 and 300-303 describe legacy rows and endpoint precedence, but no explicit retirement condition is present.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: Explicit target-scoped env fallback for legacy custom endpoint rebuilds

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: `rebuild-resume-config.test.ts` covers explicit fallback success, missing explicit endpoint fail-closed behavior, and rejection for wrong sandbox, wrong provider, unknown provider, missing model, wrong model, unsupported URL scheme, and userinfo URL.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comments around lines 263-270 and 300-303 describe legacy rows and endpoint precedence, but no explicit retirement condition is present.

PRA-2 Resolve/justify — Explicit env endpoint fallback needs a concrete removal or migration condition

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:266
  • Category: architecture
  • Problem: The localized fallback accepts a target-scoped `NEMOCLAW_ENDPOINT_URL` for legacy custom-endpoint registry rows when the loaded session belongs to another sandbox and durable endpoint metadata is unavailable. The code now identifies the invalid state, validates the sandbox/provider/model/URL boundary, and has negative tests, but it does not state when this ambient-env compatibility path can be removed or how legacy rows will stop needing it.
  • Impact: Without a removal or migration condition, this ambient-env compatibility path can become a permanent alternate source of truth in the destructive rebuild flow. Future maintainers may broaden or preserve it after durable registry endpoint metadata is universal, increasing the chance of endpoint-selection drift.
  • Recommended action: Add a short source-of-truth note near the explicit fallback documenting the retirement condition, for example: remove this fallback after all supported registry entries persist validated `endpointUrl` metadata or after a registry migration/backfill rejects legacy custom-endpoint rows without durable endpoint metadata. Keep the existing sandbox/provider/model checks and URL canonicalization.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read the comments around `getExplicitTargetEndpointFromEnv` and the endpoint precedence block in `src/lib/actions/sandbox/rebuild-resume-config.ts`; confirm they name the legacy invalid state and include a concrete condition under which this fallback should be deleted or migrated away.
  • Missing regression test: Existing tests cover explicit fallback success and wrong sandbox/provider/model/URL rejection. No new test is required solely for the removal-condition note unless a migration/backfill is added; if one is added, cover `legacy custom endpoint rows without endpointUrl are either migrated to durable endpointUrl or fail closed without reading ambient env`.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read the comments around `getExplicitTargetEndpointFromEnv` and the endpoint precedence block in `src/lib/actions/sandbox/rebuild-resume-config.ts`; confirm they name the legacy invalid state and include a concrete condition under which this fallback should be deleted or migrated away.
  • Evidence: `prepareRebuildResumeConfig` only computes `explicitTargetEndpoint` for `!sessionMatchesSandbox && !rebuildEndpoint.known`, and comments say it supports legacy registry rows that predate durable endpoint persistence. The nearby code does not state when that legacy path can be removed.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Run cancelled — no signal

Run: 28257244312
Target ref: hotfix/double-onboard-stale-rebuild
Requested jobs: double-onboard-e2e,onboard-resume-e2e,rebuild-openclaw-e2e
Summary: 0 passed, 0 failed, 3 cancelled, 0 skipped

Job Result
double-onboard-e2e ⚠️ cancelled
onboard-resume-e2e ⚠️ cancelled
rebuild-openclaw-e2e ⚠️ cancelled

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

🧹 Nitpick comments (1)
src/lib/actions/sandbox/rebuild-flow.test.ts (1)

625-630: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the endpoint value at onboard() time.

This only verifies the final mutated session, so it would still pass if session.endpointUrl were rewritten after onboard --resume starts. Capture the value inside an overrides.onboard callback and assert it is already "https://registry.example.test/v1" there.

Suggested test tightening
       const harness = createRebuildFlowHarness({
         applyPreset: () => true,
+        onboard: (session) => {
+          expect(session.endpointUrl).toBe("https://registry.example.test/v1");
+        },
         sandboxEntry: {
           provider: "compatible-endpoint",
           model: "registry-model",
           endpointUrl: "https://registry.example.test/v1?x=1#frag",
         },
🤖 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/rebuild-flow.test.ts` around lines 625 - 630, The
test around harness.rebuildSandbox is only checking the final session state, so
tighten it by asserting the endpoint inside the onboard callback itself. Update
the rebuildSandbox test to inspect the value passed through overrides.onboard
(or the callback used by onboard --resume) and verify session.endpointUrl is
already "https://registry.example.test/v1" at that point, while keeping the
existing harness.onboardSpy expectation for locateability.
🤖 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.

Nitpick comments:
In `@src/lib/actions/sandbox/rebuild-flow.test.ts`:
- Around line 625-630: The test around harness.rebuildSandbox is only checking
the final session state, so tighten it by asserting the endpoint inside the
onboard callback itself. Update the rebuildSandbox test to inspect the value
passed through overrides.onboard (or the callback used by onboard --resume) and
verify session.endpointUrl is already "https://registry.example.test/v1" at that
point, while keeping the existing harness.onboardSpy expectation for
locateability.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 430dada1-5892-4e8a-9311-8a97703df6ed

📥 Commits

Reviewing files that changed from the base of the PR and between c57aba2 and 743682c.

📒 Files selected for processing (4)
  • src/lib/actions/sandbox/rebuild-flow.test.ts
  • src/lib/actions/sandbox/rebuild-resume-config.test.ts
  • src/lib/actions/sandbox/rebuild-resume-config.ts
  • src/lib/actions/sandbox/rebuild.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/actions/sandbox/rebuild.ts

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 28257202249
Target ref: c57aba2df4f735beed0b775cd80c16fe8b3b7598
Workflow ref: main
Requested jobs: double-onboard-e2e,onboard-resume-e2e
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
double-onboard-e2e ❌ failure
onboard-resume-e2e ✅ success

Failed jobs: double-onboard-e2e. Check run artifacts for logs.

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

LGTM after addressing any feedback comments

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 28257918668
Workflow ref: hotfix/double-onboard-stale-rebuild
Requested scenarios: (default — all supported)
Requested jobs: double-onboard-vitest,sandbox-rebuild-vitest,onboard-resume-vitest,onboard-repair-vitest
Summary: 2 passed, 1 failed, 1 cancelled, 0 skipped

Job Result
double-onboard-vitest ⚠️ cancelled
onboard-repair-vitest ✅ success
onboard-resume-vitest ✅ success
sandbox-rebuild-vitest ❌ failure

Failed jobs: sandbox-rebuild-vitest. Check run artifacts for logs.

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Source-of-truth review needed: providerNameFromEnvHint camelCase alias mapping.
Open items: 0 required · 6 warnings · 0 suggestions · 7 test follow-ups
Since last review: 1 prior item resolved · 0 still apply · 3 new items found

Action checklist

  • PRA-1 Resolve or justify: Source-of-truth review needed: providerNameFromEnvHint camelCase alias mapping
  • PRA-2 Resolve or justify: Source-of-truth review needed: Stale retry endpoint overwrite due to OpenShell same-name recreate
  • PRA-3 Resolve or justify: Runtime validation gap for rebuild trust boundary in src/lib/actions/sandbox/rebuild-resume-config.ts:1
  • PRA-4 Resolve or justify: CamelCase provider alias fallback for legacy installer env in src/lib/actions/sandbox/rebuild-resume-config.ts:61
  • PRA-5 Resolve or justify: Legacy registry rows without durable endpoint metadata require explicit env fallback in src/lib/actions/sandbox/rebuild-resume-config.ts:266
  • PRA-6 Resolve or justify: Stale retry endpoint overwrite depends on OpenShell same-name recreate limitation in src/lib/actions/sandbox/rebuild.ts:788
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation gap for rebuild trust boundary
  • PRA-T5 Add or justify test follow-up: providerNameFromEnvHint camelCase alias mapping
  • PRA-T6 Add or justify test follow-up: Legacy registry rows without durable endpoint metadata
  • PRA-T7 Add or justify test follow-up: Stale retry endpoint overwrite due to OpenShell same-name recreate

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-3 Resolve/justify tests src/lib/actions/sandbox/rebuild-resume-config.ts:1 Add focused Vitest integration tests that spawn real `onboard --resume` with a prepared session and verify: (1) session endpoint is overwritten from validated config, (2) ambient env is isolated during onboard and restored after, (3) stale retry with partial session uses registry endpoint not stale session endpoint.
PRA-4 Resolve/justify correctness src/lib/actions/sandbox/rebuild-resume-config.ts:61 Document the alias mapping in code comments and ensure all current/future custom providers have entries. Track removal when all legacy rows have durable endpoint metadata and installers use canonical names.
PRA-5 Resolve/justify correctness src/lib/actions/sandbox/rebuild-resume-config.ts:266 Track migration of legacy registry rows to include durable endpointUrl. Consider a one-time migration script. Document explicit env requirements for affected users.
PRA-6 Resolve/justify correctness src/lib/actions/sandbox/rebuild.ts:788 Track OpenShell capability for temporary-name verification. When available, re-evaluate whether session endpoint should be conditionally updated based on validation source.
Review findings by urgency: 0 required fixes, 6 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: providerNameFromEnvHint camelCase alias mapping

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: rebuild-resume-config.test.ts:301-340 'accepts camelCase explicit provider aliases for non-matching session recovery'
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: rebuild-resume-config.ts:61-73 providerNameFromEnvHint; test at line 301; comment at line 266

PRA-2 Resolve/justify — Source-of-truth review needed: Stale retry endpoint overwrite due to OpenShell same-name recreate

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: test-double-onboard.sh Phase 5 stale recovery; rebuild-flow.test.ts should add unit test for unconditional overwrite
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: rebuild.ts:788-795 unconditional s.endpointUrl = resumeConfig.endpointUrl with [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869 comment; test-double-onboard.sh lines 750-754

PRA-3 Resolve/justify — Runtime validation gap for rebuild trust boundary

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:1
  • Category: tests
  • Problem: Unit tests cover all endpoint precedence branches and negative paths, but no integration test exercises the actual `onboard --resume` call with the rebuilt session endpoint, nor the `isolateAmbientRecreateEnv` + onboard interaction under real OpenShell.
  • Impact: A logic error in the session rewrite or ambient isolation could reach production without detection until E2E runs. The E2E test uses a fake server and doesn't validate the actual endpoint pinning behavior end-to-end.
  • Recommended action: Add focused Vitest integration tests that spawn real `onboard --resume` with a prepared session and verify: (1) session endpoint is overwritten from validated config, (2) ambient env is isolated during onboard and restored after, (3) stale retry with partial session uses registry endpoint not stale session endpoint.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run `npm test -- src/lib/actions/sandbox/rebuild-resume-config.test.ts` and confirm all 20 tests pass; then check for integration test file covering real onboard --resume invocation.
  • Missing regression test: Add integration test `rebuild-recovery-stale-session-endpoint-overwritten` that creates a stale sandbox with matching session containing stale endpoint, runs rebuild, and verifies the recreated sandbox uses the registry/validated endpoint. Add `rebuild-ambient-env-isolation-during-onboard-resume` that sets hostile ambient env and verifies isolation during onboard --resume.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run `npm test -- src/lib/actions/sandbox/rebuild-resume-config.test.ts` and confirm all 20 tests pass; then check for integration test file covering real onboard --resume invocation.
  • Evidence: testDepth.verdict=runtime_validation_recommended; no integration test file for rebuild flow; test-double-onboard.sh uses fake server

PRA-4 Resolve/justify — CamelCase provider alias fallback for legacy installer env

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:61
  • Category: correctness
  • Problem: providerNameFromEnvHint accepts camelCase aliases (e.g., 'anthropicCompatible') mapping to canonical registry provider names ('compatible-anthropic-endpoint') to support legacy installer `upgrade-sandboxes --auto` env hints.
  • Impact: If installer env uses non-canonical provider names, rebuild recovery for legacy registry rows (without durable endpoint metadata) depends on this alias mapping. A typo or new provider without alias would silently fail recovery.
  • Recommended action: Document the alias mapping in code comments and ensure all current/future custom providers have entries. Track removal when all legacy rows have durable endpoint metadata and installers use canonical names.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check `rebuild-resume-config.test.ts:301-340` 'accepts camelCase explicit provider aliases for non-matching session recovery' passes; verify REMOTE_PROVIDER_CONFIG keys cover all custom providers.
  • Missing regression test: Existing test 'accepts camelCase explicit provider aliases for non-matching session recovery' covers this. Add test for unknown provider alias rejection (already in rejection matrix at lines 237-280).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check `rebuild-resume-config.test.ts:301-340` 'accepts camelCase explicit provider aliases for non-matching session recovery' passes; verify REMOTE_PROVIDER_CONFIG keys cover all custom providers.
  • Evidence: sourceOfTruthReview: providerNameFromEnvHint at line 61; test at line 301; comment 'supports legacy registry rows that predate durable endpoint persistence' at line 266

PRA-5 Resolve/justify — Legacy registry rows without durable endpoint metadata require explicit env fallback

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:266
  • Category: correctness
  • Problem: Custom endpoint providers (compatible-endpoint, compatible-anthropic-endpoint) created before durable endpoint persistence lack registry endpointUrl. Rebuild recovery for these with non-matching session requires explicit NEMOCLAW_ENDPOINT_URL/PROVIDER/MODEL env vars with exact sandbox/provider/model match.
  • Impact: Users with pre-migration sandboxes hitting non-matching-session rebuild (e.g., installer upgrade-sandboxes --auto) must have correct explicit env set or rebuild fails closed. This is a temporary migration gap.
  • Recommended action: Track migration of legacy registry rows to include durable endpointUrl. Consider a one-time migration script. Document explicit env requirements for affected users.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run `rebuild-resume-config.test.ts` tests 'uses explicit target-scoped endpoint for a custom endpoint with a non-matching session' and 'does not use an explicit endpoint when its sandbox name targets another sandbox' to confirm boundary enforcement.
  • Missing regression test: Existing tests cover the explicit env acceptance and boundary rejection. Add test verifying migration path: registry entry with endpointUrl takes precedence over explicit env (covered by 'prefers durable registry endpoint metadata over a stale matching session endpoint').
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run `rebuild-resume-config.test.ts` tests 'uses explicit target-scoped endpoint for a custom endpoint with a non-matching session' and 'does not use an explicit endpoint when its sandbox name targets another sandbox' to confirm boundary enforcement.
  • Evidence: sourceOfTruthReview: comment at line 266 'supports legacy registry rows that predate durable endpoint persistence'; precedence order comment at lines 300-304; test at lines 279-300

PRA-6 Resolve/justify — Stale retry endpoint overwrite depends on OpenShell same-name recreate limitation

  • Location: src/lib/actions/sandbox/rebuild.ts:788
  • Category: correctness
  • Problem: Session endpoint is now always overwritten from validated config (was gated by pinEndpoint) because OpenShell recreates with the same sandbox name, preventing side-by-side verification. A failed recreate leaves a partial session that could steer a retry to the wrong endpoint.
  • Impact: If OpenShell gains the ability to build/verify a replacement under a temporary name before swap, this overwrite could become unnecessary or incorrect. The workaround is tied to OpenShell's current recreate semantics.
  • Recommended action: Track OpenShell capability for temporary-name verification. When available, re-evaluate whether session endpoint should be conditionally updated based on validation source.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check test-double-onboard.sh Phase 5 stale recovery test: rebuild on stale sandbox must succeed and overwrite endpoint. Verify rebuild.ts:788-795 comment references [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869.
  • Missing regression test: E2E test-double-onboard.sh Phase 5 covers stale recovery end-to-end. Add unit test in rebuild-flow.test.ts verifying session.endpointUrl is overwritten from resumeConfig.endpointUrl even when sessionMatchesSandbox=true.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check test-double-onboard.sh Phase 5 stale recovery test: rebuild on stale sandbox must succeed and overwrite endpoint. Verify rebuild.ts:788-795 comment references [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869.
  • Evidence: sourceOfTruthReview: comment at rebuild.ts:788-795 'stale recovery can be retrying after an earlier failed recreate left a partial session behind'; test-double-onboard.sh lines 750-754 diagnostic alignment

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — rebuild-recovery-stale-session-endpoint-overwritten: stale sandbox with matching session containing stale endpoint; verify rebuild overwrites with registry/validated endpoint and recreate succeeds. Unit tests cover all endpoint precedence branches and negative paths comprehensively (20 tests in rebuild-resume-config.test.ts, 4 flow tests). However, no integration test exercises actual onboard --resume with rebuilt session endpoint, nor isolateAmbientRecreateEnv + onboard interaction under real OpenShell. E2E test uses fake server and doesn't validate actual endpoint pinning behavior end-to-end.
  • PRA-T2 Runtime validation — rebuild-legacy-registry-explicit-env-recovery: legacy registry row (no durable endpoint) + non-matching session + valid explicit env; verify explicit env used and pinned. Unit tests cover all endpoint precedence branches and negative paths comprehensively (20 tests in rebuild-resume-config.test.ts, 4 flow tests). However, no integration test exercises actual onboard --resume with rebuilt session endpoint, nor isolateAmbientRecreateEnv + onboard interaction under real OpenShell. E2E test uses fake server and doesn't validate actual endpoint pinning behavior end-to-end.
  • PRA-T3 Runtime validation — rebuild-ambient-env-isolation-during-onboard-resume: ambient NEMOCLAW_ENDPOINT_URL set; verify isolated during onboard --resume and restored after. Unit tests cover all endpoint precedence branches and negative paths comprehensively (20 tests in rebuild-resume-config.test.ts, 4 flow tests). However, no integration test exercises actual onboard --resume with rebuilt session endpoint, nor isolateAmbientRecreateEnv + onboard interaction under real OpenShell. E2E test uses fake server and doesn't validate actual endpoint pinning behavior end-to-end.
  • PRA-T4 Runtime validation gap for rebuild trust boundary — Add focused Vitest integration tests that spawn real `onboard --resume` with a prepared session and verify: (1) session endpoint is overwritten from validated config, (2) ambient env is isolated during onboard and restored after, (3) stale retry with partial session uses registry endpoint not stale session endpoint.
  • PRA-T5 providerNameFromEnvHint camelCase alias mapping — rebuild-resume-config.test.ts:301-340 'accepts camelCase explicit provider aliases for non-matching session recovery'. rebuild-resume-config.ts:61-73 providerNameFromEnvHint; test at line 301; comment at line 266
  • PRA-T6 Legacy registry rows without durable endpoint metadata — rebuild-resume-config.test.ts:279-300 'uses explicit target-scoped endpoint for non-matching session'. rebuild-resume-config.ts:266 comment; precedence order lines 300-304; test at lines 279-300
  • PRA-T7 Stale retry endpoint overwrite due to OpenShell same-name recreate — test-double-onboard.sh Phase 5 stale recovery; rebuild-flow.test.ts should add unit test for unconditional overwrite. rebuild.ts:788-795 unconditional s.endpointUrl = resumeConfig.endpointUrl with [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869 comment; test-double-onboard.sh lines 750-754
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: providerNameFromEnvHint camelCase alias mapping

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: rebuild-resume-config.test.ts:301-340 'accepts camelCase explicit provider aliases for non-matching session recovery'
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: rebuild-resume-config.ts:61-73 providerNameFromEnvHint; test at line 301; comment at line 266

PRA-2 Resolve/justify — Source-of-truth review needed: Stale retry endpoint overwrite due to OpenShell same-name recreate

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: test-double-onboard.sh Phase 5 stale recovery; rebuild-flow.test.ts should add unit test for unconditional overwrite
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: rebuild.ts:788-795 unconditional s.endpointUrl = resumeConfig.endpointUrl with [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869 comment; test-double-onboard.sh lines 750-754

PRA-3 Resolve/justify — Runtime validation gap for rebuild trust boundary

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:1
  • Category: tests
  • Problem: Unit tests cover all endpoint precedence branches and negative paths, but no integration test exercises the actual `onboard --resume` call with the rebuilt session endpoint, nor the `isolateAmbientRecreateEnv` + onboard interaction under real OpenShell.
  • Impact: A logic error in the session rewrite or ambient isolation could reach production without detection until E2E runs. The E2E test uses a fake server and doesn't validate the actual endpoint pinning behavior end-to-end.
  • Recommended action: Add focused Vitest integration tests that spawn real `onboard --resume` with a prepared session and verify: (1) session endpoint is overwritten from validated config, (2) ambient env is isolated during onboard and restored after, (3) stale retry with partial session uses registry endpoint not stale session endpoint.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run `npm test -- src/lib/actions/sandbox/rebuild-resume-config.test.ts` and confirm all 20 tests pass; then check for integration test file covering real onboard --resume invocation.
  • Missing regression test: Add integration test `rebuild-recovery-stale-session-endpoint-overwritten` that creates a stale sandbox with matching session containing stale endpoint, runs rebuild, and verifies the recreated sandbox uses the registry/validated endpoint. Add `rebuild-ambient-env-isolation-during-onboard-resume` that sets hostile ambient env and verifies isolation during onboard --resume.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run `npm test -- src/lib/actions/sandbox/rebuild-resume-config.test.ts` and confirm all 20 tests pass; then check for integration test file covering real onboard --resume invocation.
  • Evidence: testDepth.verdict=runtime_validation_recommended; no integration test file for rebuild flow; test-double-onboard.sh uses fake server

PRA-4 Resolve/justify — CamelCase provider alias fallback for legacy installer env

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:61
  • Category: correctness
  • Problem: providerNameFromEnvHint accepts camelCase aliases (e.g., 'anthropicCompatible') mapping to canonical registry provider names ('compatible-anthropic-endpoint') to support legacy installer `upgrade-sandboxes --auto` env hints.
  • Impact: If installer env uses non-canonical provider names, rebuild recovery for legacy registry rows (without durable endpoint metadata) depends on this alias mapping. A typo or new provider without alias would silently fail recovery.
  • Recommended action: Document the alias mapping in code comments and ensure all current/future custom providers have entries. Track removal when all legacy rows have durable endpoint metadata and installers use canonical names.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check `rebuild-resume-config.test.ts:301-340` 'accepts camelCase explicit provider aliases for non-matching session recovery' passes; verify REMOTE_PROVIDER_CONFIG keys cover all custom providers.
  • Missing regression test: Existing test 'accepts camelCase explicit provider aliases for non-matching session recovery' covers this. Add test for unknown provider alias rejection (already in rejection matrix at lines 237-280).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check `rebuild-resume-config.test.ts:301-340` 'accepts camelCase explicit provider aliases for non-matching session recovery' passes; verify REMOTE_PROVIDER_CONFIG keys cover all custom providers.
  • Evidence: sourceOfTruthReview: providerNameFromEnvHint at line 61; test at line 301; comment 'supports legacy registry rows that predate durable endpoint persistence' at line 266

PRA-5 Resolve/justify — Legacy registry rows without durable endpoint metadata require explicit env fallback

  • Location: src/lib/actions/sandbox/rebuild-resume-config.ts:266
  • Category: correctness
  • Problem: Custom endpoint providers (compatible-endpoint, compatible-anthropic-endpoint) created before durable endpoint persistence lack registry endpointUrl. Rebuild recovery for these with non-matching session requires explicit NEMOCLAW_ENDPOINT_URL/PROVIDER/MODEL env vars with exact sandbox/provider/model match.
  • Impact: Users with pre-migration sandboxes hitting non-matching-session rebuild (e.g., installer upgrade-sandboxes --auto) must have correct explicit env set or rebuild fails closed. This is a temporary migration gap.
  • Recommended action: Track migration of legacy registry rows to include durable endpointUrl. Consider a one-time migration script. Document explicit env requirements for affected users.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run `rebuild-resume-config.test.ts` tests 'uses explicit target-scoped endpoint for a custom endpoint with a non-matching session' and 'does not use an explicit endpoint when its sandbox name targets another sandbox' to confirm boundary enforcement.
  • Missing regression test: Existing tests cover the explicit env acceptance and boundary rejection. Add test verifying migration path: registry entry with endpointUrl takes precedence over explicit env (covered by 'prefers durable registry endpoint metadata over a stale matching session endpoint').
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run `rebuild-resume-config.test.ts` tests 'uses explicit target-scoped endpoint for a custom endpoint with a non-matching session' and 'does not use an explicit endpoint when its sandbox name targets another sandbox' to confirm boundary enforcement.
  • Evidence: sourceOfTruthReview: comment at line 266 'supports legacy registry rows that predate durable endpoint persistence'; precedence order comment at lines 300-304; test at lines 279-300

PRA-6 Resolve/justify — Stale retry endpoint overwrite depends on OpenShell same-name recreate limitation

  • Location: src/lib/actions/sandbox/rebuild.ts:788
  • Category: correctness
  • Problem: Session endpoint is now always overwritten from validated config (was gated by pinEndpoint) because OpenShell recreates with the same sandbox name, preventing side-by-side verification. A failed recreate leaves a partial session that could steer a retry to the wrong endpoint.
  • Impact: If OpenShell gains the ability to build/verify a replacement under a temporary name before swap, this overwrite could become unnecessary or incorrect. The workaround is tied to OpenShell's current recreate semantics.
  • Recommended action: Track OpenShell capability for temporary-name verification. When available, re-evaluate whether session endpoint should be conditionally updated based on validation source.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check test-double-onboard.sh Phase 5 stale recovery test: rebuild on stale sandbox must succeed and overwrite endpoint. Verify rebuild.ts:788-795 comment references [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869.
  • Missing regression test: E2E test-double-onboard.sh Phase 5 covers stale recovery end-to-end. Add unit test in rebuild-flow.test.ts verifying session.endpointUrl is overwritten from resumeConfig.endpointUrl even when sessionMatchesSandbox=true.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check test-double-onboard.sh Phase 5 stale recovery test: rebuild on stale sandbox must succeed and overwrite endpoint. Verify rebuild.ts:788-795 comment references [Ubuntu 24.04][Sandbox] stale sandbox recovery removes registry entry before rebuild can recover #4497/fix(rebuild): persist inference selection metadata #5869.
  • Evidence: sourceOfTruthReview: comment at rebuild.ts:788-795 'stale recovery can be retrying after an earlier failed recreate left a partial session behind'; test-double-onboard.sh lines 750-754 diagnostic alignment

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@jyaunches

Copy link
Copy Markdown
Contributor Author

CI loop note on PR Review Advisor (Nemotron Ultra) follow-ups for head a9e2a4f3:

No blocking advisor findings remain; proceeding with required E2E validation.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 28258712455
Target ref: a9e2a4f38c0787265050d6528d43c4ebd78728da
Workflow ref: main
Requested jobs: double-onboard-e2e,onboard-resume-e2e
Summary: 1 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
double-onboard-e2e ❌ failure
onboard-resume-e2e ✅ success

Failed jobs: double-onboard-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 28259463838
Target ref: hotfix/double-onboard-stale-rebuild
Requested jobs: rebuild-openclaw-e2e,double-onboard-e2e,onboard-resume-e2e,onboard-repair-e2e
Summary: 3 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
double-onboard-e2e ❌ failure
onboard-repair-e2e ✅ success
onboard-resume-e2e ✅ success
rebuild-openclaw-e2e ✅ success

Failed jobs: double-onboard-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 28259469542
Workflow ref: hotfix/double-onboard-stale-rebuild
Requested scenarios: (default — all supported)
Requested jobs: onboard-resume-vitest,onboard-repair-vitest,rebuild-openclaw-vitest,double-onboard-vitest
Summary: 3 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
double-onboard-vitest ❌ failure
onboard-repair-vitest ✅ success
onboard-resume-vitest ✅ success
rebuild-openclaw-vitest ✅ success

Failed jobs: double-onboard-vitest. Check run artifacts for logs.

@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/rebuild-resume-config.ts`:
- Around line 59-62: The provider alias resolution in providerNameFromEnvHint is
normalizing the env hint to lowercase too early, which prevents camelCase keys
like anthropicCompatible from matching REMOTE_PROVIDER_CONFIG. Update the lookup
to preserve the original trimmed value for the config map check, and only fall
back to a normalized form when needed so valid aliases in
rebuild-resume-config.ts can resolve correctly. Keep the existing
providerNameFromEnvHint flow and REMOTE_PROVIDER_CONFIG lookup behavior intact
for other values.
🪄 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: 56d3727e-b237-4574-9f9c-0f61bb282062

📥 Commits

Reviewing files that changed from the base of the PR and between 743682c and 303291a.

📒 Files selected for processing (3)
  • src/lib/actions/sandbox/rebuild-flow.test.ts
  • src/lib/actions/sandbox/rebuild-resume-config.test.ts
  • src/lib/actions/sandbox/rebuild-resume-config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/actions/sandbox/rebuild-flow.test.ts

Comment thread src/lib/actions/sandbox/rebuild-resume-config.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Some jobs cancelled — partial pass

Run: 28261889305
Target ref: c3d3b221aafa6f5889f75c5717acb28e3080cd0b
Workflow ref: main
Requested jobs: double-onboard-e2e,onboard-resume-e2e
Summary: 1 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
double-onboard-e2e ⚠️ cancelled
onboard-resume-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28262399510
Target ref: cce56b12d33cf79d85401e469c097d809710b967
Workflow ref: main
Requested jobs: double-onboard-e2e,onboard-resume-e2e
Summary: 2 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
double-onboard-e2e ✅ success
onboard-resume-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28262793347
Target ref: hotfix/double-onboard-stale-rebuild
Requested jobs: rebuild-openclaw-e2e,upgrade-stale-sandbox-e2e,onboard-repair-e2e
Summary: 3 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
onboard-repair-e2e ✅ success
rebuild-openclaw-e2e ✅ success
upgrade-stale-sandbox-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 28262794801
Workflow ref: hotfix/double-onboard-stale-rebuild
Requested scenarios: (default — all supported)
Requested jobs: double-onboard-vitest,rebuild-openclaw-vitest,onboard-resume-vitest,onboard-repair-vitest
Summary: 3 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
double-onboard-vitest ❌ failure
onboard-repair-vitest ✅ success
onboard-resume-vitest ✅ success
rebuild-openclaw-vitest ✅ success

Failed jobs: double-onboard-vitest. Check run artifacts for logs.

@cv cv merged commit c13b44d into main Jun 26, 2026
186 of 187 checks passed
@cv cv deleted the hotfix/double-onboard-stale-rebuild branch June 26, 2026 21:18
@cv cv added the v0.0.69 Release target label Jun 27, 2026
@wscurran wscurran added area: e2e End-to-end tests, nightly failures, or validation infrastructure bug-fix PR fixes a bug or regression labels Jun 29, 2026
@wscurran

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: e2e End-to-end tests, nightly failures, or validation infrastructure bug-fix PR fixes a bug or regression v0.0.69 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants