Skip to content

feat(onboard): activate portable runtime inference - #8753

Merged
jyaunches merged 2 commits into
mainfrom
codex/portable-runtime-inference
Aug 10, 2026
Merged

feat(onboard): activate portable runtime inference#8753
jyaunches merged 2 commits into
mainfrom
codex/portable-runtime-inference

Conversation

@senthilr-nv

@senthilr-nv senthilr-nv commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add an optional, single-use runtime inference descriptor for the portable experimental profile. A valid descriptor selects an OpenAI-compatible endpoint without exporting its API key; an absent descriptor preserves local qwen3-vl:4b behavior, and an existing local runner remains installed as manual standby.

Changes

  • Admit /run/nemoclaw/portable-inference.json only from a protected directory and a current-user-owned regular file with mode 0600 and one hard link.
  • Open without following links or blocking, bound reads to 64 KiB, reject schema, timestamp, endpoint, and SSRF-policy violations, and consume every admitted descriptor once.
  • Scope the descriptor API key to the onboarding asynchronous call tree so existing credential consumers can use it without adding it to process.env, child processes, persisted state, or credential listings. The current consumer is compatible-endpoint validation and OpenShell provider registration; scopes a runtime credential without exporting or enumerating it protects the boundary.
  • Select the compatible endpoint as the one active route when the descriptor is valid. OpenShell does not automatically fail over to the existing local runner.
  • Document activation, atomic publication, custody, cleanup, route behavior, and manual switching. Add negative tests for unsafe metadata, FIFO blocking, malformed content, impossible or expired timestamps, credential exposure, and rejected endpoints.

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: Maintainer security review passed for secret handling, strict input and filesystem admission, endpoint policy, process exposure, authorization boundary, redaction, dependencies, and runtime configuration.
  • 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: Updated docs/inference/set-up-openai-compatible-endpoint.mdx; reviewed the completed source, tests, terminology, structure, voice, and code-sample presentation against the implementation and repository writing rules.
  • 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 — feature validation passed 98 CLI tests and 52 integration tests; follow-up validation passed 73 CLI tests and 46 credential integration tests; npm run typecheck:cli passed.
  • Applicable broad gate passed — Not applicable; this focused onboarding and credential-boundary change is covered by targeted tests and path-scoped hooks.
  • 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 0 errors; 2 existing warnings remain.
  • 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

    • Added support for portable inference descriptors during onboarding.
    • Configures temporary custom endpoints, models, and runtime-only credentials.
    • Added secure descriptor validation, expiration checks, HTTPS endpoint validation, and cleanup after use.
    • Added scoped credential overrides that remain isolated from environment variables, persistence, and child processes.
  • Documentation

    • Expanded setup guidance for portable inference descriptors, including schema, security requirements, installation, validation, and cleanup.
  • Bug Fixes

    • Invalid or unsafe descriptors now fail onboarding cleanly without starting the process.

Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
@senthilr-nv senthilr-nv self-assigned this Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Portable inference descriptors can now activate custom endpoints during onboarding. The loader securely validates and consumes descriptor files. Scoped credential overrides keep API keys in asynchronous runtime state without exporting or persisting them. Tests and documentation cover activation, validation, and cleanup.

Changes

Portable inference onboarding

Layer / File(s) Summary
Secure descriptor loading
src/lib/onboard/experimental/portable-inference-descriptor.ts, src/lib/onboard/experimental/portable-inference-descriptor.test.ts
Adds descriptor contracts, filesystem checks, bounded reads, race detection, strict schema and endpoint validation, expiration checks, secure consumption, and comprehensive tests.
Scoped credential resolution
src/lib/credentials/scoped-overrides.ts, src/lib/credentials/store.ts, src/lib/onboard/credential-env.ts, test/credentials.test.ts
Adds asynchronous credential overrides. Credential lookup prioritizes scoped values without copying them to process.env, persistence, listings, or child processes.
Onboarding activation and validation
src/lib/onboard/command.ts, src/lib/onboard/command.test.ts, src/lib/onboard/inference-providers/remote-openai-surface.test.ts
Loads portable activation data, applies endpoint settings, scopes the API key during runOnboard, reports descriptor errors, and validates runtime credential cleanup.
Portable endpoint setup documentation
docs/inference/set-up-openai-compatible-endpoint.mdx
Documents descriptor requirements, installer commands, route behavior, endpoint checks, credential handling, and descriptor consumption.

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

