Skip to content

fix(onboard): allocate Hermes API ports past route-only reservations - #9324

Merged
prekshivyas merged 7 commits into
NVIDIA:mainfrom
rluo8:fix/9291-hermes-api-route-only-port
Aug 18, 2026
Merged

fix(onboard): allocate Hermes API ports past route-only reservations#9324
prekshivyas merged 7 commits into
NVIDIA:mainfrom
rluo8:fix/9291-hermes-api-route-only-port

Conversation

@rluo8

@rluo8 rluo8 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Onboarding a second Hermes sandbox failed with EADDRINUSE on API port 8642 even though #8577 allocates per-sandbox ports in 8642-8652. Provider inference writes a route-only registry row before sandbox create; the Hermes API-port allocator treated that row as durable identity and pinned the default port without the allocation retry loop. Route-only reservations now allocate like an unregistered name, so a second Hermes sandbox can take the next free API port while durable legacy rows without hermesApiPort still keep 8642.

Related Issue

Fixes #9291

Changes

  • src/lib/onboard/hermes-api-port.ts: ignore isRouteOnlySandboxReservation rows in reserveCreateSandboxHermesApiPort and resolveOnboardHermesApiPort identity checks; allocate (with EADDRINUSE retry) instead of pinning 8642.
  • src/lib/onboard/hermes-api-port.test.ts: cover route-only resolve -> allocate and route-only reserve -> skip busy 8642 -> 8643; keep durable {} -> 8642 behavior.

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: No user-facing contract change; #8577 already documents per-sandbox API ports in 8642-8652. This restores that allocator for the onboard route-reservation path.
  • 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

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: User-visible Hermes API port range and multi-sandbox behavior already documented under #8577; this PR only fixes allocator identity for route-only registry rows.
  • Agent: Cursor

DGX Station Hardware Evidence

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

Verification

  • PR description includes a Signed-off-by: line and every 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 - command/result or justification: npx vitest run src/lib/onboard/hermes-api-port.test.ts -> 29 passed
  • Applicable broad gate passed - npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes - command/result:
  • 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)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Rui Luo ruluo@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Improved Hermes API port allocation for route-only reservations, allowing them to retry with another available port when needed.
    • Preserved existing port assignments for durable sandboxes and correctly reports port conflicts instead of silently reallocating.
    • Ensured onboarding assigns an available port to route-only reservations.
    • Improved handling of pending route setup states during durable sandbox provisioning.
  • Tests

    • Added regression coverage for port allocation, route setup states, durable sandboxes, and onboarding behavior.

@github-actions

github-actions Bot commented Aug 17, 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): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections match; severity counts match.
4 terminology differences from the second opinion

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

  • durable sandbox at src/lib/onboard/hermes-api-port.ts:34: primary classified it as justified; the second opinion classified it as established.
  • pendingRouteReservation at src/lib/onboard/hermes-api-port.test.ts:171: selected only by the second-opinion lane as established.
  • isRouteOnlySandboxReservation at src/lib/onboard/hermes-api-port.ts:41: selected only by the second-opinion lane as established.
  • HermesApiPortSandboxLookup at src/lib/onboard/hermes-api-port.ts:27: selected only by the second-opinion lane as define.

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

2 semantic terminology decisions

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

  • established — route-only reservation at src/lib/onboard/hermes-api-port.test.ts:158: Keep the established term for pre-create route reservations.
  • justified — durable sandbox at src/lib/onboard/hermes-api-port.ts:34: Keep the modifier because it distinguishes endpoint-preserving entries from route-only reservations.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

Manual-only E2E: onboard-repair, onboard-resume, cloud-onboard
The manual PR workflow does not run these selectors for the commit under review. Run them from reviewed code on main.

2 optional E2E recommendations
  • double-onboard
  • hermes-e2e

Workflow run details

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

@copy-pr-bot

copy-pr-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 17, 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: 7736feed-4379-45a1-bbcf-c4020eea0996

📥 Commits

Reviewing files that changed from the base of the PR and between c26195b and 2c0e97e.

📒 Files selected for processing (1)
  • src/lib/onboard/hermes-api-port.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard/hermes-api-port.test.ts

Included review availability: Your plan includes up to 12 reviews per rolling hour; 10 remain after this review.


📝 Walkthrough

