Skip to content

feat(inference): add fixed local serving profiles - #8399

Merged
prekshivyas merged 13 commits into
mainfrom
feat/fixed-local-serving-profiles
Aug 6, 2026
Merged

feat(inference): add fixed local serving profiles#8399
prekshivyas merged 13 commits into
mainfrom
feat/fixed-local-serving-profiles

Conversation

@ericksoa

@ericksoa ericksoa commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds opt-in fixed local model profiles for DGX Spark backed by public vLLM and llama.cpp catalog recipes. The dedicated noninteractive path pins model and runtime identity, authenticates loopback-only endpoints, and records ownership for recovery and uninstall.

Changes

  • Add disabled-by-default vLLM and llama.cpp serving profiles to the typed inference catalog, using the existing host-local serving recipe abstraction from feat(inference): add host-local vLLM serving presets #8249.
  • Add a dedicated noninteractive onboarder and hosted-installer runtime selection that reject unsupported overrides and materialize only the selected fixed profile.
  • Add authenticated lifecycle management, exact GGUF acquisition and verification, owner-scoped cache reuse, and exact-ownership uninstall cleanup.
  • Document the opt-in commands, generated runtime state, and uninstall behavior, with focused parser, onboarding, lifecycle, catalog, and cleanup tests.

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: Local implementation review covered endpoint authentication, loopback binding, fixed-identity override rejection, cache integrity, ownership receipts, and uninstall boundaries.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: docs/inference/choose-local-inference-server.mdx, docs/reference/commands.mdx, and docs/reference/host-files-and-state.mdx document the fixed local profile installer, host state, recovery, and ownership-aware uninstall behavior; npm run docs passes.
  • Agent: Codex Desktop

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 — 17 affected Vitest suites passed (382 tests); focused package contracts passed (4 tests).
  • 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)

Additional validation: npm run docs completed with 0 errors and 2 pre-existing warnings. The affected package contracts passed; the full package-contract lane remains subject to unrelated live-registry ETARGET failures and existing CLI subprocess timeouts.


Signed-off-by: Aaron Erickson aerickson@nvidia.com

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@coderabbitai

coderabbitai Bot commented Aug 5, 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

Adds feature-gated DGX Spark local-model profiles for vLLM and llama.cpp. The change includes catalog planning, non-interactive onboarding, authenticated runtime installation and recovery, ownership-aware cleanup, cache handling, tests, and operator documentation.

Changes

Managed local model profiles