Sequence Diagram(s)

sequenceDiagram
  participant OnboardCommand
  participant DescriptorLoader
  participant CredentialStore
  participant runOnboard
  OnboardCommand->>DescriptorLoader: Load portable inference descriptor
  DescriptorLoader-->>OnboardCommand: Return validated activation
  OnboardCommand->>CredentialStore: Apply scoped API-key override
  OnboardCommand->>runOnboard: Run onboarding with portable settings
  runOnboard->>CredentialStore: Resolve runtime credential
  CredentialStore-->>runOnboard: Return scoped API key
Loading

Possibly related PRs

Suggested labels: area: inference

Suggested reviewers: cv, apurvvkumaria, jyaunches

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 and concisely describes the primary change: activating portable runtime inference during onboarding.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/portable-runtime-inference

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

@github-code-quality

github-code-quality Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 91ccff7 in the codex/portable-runti... branch remains at 96%, unchanged from commit cae757e in the main branch.


Updated August 10, 2026 19:11 UTC

@github-actions

Copy link
Copy Markdown
Contributor

@senthilr-nv senthilr-nv added feature PR adds or expands user-visible functionality area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: providers Inference provider integrations and provider behavior provider: openai OpenAI API or OpenAI-compatible provider behavior security v0.0.106 labels Aug 10, 2026

@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

🧹 Nitpick comments (5)
src/lib/onboard/experimental/portable-inference-descriptor.test.ts (2)

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

Rely on project-level spy restoration.

The cli Vitest project enables restoreMocks, so the try/finally with openSpy.mockRestore() is redundant. You can keep the assertions and drop the wrapper.

♻️ Proposed simplification
     const openSpy = vi.spyOn(fs, "openSync");
 
-    try {
-      await expect(loadPortableInferenceDescriptor({ filePath, now: () => NOW })).rejects.toThrow(
-        /must be a regular file/,
-      );
-      expect(openSpy).not.toHaveBeenCalled();
-      expect(fs.lstatSync(filePath).isFIFO()).toBe(true);
-    } finally {
-      openSpy.mockRestore();
-    }
+    await expect(loadPortableInferenceDescriptor({ filePath, now: () => NOW })).rejects.toThrow(
+      /must be a regular file/,
+    );
+    expect(openSpy).not.toHaveBeenCalled();
+    expect(fs.lstatSync(filePath).isFIFO()).toBe(true);

Based on learnings: Vitest test files under src run in the cli project, which enables clearMocks, restoreMocks, unstubEnvs, and unstubGlobals, so suite teardown should only clean 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/onboard/experimental/portable-inference-descriptor.test.ts` around
lines 198 - 212, In the test “leaves a FIFO in place without opening it,” remove
the try/finally wrapper and the explicit openSpy.mockRestore() call, relying on
the cli Vitest project’s restoreMocks setting while preserving the existing
assertions and FIFO cleanup behavior.

Source: Learnings


82-112: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add negative cases for the apiKey format guard and the size limit.

The table covers JSON, expiry, extra fields, and query strings. It does not cover three guards in parseDescriptor and readDescriptorBytes:

  • apiKey that contains \n, \r, or \u0000, or that has surrounding whitespace (lines 220-226 of portable-inference-descriptor.ts).
  • model that contains a control character (lines 227-235).
  • A descriptor larger than DESCRIPTOR_MAX_BYTES (lines 127-129).

The apiKey guard blocks header and shell injection through the credential value. A regression there is silent without a test.

💚 Proposed additional cases
     ["an extra field", descriptor({ region: "us-test-1" }), /exactly these fields/],
+    [
+      "a newline-bearing API key",
+      descriptor({ apiKey: "secret\nX-Injected: 1" }),
+      /apiKey has an invalid length or format/,
+    ],
+    [
+      "a control character in the model",
+      descriptor({ model: "vendor/model\u0001" }),
+      /model has an invalid length or format/,
+    ],
+    [
+      "an oversized descriptor",
+      descriptor({ apiKey: "a".repeat(17 * 1024) }),
+      /apiKey has an invalid length or format/,
+    ],

As per path instructions for src/lib/{security,credentials,shields}/**-style security boundaries: "Require negative-path tests that prove the boundary rejects bypasses and does not leak secrets in errors, logs, state, or process arguments."

🤖 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/experimental/portable-inference-descriptor.test.ts` around
lines 82 - 112, Add negative cases to the parameterized tests around the
existing “deletes an admitted descriptor” test for apiKey values containing
newline, carriage return, NUL, or surrounding whitespace, a model containing a
control character, and a descriptor exceeding DESCRIPTOR_MAX_BYTES. Assert each
is rejected and the file is deleted, while ensuring invalid apiKey values are
not exposed in errors or other observable output.

Source: Path instructions

src/lib/onboard/experimental/portable-inference-descriptor.ts (1)

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

Include the errno code in the open failure message.

openDescriptor maps every non-ENOENT failure to one message. ELOOP, EACCES, and EMFILE then look identical to an operator. The errno code contains no secret, so you can report it.

♻️ Proposed change
   } catch (error) {
     if (isErrnoException(error) && error.code === "ENOENT") return null;
-    throw descriptorError(`cannot open ${filePath} without following links or blocking.`);
+    const code = isErrnoException(error) ? ` (${error.code ?? "unknown"})` : "";
+    throw descriptorError(
+      `cannot open ${filePath} without following links or blocking${code}.`,
+    );
   }
🤖 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/experimental/portable-inference-descriptor.ts` around lines
101 - 106, Update the non-ENOENT error path in openDescriptor to include the
caught errno code in the descriptorError message, while preserving the existing
ENOENT-to-null behavior and rethrowing all other failures as descriptor errors.
test/credentials.test.ts (1)

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

Remove the temporary HOME directory after the test.

Line 138 creates a directory with mkdtempSync and never removes it. Each run leaves a directory in the system temp location. Vitest does not manage filesystem resources, so this test must clean it up.

♻️ Proposed fix
   it("scopes a runtime credential without exporting or enumerating it", async () => {
     const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-creds-"));
-    const credentials = await importCredentialsModule(home);
+    try {
+      const credentials = await importCredentialsModule(home);
+      // ... existing body ...
+    } finally {
+      fs.rmSync(home, { recursive: true, force: true });
+    }

If the surrounding suite already removes these directories in a shared hook, disregard this comment.

Based on learnings: in suite-level teardown, clean up only resources Vitest does not manage, for example temporary directories and files.

🤖 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 `@test/credentials.test.ts` around lines 137 - 139, Update the test containing
the runtime credential case and its suite teardown to remove the directory
created by mkdtempSync after the test completes, using the existing home
variable and a guaranteed cleanup hook or try/finally; preserve the test
behavior and avoid duplicating cleanup if a shared hook already handles it.

Source: Learnings

src/lib/onboard/command.test.ts (1)

544-548: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a case for a portable run with no descriptor, and inject the loader.

Two related gaps:

  1. No test covers loadPortableInferenceDescriptor resolving null for a portable profile. That is the documented default path, in which NEMOCLAW_PROVIDER stays ollama and NEMOCLAW_MODEL stays qwen3-vl:4b (src/lib/onboard/command.ts, lines 438-441).

  2. activatePortableInference now runs for every portable test in this file. The existing portable-defaults test at lines 506-522 does not inject loadPortableInferenceDescriptor, so it calls the real loader against /run/nemoclaw/portable-inference.json. On a machine that has a descriptor at that path, the test consumes and deletes it and its assertions change. Inject a loader that returns null there to keep the test hermetic.

💚 Proposed additional case
+  it("keeps local portable defaults when no descriptor is present", async () => {
+    const env: NodeJS.ProcessEnv = {};
+    const runOnboard = vi.fn(async (options) => {
+      expect(options.portableInferenceActivation).toBeNull();
+      expect(env).toMatchObject({
+        NEMOCLAW_PROVIDER: "ollama",
+        NEMOCLAW_MODEL: "qwen3-vl:4b",
+      });
+      expect(env.NEMOCLAW_ENDPOINT_URL).toBeUndefined();
+      expect(env.NEMOCLAW_PREFERRED_API).toBeUndefined();
+    });
+
+    await runOnboardCommand({
+      flags: { "experimental-profile": "portable" },
+      env,
+      loadPortableInferenceDescriptor: async () => null,
+      runOnboard,
+    });
+
+    expect(runOnboard).toHaveBeenCalledOnce();
+  });

As per path instructions for test review: "Flag copied production algorithms, broad mocks that bypass the behavior under test, and conditionals that make a test pass without exercising its claim."

🤖 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/command.test.ts` around lines 544 - 548, Add coverage for a
portable onboarding run where loadPortableInferenceDescriptor resolves null,
asserting NEMOCLAW_PROVIDER remains ollama and NEMOCLAW_MODEL remains
qwen3-vl:4b. Update the existing portable-defaults test to inject a
loadPortableInferenceDescriptor stub returning null through
activatePortableInference, keeping the test isolated from the real descriptor
file.

Source: Path instructions

🤖 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 `@docs/inference/set-up-openai-compatible-endpoint.mdx`:
- Line 107: Update the baseUrl description in the endpoint configuration table
to clearly state that the compatible endpoint base URL must use HTTPS, while
preserving “compatible endpoint” as the fixed term and retaining the existing
credential, query, fragment, and SSRF-policy guidance.

In `@src/lib/credentials/scoped-overrides.ts`:
- Around line 15-19: Update the validation loop in withCredentialOverrides to
reject any value containing \u0000, \r, or \n, matching the portable descriptor
apiKey guard, instead of stripping carriage returns. Preserve trimming and
empty-value rejection, and only store values that pass this fail-closed
control-character validation.

---

Nitpick comments:
In `@src/lib/onboard/command.test.ts`:
- Around line 544-548: Add coverage for a portable onboarding run where
loadPortableInferenceDescriptor resolves null, asserting NEMOCLAW_PROVIDER
remains ollama and NEMOCLAW_MODEL remains qwen3-vl:4b. Update the existing
portable-defaults test to inject a loadPortableInferenceDescriptor stub
returning null through activatePortableInference, keeping the test isolated from
the real descriptor file.

In `@src/lib/onboard/experimental/portable-inference-descriptor.test.ts`:
- Around line 198-212: In the test “leaves a FIFO in place without opening it,”
remove the try/finally wrapper and the explicit openSpy.mockRestore() call,
relying on the cli Vitest project’s restoreMocks setting while preserving the
existing assertions and FIFO cleanup behavior.
- Around line 82-112: Add negative cases to the parameterized tests around the
existing “deletes an admitted descriptor” test for apiKey values containing
newline, carriage return, NUL, or surrounding whitespace, a model containing a
control character, and a descriptor exceeding DESCRIPTOR_MAX_BYTES. Assert each
is rejected and the file is deleted, while ensuring invalid apiKey values are
not exposed in errors or other observable output.

In `@src/lib/onboard/experimental/portable-inference-descriptor.ts`:
- Around line 101-106: Update the non-ENOENT error path in openDescriptor to
include the caught errno code in the descriptorError message, while preserving
the existing ENOENT-to-null behavior and rethrowing all other failures as
descriptor errors.

In `@test/credentials.test.ts`:
- Around line 137-139: Update the test containing the runtime credential case
and its suite teardown to remove the directory created by mkdtempSync after the
test completes, using the existing home variable and a guaranteed cleanup hook
or try/finally; preserve the test behavior and avoid duplicating cleanup if a
shared hook already handles it.
🪄 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: f1642f81-63fe-4406-8bb5-cfb52f248abf

📥 Commits

Reviewing files that changed from the base of the PR and between cae757e and 2290f75.

📒 Files selected for processing (8)
  • docs/inference/set-up-openai-compatible-endpoint.mdx
  • src/lib/credentials/scoped-overrides.ts
  • src/lib/credentials/store.ts
  • src/lib/onboard/command.test.ts
  • src/lib/onboard/command.ts
  • src/lib/onboard/experimental/portable-inference-descriptor.test.ts
  • src/lib/onboard/experimental/portable-inference-descriptor.ts
  • test/credentials.test.ts

Comment thread docs/inference/set-up-openai-compatible-endpoint.mdx Outdated
Comment thread src/lib/credentials/scoped-overrides.ts
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

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

Model lanes

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

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

3 semantic terminology decisions

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

  • define — portable inference descriptor at docs/inference/set-up-openai-compatible-endpoint.mdx:67: Define this term at first use and use it consistently for the descriptor contract.
  • define — activation component at docs/inference/set-up-openai-compatible-endpoint.mdx:69: Define this term at first use and use it consistently for the descriptor writer.
  • justified — standby at docs/inference/set-up-openai-compatible-endpoint.mdx:140: Keep this modifier with the stated contrast to the active inference route.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: cloud-inference, security-posture, inference-routing, network-policy, onboard-repair, onboard-resume, cloud-onboard

Workflow run details

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

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

senthilr-nv commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

PRA-1 is not valid for the current implementation.

The scoped credential already reaches only the authorized provider-registration operation: withCredentialOverrides stores it in the asynchronous credential scope, hydrateCredentialEnv resolves that scoped value, and setupRemoteProviderInference passes a dedicated COMPATIBLE_API_KEY environment to upsertProvider. The ambient process.env remains unset.

Commit 91ccff7 adds an integrated regression for that exact chain. It asserts that provider registration receives the scoped key and that process.env.COMPATIBLE_API_KEY is unset both inside and after the scope. The same commit also addresses the valid inline review findings by rejecting NUL, CR, and LF without mutating valid credential bytes, expanding negative descriptor tests, and correcting the documentation.

@jyaunches
jyaunches merged commit bafcad8 into main Aug 10, 2026
85 of 89 checks passed
@jyaunches
jyaunches deleted the codex/portable-runtime-inference branch August 10, 2026 19:15

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/lib/onboard/inference-providers/remote-openai-surface.test.ts (1)

164-168: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Verify scoped credential cleanup after the callback.

Line 164 and Line 167 check only process.env.COMPATIBLE_API_KEY. They do not prove that withCredentialOverrides removed runtime-only-secret from the asynchronous credential scope. A leaked override could still reach a later provider registration while these assertions pass. Add a post-scope resolution or registration assertion that the secret is no longer returned.

As per path instructions, tests must verify observable behavior through the public boundary. Based on the PR objective, the key must remain scoped to the asynchronous call tree and must not persist.

🤖 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/inference-providers/remote-openai-surface.test.ts` around
lines 164 - 168, Add a post-callback assertion in the test around
withCredentialOverrides that resolves or registers credentials through the
public provider boundary and verifies runtime-only-secret is no longer returned.
Keep the existing process.env.COMPATIBLE_API_KEY checks, and ensure the
assertion runs after the asynchronous scope completes to detect leaked
overrides.

Source: Path instructions

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

Nitpick comments:
In `@src/lib/onboard/inference-providers/remote-openai-surface.test.ts`:
- Around line 164-168: Add a post-callback assertion in the test around
withCredentialOverrides that resolves or registers credentials through the
public provider boundary and verifies runtime-only-secret is no longer returned.
Keep the existing process.env.COMPATIBLE_API_KEY checks, and ensure the
assertion runs after the asynchronous scope completes to detect leaked
overrides.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3ce0cd7e-be5d-4ead-a51d-72a95cc9943d

📥 Commits

Reviewing files that changed from the base of the PR and between 2290f75 and 91ccff7.

📒 Files selected for processing (8)
  • docs/inference/set-up-openai-compatible-endpoint.mdx
  • src/lib/credentials/scoped-overrides.ts
  • src/lib/onboard/command.test.ts
  • src/lib/onboard/credential-env.ts
  • src/lib/onboard/experimental/portable-inference-descriptor.test.ts
  • src/lib/onboard/experimental/portable-inference-descriptor.ts
  • src/lib/onboard/inference-providers/remote-openai-surface.test.ts
  • test/credentials.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • docs/inference/set-up-openai-compatible-endpoint.mdx
  • src/lib/credentials/scoped-overrides.ts
  • src/lib/onboard/command.test.ts
  • src/lib/onboard/experimental/portable-inference-descriptor.ts
  • test/credentials.test.ts

jyaunches added a commit that referenced this pull request Aug 10, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Adds the August 10, 2026 release entry for v0.0.106 before the release
plan captures the candidate commit. The entry groups supported
user-visible changes since v0.0.105 and omits work that is private,
dormant, qualification-only, internal, or outside accepted product
scope.

## Changes

- Add the canonical `docs/changelog/2026-08-10.mdx` entry with the exact
`v0.0.106` heading.
- Summarize readiness, OpenShell v0.0.101, bounded DGX Spark and vLLM
choices, inference, sandbox lifecycle, security, Hermes, and host
maintenance changes.
- Use root-absolute documentation routes and the shared dated changelog
source for all published variants.
- Exclude PR #8753 from canonical release claims because no accepted
issue or design decision establishes its product scope.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification:
`test/changelog-docs.test.ts` validates dated changelog SPDX placement,
version headings, forbidden terms, and link form.
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `docs/changelog/2026-08-10.mdx`; an independent Codex
Desktop subagent reviewed the writing rules and documentation style,
terminology, structure, voice, code-sample presentation, links, source
and test accuracy, and product scope at commit `c15039c94`.
- Agent: Codex Desktop
<!-- docs-review-head-sha: c15039c -->
<!-- docs-review-agents-blob-sha: c4923a3 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; `scripts/prepare-dgx-station-host.sh`
is unchanged.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: `npx
vitest run test/changelog-docs.test.ts` passed 6 tests.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable to one
documentation-only release entry.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
result: passed with 0 errors and 2 existing warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— dated changelog entries use the required parser-safe MDX SPDX block
and no frontmatter.

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
  * Added release notes for v0.0.106.
* Documented lifecycle readiness checks, sandbox lifecycle improvements,
safer updates, and scoped uninstall capabilities.
* Added details on OpenShell v0.0.101 adoption and DGX Spark vLLM
configuration options.
* Documented recovery and inference diagnostics, endpoint security
enforcement, and installation and image updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
prekshivyas pushed a commit that referenced this pull request Aug 11, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Completes the v0.0.106 changelog for four user-visible changes that
merged before the tag but were omitted from the pre-tag entry. Keeps
public security pages focused on operator guidance by relocating
maintenance contracts to contributor guidance and the owning OpenClaw
dependency review. Records PR #8753's portable inference descriptor as
Experimental while leaving its existing workflow documentation
unchanged.

## Changes

- Add managed-container restart-transition recovery from PR #8765,
Shields parent-owner preservation from PR #8767, and managed storage
remediation plus NVIDIA driver parsing from PR #8768 to the canonical
v0.0.106 entry.
- Add the Experimental portable inference descriptor from PR #8753 to
the v0.0.106 entry, including its short-lived credential boundary,
manual standby behavior, and owning setup page.
- Keep Process Controls focused on the operator-facing immutable-image
boundary and move the blueprint image-pin maintenance contract to
`CONTRIBUTING.md`.
- Keep Gateway and Secret Controls focused on operator actions and move
the OpenClaw audit-suppression tests and distinct removal conditions to
the owning OpenClaw 2026.7.1 dependency review.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification: the
dated-changelog, published-route, and documentation-link tests cover the
changed release entry and links.
- [ ] 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: an independent Codex
Desktop documentation writer reviewed exact head `bbfed36ca`; the review
verified the operator-facing security claims, the distinct
`allowInsecureAuth` and device-auth suppression removal conditions
against their generator branches, and the confirmed Experimental #8753
release claim. No runtime or policy behavior changes.
- [ ] 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: `CONTRIBUTING.md`, `docs/changelog/2026-08-10.mdx`,
`docs/security/gateway-authentication-controls.mdx`,
`docs/security/openclaw-2026.7.1-dependency-review.md`, and
`docs/security/process-controls.mdx`; the subagent reviewed
`docs/CONTRIBUTING.md`, `WRITING.md`, terminology, structure, voice,
code-sample presentation, canonical ownership, factual accuracy, and
product scope.
- Agent: Codex Desktop
<!-- docs-review-head-sha: bbfed36 -->
<!-- docs-review-agents-blob-sha: c4923a3 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; `scripts/prepare-dgx-station-host.sh`
is unchanged.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: `npx
vitest run test/changelog-docs.test.ts
test/check-docs-published-routes.test.ts test/check-docs-links.test.ts`
passed; `npm run docs` and `git diff --check` passed again after the
review correction.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not applicable to this
bounded documentation-only change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
result: passed with zero errors and the existing light-mode accent
contrast warning.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new pages.

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>


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

## Summary by CodeRabbit

- **Documentation**
- Documented requirements for keeping managed sandbox image digest pins
synchronized and immutable.
- Added guidance for validating custom images and using reviewed image
sources during onboarding.
- Expanded release notes with portable inference profiles, endpoint
references, cleanup behavior, startup handling, and installer details.
- Updated security documentation with current dependency-review
information and authentication-control boundaries.
- Clarified sandbox ownership, permissions, workload identity, and
managed-container restart behavior.

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

---------

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: providers Inference provider integrations and provider behavior feature PR adds or expands user-visible functionality provider: openai OpenAI API or OpenAI-compatible provider behavior security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants