Skip to content

fix(list): hide route-only reservations from list and status (#7609) - #7621

Merged
prekshivyas merged 2 commits into
mainfrom
fix/7609-list-hide-route-only-reservation
Jul 27, 2026
Merged

fix(list): hide route-only reservations from list and status (#7609)#7621
prekshivyas merged 2 commits into
mainfrom
fix/7609-list-hide-route-only-reservation

Conversation

@yanyunl1991

@yanyunl1991 yanyunl1991 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

A failed onboard that reserved the gateway inference route but never created the sandbox leaves a pendingRouteReservation registry entry with no createdAt. nemoclaw list and nemoclaw status rendered that route-only reservation as a real sandbox — a ghost the user had to destroy even though it never existed in the live gateway. This PR filters route-only reservations at the display boundary.

Closes #7609.

Reproduction

On our Ubuntu 24.04 x86_64 test host (no GPU), built from main:

NEMOCLAW_SANDBOX_BASE_IMAGE_REF=127.0.0.1:18081/untrusted/base:latest \
  nemoclaw onboard --name base-img-reject-openclaw --non-interactive --yes --fresh
nemoclaw list

Reproduced for OpenClaw, Hermes and LangChain Deep Agents Code (--agent hermes / --agent dcode). OpenClaw fails at the base-image trust check; Hermes/dcode fail later in the image build — but all three leave the same ghost, because the route reservation is written before, and independently of, the agent-specific create path.

Environment

  • Test machine: our Ubuntu 24.04 x86_64 test host (no GPU)
  • NemoClaw main HEAD 0b1854981
  • Sandbox provider: local Ollama (llama3.1:8b)

Observed on main (before fix)

SandboxBaseImageResolutionError: OpenClaw sandbox base image override
'127.0.0.1:18081/untrusted/base:latest' is outside the trusted repository
'ghcr.io/nvidia/nemoclaw/sandbox-base'.

$ nemoclaw list
  Sandboxes:
    base-img-reject-openclaw
      agent: openclaw  provider: ollama-local  ...
    base-img-reject-hermes   ...
    base-img-reject-dcode    ...

$ nemoclaw status
  Sandboxes:
    base-img-reject-openclaw (llama3.1:8b) ...   # same ghosts

Registry entry left behind:

"base-img-reject-openclaw": { "pendingRouteReservation": true, "provider": "ollama-local", ... }   // no createdAt

Observed on fix/... (after fix)

$ nemoclaw list
  No sandboxes registered. Run `nemoclaw onboard` to get started.

$ nemoclaw status
  Global status (registered sandboxes and host services):
  Gateway authority: nemoclaw-managed
  # no ghost rows

# The reservation is still on disk (preserved for --resume), just not displayed.
# Regression check: promoting one entry to a real sandbox (set createdAt) makes it
# show in `list` again — real sandboxes are never hidden.

Analysis

The provider/inference onboard step reserves the gateway route by writing a registry entry via registry.reserveSandboxInferenceRoute (src/lib/onboard/machine/handlers/provider-inference.ts), marked pendingRouteReservation: true. That marker is cleared only when the sandbox is actually created (or on a resume). When a later step throws — the untrusted base image is rejected in resolveSandboxBaseImage (src/lib/sandbox-base-image.ts) inside createSandboxWithBaseImageResolution (src/lib/onboard.ts), or the image build fails — the reservation is left behind.

registry.isRouteOnlySandboxReservation (pendingRouteReservation === true && createdAt === undefined) already identifies exactly this entry, and maintenance / upgrade-sandboxes already exclude it from their listings. nemoclaw list (buildSandboxInventory) and nemoclaw status (getStatusReport / showStatusCommand) were the outliers that did not.

The reservation is intentionally kept for --resume (#6572, #6626), so the correct fix is to filter it at the display boundary — not to release it, which would break resume.

Fix

  • src/lib/inventory/index.ts: buildSandboxInventory, getStatusReport and showStatusCommand filter out isRouteOnlySandboxReservation entries before rendering. Two passthrough fields (pendingRouteReservation, createdAt) are added to the display SandboxEntry (they already ride on recovered rows at runtime) so the predicate can read them.
  • src/lib/state/registry.ts: isRouteOnlySandboxReservation now takes a structural parameter (just the two fields it reads) so the display entry type can reuse this single source of truth instead of re-deriving the predicate.

Whole-class notes: the filter is keyed on the reservation shape, so it is independent of agent (OpenClaw/Hermes/dcode) and of the failure cause (trust rejection vs build failure) — verified on the test host for all three agents and both list and status. Internal consumers that must still see reservations (resume, inference set, connect) are unchanged. No new failure path is introduced; the reservation persistence is intentional. No docs describe the previous ghost display, so none need updating.

Tests (src/lib/inventory/index.test.ts): a route-only reservation is hidden from list; a created sandbox with a lingering reservation flag is still shown (regression lock); the empty-state hint appears when only reservations remain; and route-only reservations are hidden from status too.

Changes

  • src/lib/inventory/index.ts: filter route-only reservations from list and status; add passthrough fields to the display entry type.
  • src/lib/state/registry.ts: widen isRouteOnlySandboxReservation to a structural parameter.
  • src/lib/inventory/index.test.ts: coverage for the filter across list and status.

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)

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: docs/reference/commands.mdx and docs/manage-sandboxes/lifecycle.mdx already define list and global status as registered-sandbox views and document environment-override precedence. The fix restores that documented behavior. The follow-up changes only a comment and accurately distinguishes the registry default from explicit environment overrides. Changed comments and test titles have no blocking WRITING.md findings.
  • Agent: Codex Desktop documentation writer subagent

Verification

  • npx prek run passes on the changed files
  • npm test passes (touched files at minimum)
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes

AI Disclosure

  • AI-assisted — tool: Claude Code

Signed-off-by: Yanyun Liao yanyunl@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Route-only (incomplete) sandbox reservations are no longer treated as active sandboxes in inventory listings.
    • Status reports and the status command now omit incomplete route-only reservations from their output.
    • If only route-only reservations exist, listing and status views correctly show the “no sandboxes registered” empty-state.
    • Sandboxes with a creation timestamp remain visible even when a route reservation is still pending.
  • Tests
    • Added coverage for route-only reservation filtering behavior (including empty-state scenarios).

A failed onboard that reserved the gateway inference route but never
created the sandbox (e.g. an untrusted base-image override is rejected,
or the agent image build fails) leaves a `pendingRouteReservation`
registry entry with no `createdAt`. `nemoclaw list` and `nemoclaw
status` rendered that route-only reservation as a real sandbox, so it
appeared as a ghost that the user had to `destroy` even though it was
never in the live gateway. This reproduced for OpenClaw, Hermes and
LangChain Deep Agents Code because the reservation is written before,
and independently of, the agent-specific create path.

The reservation is intentionally preserved for `--resume`
(#6572/#6626), so the fix filters it at the display boundary rather
than releasing it: `buildSandboxInventory`, `getStatusReport` and
`showStatusCommand` now exclude `isRouteOnlySandboxReservation` entries,
matching what `maintenance` and `upgrade-sandboxes` already do.
`isRouteOnlySandboxReservation` takes a structural parameter so the
display entry type can reuse the single source of truth.

Fixes #7609

Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: 0dfebff0-b4cb-489a-bf0f-9330b1e43f5d

📥 Commits

Reviewing files that changed from the base of the PR and between 9bf48f1 and 6a348e3.

📒 Files selected for processing (1)
  • src/lib/inventory/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/inventory/index.ts

📝 Walkthrough

Walkthrough

Route-only sandbox reservations are represented in inventory data, filtered from inventory and status output, and covered by tests for exclusion, empty-state rendering, and visibility after creation.

Changes

Route-only reservation handling

Layer / File(s) Summary
Reservation predicate contract
src/lib/inventory/index.ts, src/lib/state/registry.ts
SandboxEntry carries reservation markers, and isRouteOnlySandboxReservation uses the minimal structural shape needed to identify uncreated reservations.
Inventory and status filtering
src/lib/inventory/index.ts
Inventory listing, structured status reports, and status command output exclude reservations without createdAt.
Reservation behavior coverage
src/lib/inventory/index.test.ts
Tests cover filtering, empty-state output, status output, and retaining entries that have createdAt.

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

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

Suggested reviewers: cv

🚥 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 matches the main change: hiding route-only reservations from list and status for issue #7609.
Linked Issues check ✅ Passed The changes filter ghost reservations from list and status, which addresses the reported failed-onboarding ghost sandbox behavior in #7609.
Out of Scope Changes check ✅ Passed The PR stays focused on route-only reservation filtering and related tests, with no unrelated feature changes apparent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/7609-list-hide-route-only-reservation

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

@github-code-quality

github-code-quality Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 6a348e3 in the fix/7609-list-hide-r... branch remains at 96%, unchanged from commit 921e1b0 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 6a348e3 in the fix/7609-list-hide-r... branch remains at 80%, unchanged from commit 921e1b0 in the main branch.

Show a code coverage summary of the most impacted files.
File main 921e1b0 fix/7609-list-hide-r... 6a348e3 +/-
src/lib/inventory/index.ts 90% 90% 0%
src/lib/sandbox...rce-identity.ts 88% 88% 0%
src/lib/shields/index.ts 71% 72% +1%
src/lib/state/registry.ts 84% 85% +1%

Updated July 27, 2026 08:42 UTC

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized E2E selections match; severity counts match.

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

1 optional E2E recommendation
  • onboard-negative-paths

Workflow run details

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

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>

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

Reviewed exact head 6a348e3. The route-only reservation filter is narrowly scoped, preserves resume state, and has appropriate regression coverage. The misleading default-resolution comment is corrected, the documentation-writer receipt is current, and no blocking correctness or security findings remain.

@prekshivyas
prekshivyas merged commit d7b15dd into main Jul 27, 2026
98 of 100 checks passed
@prekshivyas
prekshivyas deleted the fix/7609-list-hide-route-only-reservation branch July 27, 2026 09:04
@cv cv mentioned this pull request Jul 27, 2026
23 tasks
cv added a commit that referenced this pull request Jul 27, 2026
<!-- markdownlint-disable MD041 -->
## Summary

`docs/changelog/2026-07-25.mdx` now includes the user-facing fixes that
merged after #7607 and before the v0.0.96 tag.
The follow-up covers safer bulk backup and clone restore behavior,
policy and inference repairs, cleaner onboarding diagnostics, and
OpenClaw base-image validation while leaving test-only and
maintainer-internal merges out of the release entry.

## Changes

- Document the Shields-safe `backup-all` flow from #7557 and the
clone-specific restore pairing publication from #7608.
- Record the Claude Code resolved-launcher policy repair from #7581,
Hermes namespaced-model handling from #7604, and persisted Ollama
proxy-token reuse from #7620.
- Record OpenClaw immutable base-inventory validation from #7606, hidden
route-only reservations from #7621, and clean invalid gateway-management
errors from #7630.
- Link the gateway lifecycle and snapshot authorities, retain #7622's
already-merged Docker Engine wording, and exclude internal or test-only
merges from the release entry.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] 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:
- [x] Tests not applicable — justification: This PR changes
release-entry prose only. The changelog contract test and Fern
validation cover the dated entry, published routes, and rendering
requirements.
- [x] 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:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: At exact PR head `29316da26`, a Codex Desktop documentation
writer reviewed `docs/changelog/2026-07-25.mdx` against `AGENTS.md`,
`WRITING.md`, and `docs/CONTRIBUTING.md`. The review confirmed that the
full entry accurately reflects the merged user-visible behavior, retains
#7622's existing wording, appropriately excludes internal and test-only
PRs, and uses conforming terminology, structure, links, and release
classification. It also confirmed that the review follow-ups use active
third-person release-entry voice, name the actor and recovery
requirement directly, and accurately preserve the trusted-backup,
cached-release refresh, and local-build fallback constraints. The
changelog test passed 6/6, and the docs build completed with 0 errors
and 2 pre-existing hidden warnings.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 29316da -->
<!-- docs-review-agents-blob-sha: be20a09 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## 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, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: `npx
vitest run test/changelog-docs.test.ts` passed 6/6 tests after the final
review fix.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable to this
prose-only changelog change.
- [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) — exited
0 with 0 errors and 2 pre-existing hidden warnings after the final
review fix.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
* Expanded the changelog to clarify persistent `policy exclude`/`policy
restore` behavior across rebuilds and snapshot restores, including
reporting on removed endpoints and exclusion consistency.
* Updated `claude-code` preset guidance to allow the npm-installed
OpenShell launcher path while maintaining endpoint/HTTP method scope.
* Documented hardened handling for invalid gateway-management
declarations, improved gateway/agent-version diagnostics scope, and
clarified onboarding/restore credential and reasoning precedence.
* Tightened bulk backup/restore guidance (safety windows, approval
limits, and failure recovery) and refined OpenClaw base selection to
avoid incompatible cached releases and `:latest` fallback.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression integration: dcode LangChain Deep Code integration behavior integration: hermes Hermes integration behavior integration: openclaw OpenClaw integration behavior labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression integration: dcode LangChain Deep Code integration behavior integration: hermes Hermes integration behavior integration: openclaw OpenClaw integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Linux][Onboard] failed untrusted base-image onboarding leaves ghost sandbox entries

3 participants