Skip to content

fix(onboard): preserve Station Express choices on resume - #7059

Merged
apurvvkumaria merged 20 commits into
NVIDIA:mainfrom
senthilr-nv:codex/7048-station-express-resume
Jul 17, 2026
Merged

fix(onboard): preserve Station Express choices on resume#7059
apurvvkumaria merged 20 commits into
NVIDIA:mainfrom
senthilr-nv:codex/7048-station-express-resume

Conversation

@senthilr-nv

@senthilr-nv senthilr-nv commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

DGX Station Express now records its secret-free provider, model, sandbox, and interaction intent before managed vLLM setup can fail. Running nemoclaw onboard --resume restores those choices and retries the failed Express step instead of returning to the generic provider and model prompts.

This follow-up is refreshed onto current main after #6991 merged and contains only the Station Express resume fix.

Supersedes #7053, which GitHub automatically closed when its stacked base branch was removed after merge.

Related Issue

Fixes #7048

Changes

  • Mark only the DGX Station Express installer path so DGX Spark and generic onboarding remain unchanged.
  • Persist a versioned, validated, secret-free Station Express resume intent in the existing owner-only onboarding session.
  • Restore the managed-vLLM model and Express defaults for failed or interrupted sessions, reject conflicting or malformed state, and clear the intent after successful completion or --fresh.
  • Persist the exact validated vLLM served model selected during provider setup, accept compatible registered identities, reject aliases for a different model, and require the same identity on later resumes.
  • Retire the owner/path-validated Station installer reboot receipt after successful onboarding or explicit onboard --fresh, so a later installer run cannot restore stale Express choices.
  • Cover initial capture, injected provider failure, failed-session resume, completed provider reuse, cleanup, post-success installer re-entry, malformed state, and the Station/Spark installer boundary.
  • Correct the command reference to include resumable failed onboarding sessions.

Type of Change

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

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: Apurv approved prior exact head 98d6f503; exact-head rereview requested for 3dd789c5 after the alias-validation and success/fresh receipt-lifecycle fixes
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

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 check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — current-head verification: 28 Station wrapper/session tests, 68 general session tests, and all 59 Station installer integration tests passed; the preceding provider/vLLM selection coverage also passed; npm run typecheck:cli, normal commit hooks, and push-time CLI typecheck passed
  • Applicable broad gate passed — npx vitest run --project cli completed with 9,084 passed, 20 skipped, and four unrelated local failures (missing Python yaml, a temp-directory cleanup race, and two existing five-second timeouts)
  • 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) — passed with zero errors and two existing Fern warnings
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Senthil Ravichandran senthilr@nvidia.com

Summary by CodeRabbit

  • New Features
    • DGX Station Express onboarding now persists a validated, secret-free resume intent through session setup, including optional served-model support.
    • “Fresh” onboarding now discards prior Station Express resume state and skips restoring any prior express recipe.
  • Bug Fixes
    • Prevented Station Express environment flags from leaking into non–DGX Station express flows.
    • Improved Station Express resume guardrails: detects conflicting/invalid persisted intents, preserves/resets provider/model state safely, and avoids completing provider selection on failure.
  • Documentation
    • Updated onboard --resume guidance to cover resumable interrupted or failed sessions (keeping existing restrictions).
  • Tests
    • Expanded Station Express/session-state and resume integration coverage, including prompt/output assertions for STATION_EXPRESS.

@senthilr-nv senthilr-nv self-assigned this Jul 16, 2026
@copy-pr-bot

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

@senthilr-nv senthilr-nv added platform: dgx-station Affects DGX Station hardware or workflows area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow provider: vllm vLLM local or hosted provider behavior labels Jul 16, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / high confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: No actionable findings remain in the canonical review ledger.

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 differ; 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: cloud-onboard, inference-routing, network-policy, onboard-repair, onboard-resume

1 optional E2E recommendation
  • vllm-docker-storage

Workflow run details

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

@senthilr-nv
senthilr-nv marked this pull request as ready for review July 17, 2026 00:20
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Station Express onboarding now records validated, secret-free provider/model intent before managed setup, restores compatible environment state during resume, preserves intent across failures, and clears it after completion. Installer wiring marks DGX Station express mode, with expanded tests and updated resume guidance.

Changes

Station Express resume

Layer / File(s) Summary
Resume intent validation and environment restoration
src/lib/onboard/station-express-resume.ts, src/lib/onboard/station-express-resume.test.ts
Validates intent and environment compatibility, restores provider/model variables for eligible resumes, rejects conflicts, and restores prior environment values afterward.
Session intent checkpointing and lifecycle
src/lib/state/onboard-session.ts, src/lib/state/onboard-session-station-express.test.ts, src/lib/onboard/session-bootstrap.ts, src/lib/onboard/session-bootstrap.test.ts, src/lib/onboard/machine/handlers/provider-inference.test.ts
Persists and validates intent, checkpoints it before provider setup, retains it after failure, and clears it on completion.
Onboarding entrypoint and installer wiring
src/lib/onboard.ts, src/lib/onboard/entry-options.ts, scripts/install.sh, test/install-*.test.ts, docs/reference/commands.mdx
Composes resume and non-interactive wrappers, passes prepared intent into session bootstrap, sets the DGX Station marker, updates installer assertions, and broadens resume guidance.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant Onboard
  participant Session
  participant ProviderSetup
  Installer->>Onboard: set Station Express environment
  Onboard->>Session: checkpoint provider/model intent
  Onboard->>ProviderSetup: start managed setup
  ProviderSetup-->>Onboard: fail or complete
  Onboard->>Session: preserve intent on failure or clear on completion
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#6883: Defines Station Express profile inputs and installer behavior used by the resume implementation.
  • NVIDIA/NemoClaw#6991: Adds installer resume persistence that this onboarding code parses and clears.
  • NVIDIA/NemoClaw#7030: Updates DGX Station express resume behavior using the marker consumed by onboarding.

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

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes persist, restore, validate, and clear Station Express resume state as required by #7048, with tests covering failure, resume, and cleanup.
Out of Scope Changes check ✅ Passed The docs, install script, code, and tests all support the Station Express resume fix, with no unrelated feature work evident.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: preserving DGX Station Express onboarding choices during resume.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
@senthilr-nv
senthilr-nv force-pushed the codex/7048-station-express-resume branch from e39aedc to 2895d55 Compare July 17, 2026 00:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

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

Inline comments:
In `@src/lib/state/onboard-session-station-express.test.ts`:
- Around line 37-87: Update the parent describe title for “Station Express
onboarding session state” to append the issue reference as the final “(`#7048`)”
suffix; leave the child test titles unchanged.

In `@src/lib/state/onboard-session.ts`:
- Around line 730-737: Validate the raw resumable value before the compatibility
check around stationExpressIntent: when stationExpressIntent is present, require
data.resumable to be a boolean and reject invalid values, including string
"false", by returning null. Preserve the existing checks for non-interactive
mode, resumable === false, and complete status.
🪄 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: acb70a1c-45a1-43da-972c-1b8fc6c6324b

📥 Commits

Reviewing files that changed from the base of the PR and between c5b8dba and 2895d55.

📒 Files selected for processing (13)
  • docs/reference/commands.mdx
  • scripts/install.sh
  • src/lib/onboard.ts
  • src/lib/onboard/entry-options.ts
  • src/lib/onboard/machine/handlers/provider-inference.test.ts
  • src/lib/onboard/session-bootstrap.test.ts
  • src/lib/onboard/session-bootstrap.ts
  • src/lib/onboard/station-express-resume.test.ts
  • src/lib/onboard/station-express-resume.ts
  • src/lib/state/onboard-session-station-express.test.ts
  • src/lib/state/onboard-session.ts
  • test/install-express-prompt.test.ts
  • test/install-station-host-preparation.test.ts

Comment thread src/lib/state/onboard-session-station-express.test.ts Outdated
Comment thread src/lib/state/onboard-session.ts

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

Four correctness gaps block this revision:

  1. Completed provider selection is trusted without binding it to the persisted Express intent. StationExpressSessionLike omits provider and model, and the completed path deliberately skips restoration without checking those values. A malformed session can carry Ultra intent while resuming another provider/model. Validate completed state against vllm-local and the intent's served model, and add negative mismatch tests.

  2. Explicit-resume lifecycle parsing is not fail-closed. Raw "false" currently becomes truthy, and arbitrary status strings are accepted unless they equal complete. Require resumable === true and an allowed resumable status (in_progress or failed), with malformed and missing-field coverage.

  3. A failed Express intent can be erased by a plain invocation. Failed sessions restore only under explicit --resume, while auto-resume recognizes only in_progress; session bootstrap can then overwrite the failed checkpoint without --fresh. Either fail with clear --resume/--fresh guidance or intentionally auto-resume, and test that boundary.

  4. The acceptance-level failure-to-resume regression is still missing. Add one chained test that checkpoints the intent, injects managed-vLLM failure, verifies the persisted failed session, invokes the real wrapper with --resume, and confirms the same provider/model is reused without the generic prompt.

The current CI and signature/DCO gates are otherwise clean. Please also resolve the two current CodeRabbit threads; the malformed resumable finding is part of blocker 2, while the suite-title suffix is nonblocking but straightforward.

Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Maintainer follow-up pushed in 8a127c10804d3268c91bec695e57d68acba2d765 (append-only from audited head 2895d5522a2620cbe84b96fa0df8a890710a7422; base remains c5b8dba7fcf1928d310423caca91a7134231a70d).

This revision:

  • binds completed Station Express provider/model/sandbox state to the persisted intent and fails closed on mismatches;
  • requires raw resumable === true and an allowed in_progress/failed lifecycle status;
  • prevents a plain invocation from replacing a failed Express checkpoint without an explicit --resume or --fresh choice;
  • adds the chained checkpoint → injected managed-vLLM failure → persisted failed session → real wrapper resume acceptance test;
  • addresses both prior CodeRabbit threads, including the (#7048) suite suffix.

Validation completed before push:

  • focused Station/onboarding set: 5 files, 82 tests passed;
  • session-state set: 6 files, 89 tests passed;
  • npm run build:cli and npm run typecheck:cli passed;
  • pre-commit and commit-message hooks passed, including Biome, repository checks, secret scan, source-shape and test-size gates;
  • test-title and Vitest-project membership checks passed;
  • docs review found the existing command reference already covers resume/failure/fresh behavior, so no docs edit was needed.

GitHub reports the commit signature Verified, and DCO has passed. CI and automated reviewers are now running on the exact new head. The fork E2E controller recorded its credentialed-job skip path for this revision; no protected E2E retry or duplicate dispatch was made.

@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/state/onboard-session-station-express.test.ts`:
- Around line 145-184: Update the failure-persistence test around
handleProviderInferenceState to exercise the scenario through the authoritative
OnboardRuntime or public onboarding lifecycle instead of invoking the handler
directly. Remove manual use of LEGACY_MACHINE_STEP_MUTATION_OPTIONS and
finalizeIncompleteOnboardStep, then assert that the runtime persists the
provider failure and that resuming follows the expected behavior through the
public entrypoint.
🪄 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: 82995a27-f6e7-4326-9ec5-4f142c9a689d

📥 Commits

Reviewing files that changed from the base of the PR and between 2895d55 and 8a127c1.

📒 Files selected for processing (4)
  • src/lib/onboard/station-express-resume.test.ts
  • src/lib/onboard/station-express-resume.ts
  • src/lib/state/onboard-session-station-express.test.ts
  • src/lib/state/onboard-session.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard/station-express-resume.ts

Comment thread src/lib/state/onboard-session-station-express.test.ts Outdated
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Follow-up for the new runtime-level review finding is in 98d6f503d173be21c602b9070ae18b34066cf34d (append-only from 8a127c10804d3268c91bec695e57d68acba2d765; base remains c5b8dba7fcf1928d310423caca91a7134231a70d).

The chained regression now:

  • advances the persisted session to provider selection through a real OnboardRuntime;
  • runs managed provider selection through runOnboardMachine and injects the setup failure there;
  • lets the public nonzero-exit lifecycle persist the failed step/session (no direct finalizeIncompleteOnboardStep call and no legacy machine-step mutation option);
  • resumes through the real entry wrapper and a fresh OnboardRuntime, applying provider/inference results through the machine runner to the sandbox handoff;
  • confirms the same Station provider/model is restored without the generic sandbox-name prompt.

Validation:

  • 7 focused CLI files, 104 tests passed (Station resume, session bootstrap, provider handler, runtime, runner, and exit failure coverage);
  • public exit-handler integration: 1 file, 4 tests passed;
  • npm run typecheck:cli passed;
  • test-title and Vitest-project membership checks passed;
  • the complete file hook set and push-time CLI typecheck passed.

GitHub reports this follow-up commit Verified. Protected E2E skip approval was deliberately not recorded for the superseded revision; refreshed CI and exact-diff coordination are now running on 98d6f503d173be21c602b9070ae18b34066cf34d.

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

Re-reviewed exact head 98d6f50 against base c5b8dba. All four requested correctness blockers and all CodeRabbit threads are addressed. Focused runtime, wrapper, session, provider, exit-lifecycle, hooks, and typecheck evidence is green; no unresolved review findings remain.

Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
@senthilr-nv

Copy link
Copy Markdown
Collaborator Author

Current-main follow-up is now at exact head 7f375f8998e25a5dd5d351e614cd91fa8283f401.

  • merged current main in signed commit 5353758fbf50ccc6174c2e20d46cc56462613b49;
  • preserved the exact validated vLLM served identity in 7f375f8998e25a5dd5d351e614cd91fa8283f401, so Station Express resumes accept a compatible alias adopted by fix(onboard): adopt compatible vllm served aliases #7044 while still failing closed on mismatches or malformed state;
  • current-head verification passed: 24 Station wrapper/session tests, 61 provider/vLLM tests, 7 integration selection tests, npm run typecheck:cli, and npm run check:diff;
  • both new commits are GitHub Verified; documentation review found no additional user-facing change needed.

@apurvvkumaria, please rereview this exact head because the prior approval was bound to 98d6f503d173be21c602b9070ae18b34066cf34d. Refreshed CI and automated review are running.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
putComment timed out

Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
@senthilr-nv

Copy link
Copy Markdown
Collaborator Author

PRA-1 is addressed at exact head 0c5a1c89857c189172775840e0a5a05bf2ddad98.

Explicit nemoclaw onboard --fresh now removes the Station installer reboot receipt before onboarding continues. Cleanup follows the installer boundary: it stays under the gateway-scoped .nemoclaw state root, rejects symlinks/non-directory path components/non-regular or unowned receipt files, tolerates an absent receipt, and fails closed if safe deletion cannot be established.

Verification:

  • 27 Station wrapper/session tests passed, including real-filesystem receipt deletion and unsafe-receipt rejection;
  • all 58 Station installer integration tests passed, including a seeded resumable session + receipt, fresh invocation, and a subsequent real Station prompt-selector run that does not restore the old recipe;
  • npm run typecheck:cli, commit hooks, and push-time CLI typecheck passed;
  • commit is GitHub Verified.

@apurvvkumaria, please rereview exact head 0c5a1c89857c189172775840e0a5a05bf2ddad98. Refreshed CI and automated review are running.

@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: 3

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

Inline comments:
In `@src/lib/onboard/station-express-resume.ts`:
- Around line 147-155: Update the servedModel validation in both the parsing and
binding paths around servedModelValue, BOUND_INTENT_KEYS, and isSafeModelId to
resolve the alias and require it to identify the Station model associated with
the intent. Preserve acceptance of compatible aliases while rejecting safe but
incompatible model IDs, including during completed-selection matching. Add a
regression test covering a canonical Ultra intent with a safe, unrelated
servedModel alias.

In `@src/lib/state/onboard-session-station-express.test.ts`:
- Around line 344-354: Update the test around session.markStepComplete and the
following requireLoadedSession assertion to explicitly verify
steps.provider_selection.status is "completed". Preserve the existing provider,
model, and stationExpressIntent assertions while asserting the step completion
outcome as part of the expected session state.
- Around line 366-377: Update the failed provider-selection assertion in the
session test to capture a pre-save snapshot of stationExpressIntent and compare
the post-failure stationExpressIntent with toEqual. Keep the existing
validation-error and pending-step assertions, while ensuring the comparison
detects any mutation, including servedModel or other fields.
🪄 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: ebd1e66a-b5a9-4af8-8298-c65d76e3ebca

📥 Commits

Reviewing files that changed from the base of the PR and between 98d6f50 and 0c5a1c8.

📒 Files selected for processing (6)
  • src/lib/onboard/machine/handlers/provider-inference.test.ts
  • src/lib/onboard/station-express-resume.test.ts
  • src/lib/onboard/station-express-resume.ts
  • src/lib/state/onboard-session-station-express.test.ts
  • src/lib/state/onboard-session.ts
  • test/install-station-host-preparation.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/onboard/machine/handlers/provider-inference.test.ts
  • src/lib/state/onboard-session.ts

Comment thread src/lib/onboard/station-express-resume.ts
Comment thread src/lib/state/onboard-session-station-express.test.ts
Comment thread src/lib/state/onboard-session-station-express.test.ts
Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
@senthilr-nv

Copy link
Copy Markdown
Collaborator Author

Addressed the remaining exact-head findings in 3dd789c5fea041dbea825917d8b59a8d97af4a34:

  • Successful Station Express completion now retires the guarded installer reboot receipt as well as the session intent. Unsafe cleanup fails before the session can claim completion.
  • A cross-layer regression completes onboarding, re-enters the real installer selector, and proves stale Express choices are not restored. Explicit --fresh has the same protection.
  • Persisted served-model identities must resolve to the Station model recorded by the intent. Compatible registered Ultra identities remain exact; a safe DeepSeek identity is rejected.
  • The provider-selection tests now assert completed-step state and unchanged intent after a rejected binding.

Current-head verification: 28 Station wrapper/session tests, 68 general session tests, all 59 Station installer integration tests, CLI typecheck, normal commit hooks, and push-time CLI typecheck passed. Commit signature is GitHub Verified. The docs-impact review found no additional update needed because the documented resume/fresh contract already describes these outcomes.

@apurvvkumaria, please re-review exact head 3dd789c5 when convenient.

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

Re-review of exact head 3dd789c5fea041dbea825917d8b59a8d97af4a34 found three blockers introduced by the follow-up commits:

  1. Arbitrary verified vLLM served aliases regress. identifiesModel() only accepts registry IDs/env values, but merged base #7044 intentionally accepts an arbitrary served name (for example nemotron-ultra) after /v1/models.root proves the underlying Ultra checkpoint; managed --served-model-name overrides have the same shape. The provider setup can therefore succeed and then markStepComplete("provider_selection", ...) throws while binding the checkpoint. The test was changed from nemotron-ultra to a registry identifier, masking the regression. Carry the route-validated model identity into the atomic binding and add an arbitrary-alias persistence/failure/resume test.

  2. Malformed binding lifecycle is accepted. A bound intent with a non-complete provider step and null provider/model passes normalization and wrapper matching, then installation is replayed with the registry canonical alias rather than the recorded one. Conversely, an unbound intent with a complete provider step is invalid. Enforce the invariant after parsing steps: complete provider step => bound intent + vllm-local + exact session model; non-complete provider step => unbound intent + null provider/model. Add normalization and wrapper negatives for both directions.

  3. Receipt retirement precedes durable completion. completeSession() unlinks station-express-resume inside the update mutator before saveSession() writes/renames the completed session. A persistence failure or crash in that window leaves the old resumable session on disk but deletes the reboot receipt, violating #7048's clear-only-after-success criterion. Coordinate these two durable states with a recoverable journal/tombstone (or a single authoritative state), and inject a post-cleanup save failure/crash-recovery regression.

The current static symlink check also has an lstat-then-path-unlink directory-swap race; please either close it with an fd/rename-based boundary or document why the verified owner-only directory makes it out of scope. Protected E2E must remain undispatched until these blockers and the exact head/base/review gate are rechecked.

@senthilr-nv

senthilr-nv commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Update: exact-head review at 3dd789c5 has requested changes. Please do not approve the credentialed E2E skip yet.

Main CI is green, but the PR remains blocked on the served-model alias, lifecycle invariant, and durable receipt-retirement findings. The earlier approval request is superseded until those findings are addressed and the exact head is re-reviewed.

@senthilr-nv

Copy link
Copy Markdown
Collaborator Author

Exact-head follow-up is ready at 070e4af7d.

The arbitrary vLLM alias binding, lifecycle normalization, receipt durability, and owner-only path-boundary findings are addressed with regression coverage. All normal CI and both review advisors are green with zero findings.

Protected E2E remains undispatched pending exact-head approval.

@apurvvkumaria, please rereview this head.

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

Re-review of exact head : the arbitrary-alias proof, provider lifecycle invariants, save-before-clear ordering, and owner-only pathname boundary address the prior findings. One correctness blocker remains.\n\n treats any existing session as proof that a loaded Station reboot receipt belongs to that completed attempt, deletes the receipt, and returns without invoking onboarding. The receipt is created before reboot/CLI onboarding, so an unrelated older completed session can legitimately preexist; after reboot, the newly accepted Station attempt is then silently discarded. The new case currently encodes this false positive by using a completed session with no Station provenance and expecting no CLI invocation. The TypeScript cleanup predicate is likewise uncorrelated.\n\nPlease bind the receipt to the exact Station attempt/generation (not just provider/model heuristics) and retire it only when the durable completion marker matches that generation. Add regressions for: (1) old unrelated completed session + new receipt must not skip onboarding or retire the new receipt; (2) matching Station completion + injected post-save cleanup failure must retire only that receipt on re-entry without replaying onboarding; and (3) a replaced/mismatched receipt fails closed. Protected E2E should remain held until this exact-head blocker is addressed and re-reviewed.\n\nThe residual TypeScript lstat/unlink race is reduced to a same-UID principal by the new owner-only ancestor checks and is not blocking this review.

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

Re-review of exact head 070e4af7d94385bde2a5626fdb6c7f729d2894ed: the arbitrary-alias proof, provider lifecycle invariants, save-before-clear ordering, and owner-only pathname boundary address the prior findings. One correctness blocker remains.

scripts/install.sh:2560-2562,2593-2597 treats any existing { status: "complete", resumable: false } session as proof that a loaded Station reboot receipt belongs to that completed attempt, deletes the receipt, and returns without invoking onboarding. The receipt is created before reboot and CLI onboarding, so an unrelated older completed session can legitimately preexist; after reboot, the newly accepted Station attempt is then silently discarded. The new test/install-onboard-yes.test.ts case currently encodes this false positive by using a completed session with no Station provenance and expecting no CLI invocation. The TypeScript cleanup predicate is likewise uncorrelated.

Please bind the receipt to the exact Station attempt or generation—not just provider/model heuristics—and retire it only when the durable completion marker matches that generation. Add regressions for:

  1. An old unrelated completed session plus a new receipt must not skip onboarding or retire the new receipt.
  2. A matching Station completion plus an injected post-save cleanup failure must retire only that receipt on re-entry without replaying onboarding.
  3. A replaced or mismatched receipt must fail closed.

Protected E2E should remain held until this exact-head blocker is addressed and re-reviewed.

The residual TypeScript lstat/unlink race is reduced to a same-UID principal by the new owner-only ancestor checks and is not blocking this review.

apurvvkumaria and others added 10 commits July 17, 2026 01:22
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Accept supported full model identities and keep fresh cleanup safe for legacy state directories.

Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

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

Re-reviewed exact head 439d38c70aa6731c1bc66a329cc5961a969f4198 against base aa3dd78a2c64d59e6d5367e14e24c377c56c66b4. The Station receipt is now bound to the exact installer generation, completion persists the matching retirement marker before receipt cleanup, recovery reconciles only that generation, unrelated completed sessions do not suppress a new attempt, and replaced or mismatched receipts fail closed. All inline threads are resolved. Local exact-head verification passed 61 focused CLI lifecycle tests, 18 installer wrapper tests, 60 Station installer tests, and CLI typecheck. Current canonical advisor output reports zero actionable findings; the failed Nemotron lane is an advisor infrastructure failure and its partial output is explicitly non-canonical.

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 platform: dgx-station Affects DGX Station hardware or workflows provider: vllm vLLM local or hosted provider behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Station Express context is lost after managed vLLM onboarding failure

4 participants