Walkthrough

The change distinguishes route-only reservations from durable Hermes sandboxes during API port resolution. Route-only reservations retry allocation when a port is busy. Durable sandboxes preserve EADDRINUSE. Regression tests cover reservation and onboarding paths.

Changes

Hermes API port allocation

Layer / File(s) Summary
Durable sandbox lookup and reservation
src/lib/onboard/hermes-api-port.ts, src/lib/onboard/hermes-api-port.test.ts
Adds HermesApiPortSandboxLookup. Reservation logic excludes route-only entries from durable port preservation. Tests cover retry allocation and durable EADDRINUSE handling.
Onboard port resolution
src/lib/onboard/hermes-api-port.ts, src/lib/onboard/hermes-api-port.test.ts
Onboarding allocates a port for route-only reservations while preserving ports for durable sandboxes. Tests verify one allocation and publication of the selected port.

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

Merge Risk: ⚪ Minimal · up to 2c0e9

This localized change restores correct Hermes API-port allocation for route-only reservations, with targeted behavior tests passing; no actionable merge-blocking risk remains after normal checks.

🚥 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 describes the main change: allocating Hermes API ports beyond route-only reservations.
Linked Issues check ✅ Passed The allocator and regression tests address issue #9291 by retrying from busy port 8642 and enabling a distinct port for the second sandbox.
Out of Scope Changes check ✅ Passed The changes stay within Hermes API port allocation and related regression coverage; no unrelated code changes are shown.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@wscurran wscurran added area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression integration: hermes Hermes integration behavior labels Aug 17, 2026

@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 draft commit 8d3094f. I found no blocking defect.

One non-blocking coverage gap remains: add a case where pendingRouteReservation is true and createdAt is present. That row is durable, so an EADDRINUSE result must propagate after one default-port attempt instead of starting fresh allocation.

Security review:

  1. Secrets and credentials: PASS. Port allocation does not change credential flow.
  2. Input validation and data sanitization: PASS. The allocator reuses the canonical route-only reservation predicate.
  3. Authentication and authorization: PASS. This change adds no authorization path.
  4. Dependencies and third-party libraries: PASS. This change adds no dependency.
  5. Error handling and logging: PASS. EADDRINUSE retries apply only to allocation, while durable identity collisions still propagate.
  6. Cryptography and data protection: PASS. This change adds no cryptographic or protected-data flow.
  7. Configuration and security headers: PASS. The selected port stays within the established Hermes range.
  8. Security testing: PASS with the non-blocking durable pending-reservation coverage gap above.
  9. System security: PASS. The change preserves durable sandbox identity and fixes only the pre-create route-reservation path.

Cross-issue sweep: no adjacent fix or conflict found.

@rluo8
rluo8 marked this pull request as ready for review August 18, 2026 01:00

@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 commit 2c0e97ea08bef65616256e7cf51e3dea917d94ec; 35 focused Hermes port tests passed locally.

Security review:

  1. Secrets and credentials — PASS: no credential changes.
  2. Input validation — PASS: route-only reservations use the canonical registry predicate; durable rows remain distinct.
  3. Authentication and authorization — PASS: no access-control changes.
  4. Dependencies and supply chain — PASS: no dependency changes.
  5. Error handling and logging — PASS: transient reservations retry EADDRINUSE; durable conflicts still propagate.
  6. Cryptography — PASS: no cryptographic changes.
  7. Policy and network isolation — PASS: allocation remains within the existing Hermes API port range.
  8. Testing and regression safety — PASS: route-only, pending-route-with-timestamp, durable, and busy-port cases are covered.
  9. System security — PASS: durable sandbox identity is not silently reallocated.

The earlier failing CI shard was canceled while installing runner packages; it did not report a source-test failure.

@prekshivyas
prekshivyas enabled auto-merge (squash) August 18, 2026 04:17
@prekshivyas
prekshivyas disabled auto-merge August 18, 2026 04:17
@prekshivyas
prekshivyas merged commit eb56393 into NVIDIA:main Aug 18, 2026
90 of 98 checks passed
@github-actions github-actions Bot added the v0.0.110 Release target label Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression integration: hermes Hermes integration behavior v0.0.110 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[WSL x86][Onboard] second Hermes sandbox aborts with EADDRINUSE on API port 8642

3 participants