Layer / File(s) Summary
Profile contracts and catalog planning
managed-inference/..., src/lib/inference/serving/..., src/lib/onboard/local-model-profile/plan.ts
Adds feature-gated Spark presets, a pinned vLLM recipe, host-local validation, and runtime-specific plan resolution.
Installer and onboarding flow
scripts/install.sh, src/lib/onboard/local-model-profile/*, src/lib/onboard/setup-nim-flow.ts, test/install-local-model-profile.test.ts
Adds runtime selection, override validation, non-interactive onboarding, and dedicated vLLM or llama.cpp installation paths.
Managed llama.cpp runtime
src/lib/inference/llama-cpp/*, src/lib/adapters/docker/local-model-runtime.ts
Adds verified model acquisition, cache ownership, authenticated Docker resources, readiness probing, receipts, and installer tests.
Host-local vLLM runtime
src/lib/inference/vllm*.ts, src/lib/inference/serving/*, src/lib/inference/local.ts
Adds fixed serving arguments, bearer authentication, loopback binding, readiness checks, endpoint recovery, and lifecycle tests.
Cleanup and uninstall integration
src/lib/inference/local-model-profile/*, src/lib/actions/uninstall/*
Adds receipt-bound cleanup for vLLM and llama.cpp resources, cache preservation or deletion, fail-closed validation, and consolidated uninstall handling.
Operator and state documentation
docs/inference/choose-local-inference-server.mdx, docs/reference/commands.mdx, docs/reference/host-files-and-state.mdx
Documents profile prerequisites, installation commands, managed state, authentication, cache behavior, recovery, and uninstall behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant SetupFlow
  participant ProfilePlan
  participant ProfileOnboarder
  participant ManagedRuntime
  participant ProviderState
  Installer->>SetupFlow: select local model runtime
  SetupFlow->>ProfilePlan: resolve feature-gated catalog plan
  ProfilePlan-->>SetupFlow: return vLLM or llama.cpp plan
  SetupFlow->>ProfileOnboarder: execute dedicated onboarding
  ProfileOnboarder->>ManagedRuntime: install and verify runtime
  ManagedRuntime-->>ProfileOnboarder: return endpoint and credentials
  ProfileOnboarder->>ProviderState: attach selected provider and model
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#8249: Extends related host-local vLLM serving, authentication, installation, and cleanup behavior.
  • NVIDIA/NemoClaw#8294: Defines related llama.cpp artifact, cache, and receipt lifecycle contracts.
  • NVIDIA/NemoClaw#8338: Introduces related host-local llama.cpp runtime bindings extended by this change.

Suggested labels: feature, area: inference, area: local-models, area: onboarding, platform: dgx-spark, area: providers

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.40% 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 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: adding fixed local serving profiles for inference.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/fixed-local-serving-profiles

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

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

@github-code-quality

github-code-quality Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 7c25b61 in the feat/fixed-local-ser... branch remains at 96%, unchanged from commit 8227087 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 7c25b61 in the feat/fixed-local-ser... branch remains at 82%, unchanged from commit 8227087 in the main branch.

Show a code coverage summary of the most impacted files.
File main 8227087 feat/fixed-local-ser... 7c25b61 +/-
src/lib/inference/vllm.ts 89% 87% -2%
src/lib/actions...all/run-plan.ts 84% 85% +1%
src/lib/inference/local.ts 79% 80% +1%
src/lib/inferen...ter-registry.ts 84% 89% +5%
src/lib/onboard/docker-cdi.ts 70% 80% +10%
src/lib/onboard...le/onboarder.ts 0% 79% +79%
src/lib/inferen...ed-installer.ts 0% 84% +84%
src/lib/inferen...file/cleanup.ts 0% 85% +85%
src/lib/inferen...al-lifecycle.ts 0% 89% +89%
src/lib/onboard...profile/plan.ts 0% 90% +90%

Updated August 06, 2026 00:56 UTC

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed after a partial review · low confidence · 0 blockers · 0 warnings · 0 suggestions

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

3 semantic terminology decisions

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

  • define — fixed local model profile at docs/inference/choose-local-inference-server.mdx:26: Keep this term and its option-table definition before the installation procedure.
  • established — host-local at docs/reference/commands.mdx:3651: Keep host-local where the runtime-location distinction is required; use host-side only for the broader outside-sandbox location meaning.
  • established — owner-only at docs/reference/host-files-and-state.mdx:36: Keep the established term for permissions and state that must remain restricted to the current user.

E2E guidance

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

Recommended E2E: cloud-onboard, managed-image-multiarch-startup, inference-routing, network-policy, onboard-repair, onboard-resume

1 optional E2E recommendation
  • llama-cpp-dgx-spark-qualification
1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Add a profile-specific host-to-sandbox route regression test

  • Location: src/lib/onboard/local-model-profile/integration.ts:15
  • Category: tests
  • Problem: The new local-model profile path has unit and mocked onboarding coverage, but no checked-in test creates or resumes a sandbox and proves its advertised inference.local route reaches either selected fixed runtime while unrelated egress remains denied.
  • Impact: A catalog-valid, authenticated loopback runtime can still fail to route through OpenShell or receive an unintended network-policy exception in the real host-to-sandbox topology.
  • Recommendation: Add an existing E2E suite case for each selected DGX Spark local-model runtime that installs or resumes the profile, sends an authenticated model request through inference.local from the sandbox, and verifies unrelated egress remains denied.
  • Verification: Inspect the checked-in E2E scenario and its assertions for a sandbox-originated inference.local request to both profile runtimes plus a denied unrelated-egress assertion.
  • Test coverage: In an existing DGX Spark E2E suite, install or resume each local-model runtime, create or recover the sandbox, invoke the selected model through inference.local with its managed credential path, and assert a non-profile egress destination remains blocked.
  • Simplification (native): Remove Do not add another unit harness for OpenShell routing.; use Extend the existing inference-routing or network-policy E2E coverage with the fixed-profile scenario.. Net: 0 lines.
  • Keep: The test must retain real sandbox, OpenShell route, and network-policy enforcement.
  • Evidence: Risk plan invariant: the selected provider is reachable through the route advertised to the agent and network policy denies unintended egress. src/lib/onboard/local-model-profile/onboarder.test.ts covers mocked install and selection handlers, not a created sandbox route. src/lib/inference/llama-cpp/managed-installer.test.ts and src/lib/inference/serving/vllm-host-local-lifecycle.test.ts cover local runtime behavior without an OpenShell sandbox boundary. The E2E inventory includes inference-routing, network-policy, onboard-repair, and onboard-resume jobs, but no listed changed test covers the new fixed-profile route end to end.

Workflow run details

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

Comment thread src/lib/onboard/local-model-profile/onboarder.ts Fixed
Comment thread src/lib/inference/llama-cpp/managed-installer.ts Fixed
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts Fixed
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts Fixed
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts Fixed
Comment thread src/lib/inference/local-model-profile/cleanup.ts Fixed
Comment thread src/lib/inference/serving/vllm-host-local-lifecycle.test.ts Fixed
Comment thread src/lib/inference/serving/vllm-host-local-lifecycle.test.ts Fixed
Comment thread src/lib/inference/vllm.ts Fixed
Comment thread src/lib/onboard/local-model-profile/onboarder.ts Fixed
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

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

🧹 Nitpick comments (15)
src/lib/actions/uninstall/run-plan-local-model-profile.test.ts (1)

130-153: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a case for a failing cleanup child.

This case proves the success path only. removeHostLocalModelRuntimes in run-plan.ts lines 1444-1448 aborts the whole uninstall when the cleanup child exits nonzero, and that guard is the reason ownership failures cannot be reported as a successful uninstall. Add a case where runLocalModelRuntimeCleanup returns notFound(), then assert exitCode is 1, assert the error contains "Host-local model cleanup did not complete", and assert that runDocker never received an rm argument.

🤖 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/uninstall/run-plan-local-model-profile.test.ts` around lines
130 - 153, Add a failing-cleanup test alongside the existing success case for
runUninstallPlan, configuring runLocalModelRuntimeCleanup to return notFound().
Assert the result has exitCode 1, its error includes “Host-local model cleanup
did not complete,” and the injected runDocker mock never receives an rm
argument.
src/lib/inference/llama-cpp/managed-installer.ts (1)

562-562: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Make the discarded validation call explicit.

Line 562 calls readPrivateRegularFile and drops the result. The call only exists to fail closed when an existing runtime.json is not an owner-only regular file. A future reader can remove it as dead code. Assign the result or add a short comment that states the intent.

♻️ Proposed clarification
-    readPrivateRegularFile(path.join(privateStateDir, MANAGED_LLAMA_CPP_RUNTIME_RECEIPT_FILE));
+    // Fail closed when a prior runtime receipt exists with unsafe ownership or mode.
+    readPrivateRegularFile(path.join(privateStateDir, MANAGED_LLAMA_CPP_RUNTIME_RECEIPT_FILE));
🤖 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/inference/llama-cpp/managed-installer.ts` at line 562, Make the
intentional discarded result of readPrivateRegularFile in the managed installer
explicit by assigning it to an appropriately named unused variable or adding a
concise comment explaining that the call validates the existing runtime receipt
and fails closed when it is not owner-only regular. Preserve the current
validation behavior.
src/lib/inference/llama-cpp/managed-installer.test.ts (2)

107-112: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the redundant environment unstub.

The cli Vitest project already enables unstubEnvs, so vi.unstubAllEnvs() repeats work the project isolation performs. Keep only the temporary-directory removal, which Vitest does not manage.

♻️ Proposed simplification
 afterEach(() => {
-  vi.unstubAllEnvs();
   for (const directory of temporaryDirectories.splice(0)) {
     fs.rmSync(directory, { force: true, recursive: true });
   }
 });

Based on learnings: Vitest test files under src are executed by the cli Vitest project, which enables clearMocks, restoreMocks, unstubEnvs, and unstubGlobals; suite-level teardown should only clean up resources Vitest does not manage.

🤖 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/inference/llama-cpp/managed-installer.test.ts` around lines 107 -
112, Remove the redundant vi.unstubAllEnvs() call from the afterEach teardown in
managed-installer.test.ts, leaving the temporaryDirectories cleanup loop intact
because Vitest does not manage those filesystem resources.

Source: Learnings


114-241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the foreign-ownership abort paths.

installManagedLlamaCpp returns { ok: false } when the container name or the network name carries foreign labels (managed-installer.ts lines 570-576). No test exercises those branches. That guard prevents the installer from removing or reusing a resource it does not own, so it needs a test. Add cases where dockerCaptureImpl returns a row with a mismatched generation label or a missing owner label, and assert that dockerForceRmImpl and dockerRunImpl are not called.

The readiness-timeout branch (lines 662-672) is also uncovered. Consider a case where probeImpl always returns a failure and now advances past the deadline.

🤖 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/inference/llama-cpp/managed-installer.test.ts` around lines 114 -
241, The managed installer tests lack coverage for foreign-owned resource aborts
and readiness timeout. Add tests around installManagedLlamaCpp where
dockerCaptureImpl reports a container or network with a mismatched generation
label or missing owner label, asserting the result is unsuccessful and neither
dockerForceRmImpl nor dockerRunImpl is called; also cover the readiness-timeout
path with probeImpl always failing and now advancing beyond the deadline.
src/lib/actions/uninstall/run-plan.ts (1)

1471-1475: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the reserved managed-inference-name pattern into one constant.

This regex is repeated verbatim at lines 1492-1494. The two uses are coupled: this one aborts uninstall when a managed container remains, and the other excludes the same names from generic docker rm -f. If one copy changes, a managed inference container becomes eligible for generic force removal and bypasses the ownership-aware cleanup path.

The literal also duplicates MANAGED_LLAMA_CPP_CONTAINER_NAME from src/lib/inference/llama-cpp/managed-installer.ts line 31 and the vLLM container names. Define one exported pattern or name list and use it in both places.

🤖 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/uninstall/run-plan.ts` around lines 1471 - 1475, Extract the
repeated managed-inference container-name regex into one exported constant or
name list, including the llama-cpp and vLLM names plus the rank pattern. Update
both the residual-container check and the generic docker removal exclusion in
the uninstall flow to reuse this shared symbol, and align it with
MANAGED_LLAMA_CPP_CONTAINER_NAME and the existing vLLM container names.
src/lib/inference/local-model-profile/cleanup.test.ts (1)

211-244: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the cache-deletion abort guards.

removeOwnedLlamaCppCache performs a recursive delete. Two guards protect it and neither has a test:

  • An entry whose name does not match ^sha256-[a-f0-9]{64}$, or an entry that is not a directory, must abort the whole operation before any deletion (cleanup.ts lines 316-318).
  • A symlinked path component must abort (realOwnerDirectory, cleanup.ts line 122).

Add a case that places a stray file and a symlinked entry inside the cache root, then assert { ok: false } and that the valid entry still exists.

🤖 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/inference/local-model-profile/cleanup.test.ts` around lines 211 -
244, Add a cleanupLocalModelRuntimes test covering both cache-deletion guards:
create a valid receipt-bound entry plus a stray file or invalidly
named/non-directory entry and a symlinked path component under the cache root,
then assert the result is { ok: false }, no deletion occurs, and the valid entry
remains. Use the existing home/cache setup and dependency mocks from the nearby
test.
src/lib/inference/local-model-profile/cleanup.ts (3)

187-271: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

Share the runtime-receipt schema between the writer and the reader.

src/lib/inference/llama-cpp/managed-installer.ts lines 203-216 writes runtime.json from an inline object literal. This function validates the same document with an inline 60-line predicate and about 30 as Record<string, unknown> casts. No shared type or schema links the two sides, so a field rename or an added field in the installer surfaces only as an uninstall failure on a user machine.

The repository already has the pattern to follow: src/lib/inference/llama-cpp/gguf-cache-receipt.ts exports a constructor and a verifier for the cache receipt. Add an equivalent module for the host-local runtime receipt that exports the typed shape, a create... function used by the installer, and a verify... function used here. That change also removes the cast noise and makes the required-key set a single declaration.

🤖 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/inference/local-model-profile/cleanup.ts` around lines 187 - 271,
Extract the host-local runtime receipt shape and validation from
llamaCppRuntimeReceipt into a shared module, following the constructor/verifier
pattern of gguf-cache-receipt.ts. Export the typed receipt shape plus create and
verify functions; update managed-installer.ts to build receipts through the
constructor and update llamaCppRuntimeReceipt to call the verifier, preserving
the existing ownership, authentication, container, network, runtime, and model
validation behavior while centralizing the exact required keys.

63-110: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Docker ownership inspection is implemented three times. The install path and the cleanup path each reimplement the same contract: capture docker inspect with ignoreError, parse the JSON, require exactly one row, verify the resource name, verify the id against ^[a-f0-9]{12,64}$, verify the owner and identity labels, and classify the result as absent, foreign, or owned. These checks decide whether NemoClaw reuses a Docker resource and whether it deletes one, so the implementations must not drift.

  • src/lib/inference/local-model-profile/cleanup.ts#L63-L110: promote inspectOwnedResource into a shared module, keep the container and network handling, and import it here.
  • src/lib/inference/llama-cpp/managed-installer.ts#L457-L534: delete ownedNetwork and ownedContainerId, and call the shared helper with the owner label plus the generation and auth-fingerprint labels.
🤖 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/inference/local-model-profile/cleanup.ts` around lines 63 - 110,
Centralize the duplicated Docker ownership inspection contract. In
src/lib/inference/local-model-profile/cleanup.ts lines 63-110, move
inspectOwnedResource into a shared module while preserving container/network
handling, then import it here. In
src/lib/inference/llama-cpp/managed-installer.ts lines 457-534, remove
ownedNetwork and ownedContainerId and use the shared helper with the owner,
generation, and auth-fingerprint labels.

356-363: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Use DUAL_STATION_VLLM_ROLE_LABEL in cleanup.

src/lib/inference/vllm-station-cluster-lifecycle.ts already exports the label used for dual-station containers. Import it in cleanup.ts instead of duplicating the string. This keeps cleanup synchronized with the producer and prevents role detection from drifting.

🤖 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/inference/local-model-profile/cleanup.ts` around lines 356 - 363,
Update cleanup.ts to import and use the existing DUAL_STATION_VLLM_ROLE_LABEL
from vllm-station-cluster-lifecycle.ts in the labels lookup within the cleanup
logic, replacing the duplicated literal string while preserving the current
head/worker role handling.
src/lib/onboard/local-model-profile/plan.ts (1)

59-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse the registry predicates instead of re-declaring the refs.

isHostLocalVllmRecipe hardcodes "vllm.host-local/v1" and "vllm.host-local.lifecycle/v1". src/lib/inference/serving/adapter-registry.ts already owns those refs as HOST_LOCAL_VLLM_MATERIALIZER_REF and HOST_LOCAL_VLLM_LIFECYCLE_REF and exports isHostLocalInferenceServingRecipe at line 126. isLlamaCppRecipe likewise re-declares the backend and provider literals that isLlamaCppServingRecipe already covers for the catalog validator.

That creates a second source of truth. If a ref is versioned later, this file keeps compiling and the profile fails at runtime with "selects an incompatible serving recipe" instead of failing at the registry.

Import the registry predicates and delete the local copies.
As per coding guidelines: "Use existing repository vocabulary and one name per concept".

🤖 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/onboard/local-model-profile/plan.ts` around lines 59 - 89, Replace
the local isHostLocalVllmRecipe and isLlamaCppRecipe implementations with
imports of the existing isHostLocalInferenceServingRecipe and
isLlamaCppServingRecipe predicates from the serving adapter registry. Remove the
duplicate local predicates and any now-unused imports, preserving all existing
call sites and type-guard behavior.

Source: Coding guidelines

src/lib/onboard/setup-nim-flow.ts (1)

536-554: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the self-assigning destructuring fallback with a conditional block.

The fallback object at Lines 545-553 assigns each variable to itself, so it exists only to make the destructuring form valid when localModelState is null. Line 554 then assigns undefined to vllmModelIdentity on that same path, which is already its value. A guarded block states the intent directly and removes the no-op branch.

♻️ Proposed refactor
     const localModelState = localModelProfile.state;
-    ({
-      model,
-      provider,
-      endpointUrl,
-      credentialEnv,
-      preferredInferenceApi,
-      nimContainer,
-      allowToolsIncompatible,
-    } = localModelState ?? {
-      model,
-      provider,
-      endpointUrl,
-      credentialEnv,
-      preferredInferenceApi,
-      nimContainer,
-      allowToolsIncompatible,
-    });
-    vllmModelIdentity = localModelState?.vllmModelIdentity;
+    if (localModelState) {
+      ({
+        model,
+        provider,
+        endpointUrl,
+        credentialEnv,
+        preferredInferenceApi,
+        nimContainer,
+        allowToolsIncompatible,
+      } = localModelState);
+      vllmModelIdentity = localModelState.vllmModelIdentity;
+    }
🤖 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/onboard/setup-nim-flow.ts` around lines 536 - 554, Replace the
self-referential fallback destructuring in the local model state handling with a
conditional block that destructures and assigns model state fields only when
localModelState is present. Preserve the existing values when it is absent, and
keep vllmModelIdentity assigned from localModelState?.vllmModelIdentity.
src/lib/inference/serving/adapter-registry.ts (2)

396-412: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract one bounded-safe-text helper.

Both branches repeat the same allowlist regex and the same includes("\0") check with only the byte cap differing. The allowlist already excludes the null byte, so includes("\0") can never decide the result. Extract a single helper to remove the duplication and the unreachable check.

♻️ Proposed refactor
+const SAFE_SERVING_TEXT = /^[A-Za-z0-9_@%+=:,./-]+$/u;
+
+function boundedSafeText(value: string, maximumBytes: number): boolean {
+  return Buffer.byteLength(value, "utf8") <= maximumBytes && SAFE_SERVING_TEXT.test(value);
+}
   if (
     recipe.spec.serve.arguments.some(
-      ({ value }) =>
-        typeof value === "string" &&
-        (Buffer.byteLength(value, "utf8") > 16_384 ||
-          value.includes("\0") ||
-          !/^[A-Za-z0-9_@%+=:,./-]+$/u.test(value)),
+      ({ value }) => typeof value === "string" && !boundedSafeText(value, 16_384),
     ) ||
-    Object.values(recipe.spec.runtime.environment).some(
-      (value) =>
-        Buffer.byteLength(value, "utf8") > 4_096 ||
-        value.includes("\0") ||
-        !/^[A-Za-z0-9_@%+=:,./-]+$/u.test(value),
-    )
+    Object.values(recipe.spec.runtime.environment).some((value) => !boundedSafeText(value, 4_096))
   ) {
     return "host-local vLLM serving values must be bounded safe text";
   }
🤖 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/inference/serving/adapter-registry.ts` around lines 396 - 412, In the
validation around recipe.spec.serve.arguments and
recipe.spec.runtime.environment, extract a shared bounded-safe-text helper that
accepts a value and byte limit, applies the existing allowlist regex and cap,
and removes the redundant null-byte checks. Replace both inline predicates with
calls to this helper while preserving the 16,384-byte and 4,096-byte limits.

367-381: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Validate serving argument names, not only their values.

The validator checks argument names against HOST_LOCAL_MATERIALIZER_OWNED_ARGUMENTS and checks argument values against the safe-text allowlist. It never checks that a name has a safe flag shape. A future recipe could declare a name with whitespace, a null byte, or a leading value, and it would pass this validator and reach the container argv unchanged.

Add a flag-name pattern check next to the owned-argument check.

♻️ Proposed refactor

Add a constant next to the other patterns:

 const SAFE_ENVIRONMENT_NAME = /^[A-Z][A-Z0-9_]{0,127}$/u;
+const SAFE_SERVING_ARGUMENT_NAME = /^--[a-z0-9]+(?:-[a-z0-9]+)*$/u;

Then extend the check:

   if (
     recipe.spec.serve.arguments.some(({ name }) =>
-      HOST_LOCAL_MATERIALIZER_OWNED_ARGUMENTS.has(name),
+      HOST_LOCAL_MATERIALIZER_OWNED_ARGUMENTS.has(name) || !SAFE_SERVING_ARGUMENT_NAME.test(name),
     )
   ) {
-    return "host-local vLLM recipe overrides a materializer-owned serving argument";
+    return "host-local vLLM recipe uses an unsupported or materializer-owned serving argument";
   }
🤖 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/inference/serving/adapter-registry.ts` around lines 367 - 381, Update
the serving-argument validation near HOST_MATERIALIZER_OWNED_ARGUMENTS to
validate each argument name against a safe flag-name pattern, rejecting names
with whitespace, null bytes, leading values, or other invalid shapes before
container argv construction. Preserve the existing materializer-owned argument
rejection and value validation behavior, and define the pattern alongside the
existing validation constants.
src/lib/onboard/local-model-profile/onboarder.ts (2)

4-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the LocalModelVllmProfile alias and import the installer type only.

Two points in this block:

  • Line 12 introduces LocalModelVllmProfile as a second name for VllmProfile. integration.ts Line 11 re-exports it, but no consumer uses the alias. It adds a second name for one concept.
  • Line 4 imports the value installManagedLlamaCpp only to derive typeof installManagedLlamaCpp at Line 24. Use import type so this module does not pull the managed installer into its runtime import graph. The onboarder receives the installer through deps.
♻️ Proposed changes
-import { installManagedLlamaCpp } from "../../inference/llama-cpp/managed-installer";
+import type { installManagedLlamaCpp } from "../../inference/llama-cpp/managed-installer";
 import { materializeHostLocalVllmSelection } from "../../inference/serving/host-local-vllm-selection";
 import type { ResolvedHostLocalInferenceSelection } from "../../inference/serving/types";
 import type { VllmProfile } from "../../inference/vllm";
 import { VLLM_EXTRA_ARGS_ENV } from "../../inference/vllm-models";
 import type { SetupNimSelectionResult, SetupNimSelectionState } from "../setup-nim-flow";
 import type { LocalModelProfilePlan } from "./plan";
 
-export type LocalModelVllmProfile = VllmProfile;
-

Then drop LocalModelVllmProfile from the export type block in src/lib/onboard/local-model-profile/integration.ts Lines 9-12.

As per coding guidelines: "Use existing repository vocabulary and one name per concept" and "Do not add configuration, fallback, migration, compatibility, or extension layers without a current requirement; identify the current consumer and protecting test".

🤖 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/onboard/local-model-profile/onboarder.ts` around lines 4 - 12, Remove
the unused LocalModelVllmProfile alias from onboarder.ts and its re-export from
the integration.ts export type block, keeping VllmProfile as the sole type name.
Change the installManagedLlamaCpp import to a type-only import because it is
used only for typeof in the onboarder dependency typing, while preserving
runtime injection through deps.

Source: Coding guidelines


66-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Inject the environment instead of reading process.env directly.

resolveLocalModelProfilePlan in plan.ts Line 94 accepts an injectable env parameter. This override check reads process.env directly, so a test can only exercise the rejection branch by mutating the real environment and then undoing the stub. Add an optional env field to LocalModelProfileOnboarderDeps that defaults to process.env, and read the three override variables from it. That matches the injection style already used in this feature area and keeps the tests deterministic.

As per coding guidelines: "deterministic tests must clear mock calls, restore spies, undo environment/global stubs".

🤖 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/onboard/local-model-profile/onboarder.ts` around lines 66 - 70, Add
an optional env dependency to LocalModelProfileOnboarderDeps, defaulting to
process.env, and use that injected object in the override check within
resolveLocalModelProfilePlan’s onboarding flow for NEMOCLAW_VLLM_MODEL,
VLLM_EXTRA_ARGS_ENV, and NEMOCLAW_VLLM_PORT. Preserve the existing rejection
behavior while allowing tests to supply a deterministic environment without
mutating process.env.

Source: Coding guidelines

🤖 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 `@managed-inference/presets/local-model-profile.vllm.spark.v1.yaml`:
- Around line 16-68: Add a host.gpu.driver_version observation requirement to
the requirements.all list in the vLLM preset, requiring version 580.65.06 or
later using the existing readiness comparison conventions. Keep the current
qualification and capability requirements unchanged.

In `@src/lib/inference/local-model-profile/cleanup-entry.ts`:
- Around line 11-14: Update the cleanup flow around cleanupLocalModelRuntimes so
the removed and preserved resource lists are printed before handling result.ok
failure. Preserve both reporting loops for successful and failed results, then
throw result.reason after reporting when cleanup fails.

In `@src/lib/inference/local-model-profile/cleanup.test.ts`:
- Line 103: Update the run stub in the cleanup test to remove the no-op argv
conditional and return 0 directly, since both branches currently produce the
same result. Keep the stub signature and surrounding test behavior unchanged.
- Around line 196-209: Update the Docker-unavailable test around
cleanupLocalModelRuntimes to provide explicit stubs for both capture and forceRm
alongside run, preventing fallback to real Docker adapters. Assert the injected
capture and forceRm dependencies are never called while preserving the existing
unavailable-Docker failure assertion.

In `@src/lib/inference/serving/catalog.ts`:
- Around line 523-527: Update the error message in the preset selection guard
within the serving catalog validation flow to state that selection must not be
automatic, reflecting that both explicit-only and disabled values are accepted.
Preserve the existing automatic-selection condition and error behavior.

In `@src/lib/onboard/local-model-profile/onboarder.ts`:
- Around line 76-87: Update the materialization flow in
runDedicatedLocalModelProfile so errors thrown by
materializeHostLocalVllmSelection are caught and reported through the existing
operator-facing error path, then return "retry-selection". Ensure the catch
covers handleLocalModelProfile rather than only resolveLocalModelProfilePlan,
preventing the materialization exception from escaping setupNim as an unhandled
rejection.

---

Nitpick comments:
In `@src/lib/actions/uninstall/run-plan-local-model-profile.test.ts`:
- Around line 130-153: Add a failing-cleanup test alongside the existing success
case for runUninstallPlan, configuring runLocalModelRuntimeCleanup to return
notFound(). Assert the result has exitCode 1, its error includes “Host-local
model cleanup did not complete,” and the injected runDocker mock never receives
an rm argument.

In `@src/lib/actions/uninstall/run-plan.ts`:
- Around line 1471-1475: Extract the repeated managed-inference container-name
regex into one exported constant or name list, including the llama-cpp and vLLM
names plus the rank pattern. Update both the residual-container check and the
generic docker removal exclusion in the uninstall flow to reuse this shared
symbol, and align it with MANAGED_LLAMA_CPP_CONTAINER_NAME and the existing vLLM
container names.

In `@src/lib/inference/llama-cpp/managed-installer.test.ts`:
- Around line 107-112: Remove the redundant vi.unstubAllEnvs() call from the
afterEach teardown in managed-installer.test.ts, leaving the
temporaryDirectories cleanup loop intact because Vitest does not manage those
filesystem resources.
- Around line 114-241: The managed installer tests lack coverage for
foreign-owned resource aborts and readiness timeout. Add tests around
installManagedLlamaCpp where dockerCaptureImpl reports a container or network
with a mismatched generation label or missing owner label, asserting the result
is unsuccessful and neither dockerForceRmImpl nor dockerRunImpl is called; also
cover the readiness-timeout path with probeImpl always failing and now advancing
beyond the deadline.

In `@src/lib/inference/llama-cpp/managed-installer.ts`:
- Line 562: Make the intentional discarded result of readPrivateRegularFile in
the managed installer explicit by assigning it to an appropriately named unused
variable or adding a concise comment explaining that the call validates the
existing runtime receipt and fails closed when it is not owner-only regular.
Preserve the current validation behavior.

In `@src/lib/inference/local-model-profile/cleanup.test.ts`:
- Around line 211-244: Add a cleanupLocalModelRuntimes test covering both
cache-deletion guards: create a valid receipt-bound entry plus a stray file or
invalidly named/non-directory entry and a symlinked path component under the
cache root, then assert the result is { ok: false }, no deletion occurs, and the
valid entry remains. Use the existing home/cache setup and dependency mocks from
the nearby test.

In `@src/lib/inference/local-model-profile/cleanup.ts`:
- Around line 187-271: Extract the host-local runtime receipt shape and
validation from llamaCppRuntimeReceipt into a shared module, following the
constructor/verifier pattern of gguf-cache-receipt.ts. Export the typed receipt
shape plus create and verify functions; update managed-installer.ts to build
receipts through the constructor and update llamaCppRuntimeReceipt to call the
verifier, preserving the existing ownership, authentication, container, network,
runtime, and model validation behavior while centralizing the exact required
keys.
- Around line 63-110: Centralize the duplicated Docker ownership inspection
contract. In src/lib/inference/local-model-profile/cleanup.ts lines 63-110, move
inspectOwnedResource into a shared module while preserving container/network
handling, then import it here. In
src/lib/inference/llama-cpp/managed-installer.ts lines 457-534, remove
ownedNetwork and ownedContainerId and use the shared helper with the owner,
generation, and auth-fingerprint labels.
- Around line 356-363: Update cleanup.ts to import and use the existing
DUAL_STATION_VLLM_ROLE_LABEL from vllm-station-cluster-lifecycle.ts in the
labels lookup within the cleanup logic, replacing the duplicated literal string
while preserving the current head/worker role handling.

In `@src/lib/inference/serving/adapter-registry.ts`:
- Around line 396-412: In the validation around recipe.spec.serve.arguments and
recipe.spec.runtime.environment, extract a shared bounded-safe-text helper that
accepts a value and byte limit, applies the existing allowlist regex and cap,
and removes the redundant null-byte checks. Replace both inline predicates with
calls to this helper while preserving the 16,384-byte and 4,096-byte limits.
- Around line 367-381: Update the serving-argument validation near
HOST_MATERIALIZER_OWNED_ARGUMENTS to validate each argument name against a safe
flag-name pattern, rejecting names with whitespace, null bytes, leading values,
or other invalid shapes before container argv construction. Preserve the
existing materializer-owned argument rejection and value validation behavior,
and define the pattern alongside the existing validation constants.

In `@src/lib/onboard/local-model-profile/onboarder.ts`:
- Around line 4-12: Remove the unused LocalModelVllmProfile alias from
onboarder.ts and its re-export from the integration.ts export type block,
keeping VllmProfile as the sole type name. Change the installManagedLlamaCpp
import to a type-only import because it is used only for typeof in the onboarder
dependency typing, while preserving runtime injection through deps.
- Around line 66-70: Add an optional env dependency to
LocalModelProfileOnboarderDeps, defaulting to process.env, and use that injected
object in the override check within resolveLocalModelProfilePlan’s onboarding
flow for NEMOCLAW_VLLM_MODEL, VLLM_EXTRA_ARGS_ENV, and NEMOCLAW_VLLM_PORT.
Preserve the existing rejection behavior while allowing tests to supply a
deterministic environment without mutating process.env.

In `@src/lib/onboard/local-model-profile/plan.ts`:
- Around line 59-89: Replace the local isHostLocalVllmRecipe and
isLlamaCppRecipe implementations with imports of the existing
isHostLocalInferenceServingRecipe and isLlamaCppServingRecipe predicates from
the serving adapter registry. Remove the duplicate local predicates and any
now-unused imports, preserving all existing call sites and type-guard behavior.

In `@src/lib/onboard/setup-nim-flow.ts`:
- Around line 536-554: Replace the self-referential fallback destructuring in
the local model state handling with a conditional block that destructures and
assigns model state fields only when localModelState is present. Preserve the
existing values when it is absent, and keep vllmModelIdentity assigned from
localModelState?.vllmModelIdentity.
🪄 Autofix

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: f6384930-6127-4ae3-87b7-2f0372bf5cf1

📥 Commits

Reviewing files that changed from the base of the PR and between b148bc1 and f709b28.

📒 Files selected for processing (37)
  • docs/inference/choose-local-inference-server.mdx
  • docs/reference/commands.mdx
  • docs/reference/host-files-and-state.mdx
  • managed-inference/presets/local-model-profile.llama-cpp.spark.v1.yaml
  • managed-inference/presets/local-model-profile.vllm.spark.v1.yaml
  • managed-inference/recipes/vllm.qwen3-6-35b-a3b-nvfp4.spark-single.v1.yaml
  • managed-inference/schemas/preset.schema.json
  • scripts/install.sh
  • src/lib/actions/uninstall/run-plan-local-model-profile.test.ts
  • src/lib/actions/uninstall/run-plan.ts
  • src/lib/adapters/docker/local-model-runtime.ts
  • src/lib/inference/llama-cpp/host-local-runtime.ts
  • src/lib/inference/llama-cpp/managed-installer.test.ts
  • src/lib/inference/llama-cpp/managed-installer.ts
  • src/lib/inference/local-model-profile/cleanup-entry.ts
  • src/lib/inference/local-model-profile/cleanup.test.ts
  • src/lib/inference/local-model-profile/cleanup.ts
  • src/lib/inference/local.ts
  • src/lib/inference/serving/adapter-registry.ts
  • src/lib/inference/serving/catalog.ts
  • src/lib/inference/serving/host-local-vllm-selection.ts
  • src/lib/inference/serving/types.ts
  • src/lib/inference/serving/vllm-host-local-lifecycle.test.ts
  • src/lib/inference/serving/vllm-host-local-lifecycle.ts
  • src/lib/inference/serving/vllm-managed-support.ts
  • src/lib/inference/vllm-models.ts
  • src/lib/inference/vllm.ts
  • src/lib/onboard.ts
  • src/lib/onboard/local-model-profile/integration.ts
  • src/lib/onboard/local-model-profile/onboarder.test.ts
  • src/lib/onboard/local-model-profile/onboarder.ts
  • src/lib/onboard/local-model-profile/plan.test.ts
  • src/lib/onboard/local-model-profile/plan.ts
  • src/lib/onboard/setup-nim-flow.test.ts
  • src/lib/onboard/setup-nim-flow.ts
  • test/install-local-model-profile.test.ts
  • test/onboard-selection.test.ts

Comment thread managed-inference/presets/local-model-profile.vllm.spark.v1.yaml
Comment thread src/lib/inference/local-model-profile/cleanup-entry.ts
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts Outdated
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts
Comment thread src/lib/inference/serving/catalog.ts
Comment thread src/lib/onboard/local-model-profile/onboarder.ts Outdated
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

@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/uninstall/run-plan-local-model-profile.test.ts`:
- Around line 50-66: Update the runDocker mock in the local model profile
uninstall test to match complete expected Docker argument lists, including both
recognized ps inventory queries, and throw or otherwise fail for any
unrecognized ps request or non-ps command instead of returning ok(). Preserve
the existing explicit inventory responses used by the cleanup behavior under
test.
🪄 Autofix

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: 5d8ae271-bfa6-4462-8cf8-005391539699

📥 Commits

Reviewing files that changed from the base of the PR and between ff9f532 and d9f4437.

📒 Files selected for processing (3)
  • src/lib/actions/uninstall/run-plan-local-model-profile.test.ts
  • src/lib/inference/llama-cpp/managed-installer.test.ts
  • src/lib/inference/local-model-profile/cleanup.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/inference/llama-cpp/managed-installer.test.ts
  • src/lib/inference/local-model-profile/cleanup.test.ts

Comment thread src/lib/actions/uninstall/run-plan-local-model-profile.test.ts Outdated
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts Fixed
Comment thread src/lib/inference/local-model-profile/cleanup.test.ts Fixed
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Comment thread src/lib/inference/serving/runtime-auth-fingerprint.ts Fixed
ericksoa and others added 5 commits August 5, 2026 14:48
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
prekshivyas and others added 2 commits August 5, 2026 17:13
@copy-pr-bot

copy-pr-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@prekshivyas
prekshivyas merged commit 35b15d5 into main Aug 6, 2026
63 of 64 checks passed
@prekshivyas
prekshivyas deleted the feat/fixed-local-serving-profiles branch August 6, 2026 02:40
@github-actions github-actions Bot added the v0.0.104 Release target label Aug 6, 2026
cv pushed a commit that referenced this pull request Aug 6, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Adds discoverable serving profiles and carries the exact selected
catalog preset and recipe identity through onboarding review, resume,
status, diagnostics, recovery, and uninstall. Existing automatic
defaults remain unchanged when no profile is selected, and legacy
sessions and unlabeled runtimes remain compatible.

## Related Issues

Fixes #8246
Fixes #8384
Parent epic: #8379

## Changes

- Add human and JSON `profiles list` discovery with stable IDs, display
names, backend, model, topology, selection mode, support state, download
estimates, and compatibility reasons.
- Add model-independent `onboard --profile <id-or-display-name>`
selection, with terminal-safe errors for unknown, ambiguous, disabled,
incompatible, or conflicting selections before effects.
- Show the selected profile, recipe, support state, runtime image, and
download estimates on the review screen.
- Persist secret-free catalog, preset, recipe, model, runtime-image, and
digest provenance in onboarding sessions and sandbox registry records.
- Automatically reuse the recorded profile on resume, reject selection
or catalog drift before effects, and preserve legacy resume behavior
when provenance is absent.
- Expose profile and recipe provenance in human status, JSON status, and
debug diagnostics.
- Bind host-local vLLM recovery and uninstall to an owner-only receipt
containing exact container, authentication, and serving-profile
identity; retain compatibility with legacy authenticated unlabeled
runtimes.
- Build on the fixed local vLLM and llama.cpp catalog profiles from
#8399; this PR is stacked on that dependency and carries only the
generic lifecycle/provenance delta.
- Document discovery, review, resume, status, recovery, uninstall, and
legacy behavior.

Station catalog migration and physical hardware qualification remain
separately tracked under the parent epic.

## Type of Change

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

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Local implementation
and independent final review covered secret-free provenance, environment
restoration, authenticated loopback runtime ownership, recovery drift
rejection, and fail-closed uninstall boundaries.
- [ ] 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: The isolated implementation and documentation, reviewed
against exact #8399 base `7c25b6175` for profile discovery, review,
immutable provenance, resume drift rejection, status/diagnostics,
authenticated recovery, legacy compatibility, and ownership-aware
uninstall were reviewed. `npm run docs`, focused profile tests, `git
diff --check`, and privacy checks passed; no private or unannounced
model details or credentials were added.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 33eb0c0 -->
<!-- docs-review-agents-blob-sha: c69aad4 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable.
- Station profile/scenario: Not applicable; tracked separately under
#8379.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every authored
commit is signed and includes DCO sign-off
- [x] Normal pre-commit and pre-push hooks passed
- [x] Targeted behavior tests pass — 13 focused suites passed with 317
tests, including discovery, selection, review, session persistence,
resume drift, registry/status, recovery receipts, and uninstall
ownership
- [x] Applicable broad gates passed — repository checks, CLI typecheck,
catalog compile/check, documentation build, and diff checks
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [x] `npm run docs` builds without errors (Fern reported 2 existing
unprinted warnings)
- [x] Doc pages follow the documentation style guide
- [ ] New doc pages include SPDX header and frontmatter (no new pages)

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



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

## Summary by CodeRabbit

* **New Features**
* Added `profiles:list` to discover installed serving profiles, view
compatibility, and output results as text or JSON.
* Added managed local-model onboarding for vLLM and llama.cpp on
supported DGX Spark systems.
* Added profile selection by ID or name, validation, resume tracking,
and configuration details.
* Added secure runtime installation, recovery, and ownership-aware
cleanup for local models.
  * Added host-local vLLM recovery and authenticated runtime management.

* **Documentation**
* Expanded setup, installer, local inference, host-state, onboarding,
and uninstall guidance.

* **Bug Fixes**
* Improved validation for conflicting options, incompatible profiles,
catalog changes, and unsafe cleanup scenarios.

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

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Co-authored-by: Aaron Erickson <aerickson@nvidia.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.0.104 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants