Skip to content

feat(onboard): add reversible configuration review - #8171

Open
prekshivyas wants to merge 10 commits into
mainfrom
codex/onboard-draft-navigation
Open

feat(onboard): add reversible configuration review#8171
prekshivyas wants to merge 10 commits into
mainfrom
codex/onboard-draft-navigation

Conversation

@prekshivyas

@prekshivyas prekshivyas commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Onboarding now collects configuration in a reversible draft, shows one Review screen, and materializes credentials, policies, and sandbox state only after the user selects Apply configuration. Users can walk Back to Step 1, preserve compatible later answers, edit any choice directly from Review, and return immediately to Review when no dependent answer needs to be collected again.

Related Issue

Closes #6005.

Supersedes #7190 while preserving its b discoverability intent through the complete pre-materialization workflow required by the issue.

Changes

  • Add the onboarding intent-draft controller used only by nemoclaw onboard, with typed answer, Back, Review edit, Apply, and Exit transitions. Issue [All Platforms][Onboard][GitHub Issue #6005] nemoclaw onboard wizard has no back-navigation — users cannot correct a previous step without Ctrl+C #6005 requires navigation before external effects; a direct key alias in the existing interleaved flow cannot safely undo created sandboxes or collected credentials. Controller, UI, boundary, runtime, schema, seed, session, and PTY tests protect this contract.
  • Invalidate and reopen only answers that become incompatible after an earlier edit, while retaining compatible answers so repeated Back can reach Step 1 and then return directly to Review.
  • Persist a versioned, secret-free partial draft for interrupted-session resume and reject custom endpoint URL userinfo, query parameters of any name, and fragments.
  • Keep credential collection, provider validation, policy application, and sandbox materialization forward-only after Apply; post-Apply Back requests explain the supported repair, rebuild, and --fresh paths.
  • Document exact Back transitions, Review behavior, invalidation rules, custom resource output, and the Apply boundary for OpenClaw, Hermes, and Deep Agents onboarding.

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: PASS on head c522b7f74 with no findings: feat(onboard): add reversible configuration review #8171 (comment)
  • 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: independent exact-head review of the full PR diff, including Back/Edit collection, draft revalidation, endpoint URL restrictions, tests, documentation, and generated OpenClaw, Hermes, and Deep Agents variants; npm run docs passed with 66 guarded routes, 0 errors, and 2 existing warnings.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

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

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — 89 focused onboarding regressions and the amended Ollama tests (2/2) passed; the stale-accepted-resume fix passed 81 focused tests and 1,037/1,037 changed tests; the endpoint-query follow-up passed 44/44 focused tests. CLI type-check, source architecture, test-size, test-linearity, repository checks, gitleaks, and docs validation passed. A low-worker broad run passed 2,913/2,915 tests; two unrelated Hermes forward-watcher cases exceeded their five-second timeout under local macOS host load and remain covered by GitHub CI.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — GitHub CI pending; the local Docker daemon is unavailable.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

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

Summary by CodeRabbit

  • New Features

    • Added a guided onboarding wizard for configuring agents, inference, sandboxes, integrations, tools, resources, and policies.
    • Added review, direct editing, backward navigation, draft saving, and resume support before applying changes.
    • Added custom resource configuration and dependent-choice validation.
    • Reuses reviewed messaging, web-search, and policy selections without reopening prompts.
    • Requests credentials only when configuration is applied.
  • Bug Fixes

    • Prevented backward navigation after setup changes begin and improved recovery guidance.
  • Documentation

    • Updated onboarding and command references with the staged workflow.

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

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

The onboarding flow now collects secret-free configuration drafts, supports review editing and backward navigation, persists partial drafts, and applies accepted choices before credential and resource setup. Post-Apply flows restrict navigation and reuse reviewed selections. Documentation and tests cover the new phases.

Changes

Onboarding intent-draft workflow

Layer / File(s) Summary
Draft contracts, validation, persistence, and projection
src/lib/onboard/intent-draft/*, src/lib/state/onboard-session*, ci/env-var-doc-allowlist.json
Adds typed draft contracts, dependency reconciliation, endpoint validation, secret-free parsing, environment projection, and session persistence.
Draft collection, review, and navigation
src/lib/onboard/intent-draft/controller.ts, src/lib/onboard/intent-draft/ui.ts, test/onboard-intent-draft-pty.test.ts
Adds staged prompts, review and edit actions, Back and exit handling, checkpointing, dependency invalidation, and Apply results.
Draft boundary and onboarding integration
src/lib/onboard/intent-draft/boundary.ts, src/lib/onboard/intent-draft/deps.ts, src/lib/onboard.ts, src/lib/onboard/setup-nim-flow.ts, src/lib/onboard/intent-draft/ollama-model-selection.ts
Connects draft restoration, dependency wiring, acceptance, provider discovery, Ollama model selection, and onboarding setup.
Post-Apply credentials and reviewed selections
src/lib/onboard/credential-navigation.ts, src/lib/onboard/web-search-flow.ts, src/lib/onboard/messaging-channel-setup.ts, src/lib/onboard/policy-selection.ts, src/lib/onboard/machine/handlers/*
Restricts backward navigation after Apply and materializes reviewed provider, web-search, messaging, and policy choices without reopening selection prompts.
Onboarding documentation and validation
docs/get-started/*, docs/reference/commands.mdx, test/*
Documents the staged onboarding flow and validates draft persistence, navigation, review, credential timing, cancellation, and the accepted-intent marker.

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

Possibly related PRs

  • NVIDIA/NemoClaw#5115: Shares onboarding state persistence and messaging or policy handling.
  • NVIDIA/NemoClaw#5829: Shares provider-selection and recovery changes in src/lib/onboard.ts.
  • NVIDIA/NemoClaw#5913: Shares messaging reconciliation changes in src/lib/onboard/machine/handlers/sandbox-messaging.ts.

Suggested labels: feature, area: onboarding, area: docs

Suggested reviewers: cv, apurvvkumaria

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement Back navigation, editable prior choices, and compatible progress preservation for issue #6005.
Out of Scope Changes check ✅ Passed The code, tests, documentation, and supporting configuration changes directly support reversible onboarding review.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: reversible configuration review for onboarding.
✨ 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 codex/onboard-draft-navigation

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

@github-code-quality

github-code-quality Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 078058f in the codex/onboard-draft-... branch remains at 96%, unchanged from commit a561719 in the main branch.


Updated August 04, 2026 06:47 UTC

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@prekshivyas

Copy link
Copy Markdown
Collaborator Author

Sensitive-path security review

Result: PASS on head 5f959e5971de97fd48099400f94abc1705b0cbba. No blocking findings or warnings.

  1. Secrets and credentials — PASS. The persisted draft schema is fixed and secret-free, unknown credential-shaped fields are discarded, custom endpoint URLs reject URL userinfo and credential-like query parameters, and gitleaks passed. Credential values remain in the existing post-Apply credential store flow.
  2. Input validation — PASS. Seeded and resumed choices are revalidated against live agent/provider/channel/tool/profile/policy menus; sandbox names use the existing validator; endpoint metadata is limited to HTTP(S). Existing downstream endpoint compatibility and SSRF checks remain authoritative after Apply.
  3. Authentication and authorization — PASS. The change records only the authentication method before Review. It does not bypass credential validation, gateway registration, or provider-specific authentication.
  4. Dependencies and supply chain — PASS. No dependency or lockfile changes.
  5. Logging and data exposure — PASS. Review and checkpoints contain only non-secret intent metadata; credential prompts and logs do not print credential values.
  6. Cryptography — PASS. No cryptographic behavior changed.
  7. Configuration and infrastructure — PASS. No port, header, container-capability, or network-policy weakening. Draft projection uses an internal marker and restores all projected environment values when onboarding exits.
  8. Security tests — PASS. Tests cover credential-shaped field stripping, credential-bearing endpoint rejection, incomplete/unaccepted draft refusal, environment restoration, the Apply boundary, post-Apply Back refusal, dependency invalidation, session persistence, and PTY navigation.
  9. System design and race boundaries — PASS. The collector can only checkpoint a secret-free draft; external materialization is behind the explicit Apply boundary. Accepted choices cannot silently rewind after credentials or sandbox effects begin, preventing stale partial rollback behavior.

Reviewed the complete 41-file PR diff and the integration points for inference, web search, messaging, policy selection, credentials, session persistence, and sandbox startup.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

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

Model lanes

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

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

  • secret-free at src/lib/onboard/intent-draft/schema.ts:222: selected only by the second-opinion lane as established.
  • materialization at src/lib/onboard/intent-draft/boundary.ts:16: selected only by the second-opinion lane as established.
  • reconcile at src/lib/onboard/intent-draft/schema.ts:91: selected only by the second-opinion lane as established.
  • intent draft at src/lib/onboard.ts:54: selected only by the second-opinion lane as justified.
  • review boundary at src/lib/onboard/intent-draft/controller.ts:7: selected only by the second-opinion lane as justified.
  • accepted draft at src/lib/onboard/intent-draft/boundary.test.ts:111: selected only by the second-opinion lane as justified.
  • Edit a choice at src/lib/onboard/intent-draft/ui.ts:322: selected only by the second-opinion lane as justified.
  • Apply configuration at docs/reference/commands.mdx:305: selected only by the second-opinion lane as justified.
2 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • rebuild-openclaw: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • rebuild-hermes: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

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.

  • established — credential-free at docs/reference/commands.mdx:244: Keep `credential-free` for the pre-review choices because the controlled word list defines this security boundary.
  • define — choice collection at docs/reference/commands.mdx:244: Retain `choice collection` with its scope defined in the command reference.
  • established — forward-only at docs/reference/commands.mdx:305: Keep `forward-only` for the post-Apply phase because its navigation constraint is stated beside the term.

E2E guidance

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

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

3 optional E2E recommendations
  • double-onboard
  • channels-add-remove
  • ollama-auth-proxy

Workflow run details

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

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/onboard/messaging-channel-setup.ts (1)

184-195: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Preserve reviewed channel IDs in non-interactive setup.

An accepted intentDraft passes selectionProvided: true, but the non-interactive branch ignores it and derives channels from configured inputs. Use the provided channel IDs and cover this combination in a 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/messaging-channel-setup.ts` around lines 184 - 195, Update
the channel selection initialization in the setup flow around statusForChannel
so the non-interactive path with selectionProvided true preserves the accepted
intentDraft channel IDs instead of deriving channels from configured inputs;
retain filtering to availableChannels as appropriate, and add a test covering
selectionProvided true with the accepted draft IDs.
🧹 Nitpick comments (14)
src/lib/state/onboard-session/intent-draft.test.ts (1)

46-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the accepted phase and for an unknown draft version.

The suite covers a collecting draft and unknown-field stripping. It does not cover the two cases that change materialization behavior:

  • A phase: "accepted" draft must survive the save and load round trip. Downstream handlers gate credential materialization and the reviewed policy tier on that exact value.
  • A draft with an unsupported version must normalize to null rather than persist.
💚 Proposed additional cases
+  it("round-trips an accepted draft that gates materialization", async () => {
+    const session = await import("../onboard-session");
+    const created = session.createSession();
+    created.intentDraft = {
+      version: 1,
+      phase: "accepted",
+      answers: { agent: "openclaw", policy: "balanced" },
+    };
+
+    session.saveSession(created);
+
+    expect(session.loadSession()?.intentDraft?.phase).toBe("accepted");
+  });
+
+  it("drops a draft written by an unsupported version", async () => {
+    const session = await import("../onboard-session");
+    const created = session.createSession() as unknown as Record<string, unknown>;
+    created.intentDraft = { version: 2, phase: "accepted", answers: { agent: "openclaw" } };
+
+    expect(session.normalizeSession(created as never)?.intentDraft).toBeNull();
+  });
🤖 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/state/onboard-session/intent-draft.test.ts` around lines 46 - 64, Add
tests alongside the existing normalizeSession coverage for both materialization
boundaries: verify an intent draft with phase "accepted" survives the save/load
round trip unchanged, and verify a draft with an unsupported version normalizes
to null and is not persisted. Reuse the existing session creation and
normalization helpers in the test.
src/lib/onboard/intent-draft/ui.test.ts (2)

13-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fail the test when queued replies stay unconsumed.

The prompt fake throws only when replies is empty. It stays silent when the flow consumes fewer replies than queued. A test that skips a step therefore still passes, and the positional reply arrays hide which step received which answer. Line 146 queues fifteen unlabeled entries, so a single misplaced reply changes the navigation path without any assertion noticing.

Record the prompt text with each reply, and assert that the queue is empty after the call. The recorded pairs also let each test state the navigation path it claims to exercise.

♻️ Proposed change to `makeDeps` and a per-test assertion
-function makeDeps(replies: string[]): OnboardIntentDraftUiDeps & { lines: string[] } {
+function makeDeps(
+  replies: string[],
+): OnboardIntentDraftUiDeps & {
+  lines: string[];
+  asked: [string, string][];
+  pendingReplies: string[];
+} {
   const lines: string[] = [];
+  const asked: [string, string][] = [];
   return {
     lines,
+    asked,
+    pendingReplies: replies,
-    prompt: vi.fn(async () => {
+    prompt: vi.fn(async (question: string) => {
       const reply = replies.shift();
       if (reply === undefined) throw new Error("Missing prompt reply");
+      asked.push([question, reply]);
       return reply;
     }),

Then assert full consumption in each test:

     const result = await collectOnboardIntentDraft(deps);
 
+    expect(deps.pendingReplies).toEqual([]);
     expect(result.kind).toBe("apply");
🤖 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/intent-draft/ui.test.ts` around lines 13 - 17, Update the
test dependency factory’s prompt fake in makeDeps to record each prompt text
alongside its consumed reply, and ensure queued replies are identified by the
prompt they are intended for rather than relying on unlabeled positional
entries. Add assertions after every relevant test flow that the reply queue is
empty, while preserving the existing missing-reply failure behavior and using
the recorded prompt/reply pairs to make each test’s navigation path explicit.

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

Reduce exact-string assertions on rendered layout.

Several assertions pin exact indentation, for example " 1) Apply configuration" on line 90, " Agent:" on line 151, and " Managed tools: nous-web, nous-audio" on line 205. A purely visual change to indentation or spacing breaks many tests at once without any behavior change.

Match on trimmed text or on a substring where the label, not the layout, is the contract. Keep exact matching only for prompt strings that encode a default value, such as " CPU [50%]: ".

Also applies to: 151-153, 176-177, 205-205, 226-228

🤖 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/intent-draft/ui.test.ts` at line 90, Relax layout-sensitive
assertions in the intent-draft UI tests, including the checks around deps.lines
and the related assertions at the referenced locations, by matching trimmed text
or stable label substrings instead of exact indentation. Preserve exact-string
assertions only where spacing is part of the prompt contract, such as the CPU
default prompt.
src/lib/onboard/messaging-channel-setup.test.ts (1)

458-473: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add coverage for an already-configured credential under selectionProvided.

This test only covers the missing-token case. Add a companion test where TELEGRAM_BOT_TOKEN is already set before calling setupMessagingChannels(..., { selectionProvided: true }), asserting prompt is not called again for the token. This locks in the resume behavior described in the linked comment on sandbox-messaging.ts lines 377-383.

🤖 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/messaging-channel-setup.test.ts` around lines 458 - 473, Add
a companion test near “uses reviewed channel IDs while requesting their
credentials after Apply (`#6005`)” that sets TELEGRAM_BOT_TOKEN before calling
setupMessagingChannels with selectionProvided: true. Assert the Telegram channel
remains selected and prompt is not called for the token, preserving the existing
credential without invoking saveCredential again.
src/lib/onboard/intent-draft/ui.ts (2)

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

Extract the duplicated multi-select parse loop.

promptMessaging and promptManagedTools repeat the same token split, lookup, dedupe, and invalid-token loop. Only the label and the return wrapper differ. Extract one helper so both prompts stay consistent when the parsing rules change.

♻️ Proposed helper
function parseMultiSelect(
  raw: string,
  choices: readonly OnboardIntentChoice[],
): { readonly selected: string[] } | { readonly invalid: string } {
  const selected: string[] = [];
  for (const part of raw.split(/[\s,]+/).filter(Boolean)) {
    const choice = findChoice(part, choices);
    if (!choice) return { invalid: part };
    if (!selected.includes(choice.value)) selected.push(choice.value);
  }
  return { selected };
}

Then each prompt becomes:

-    const selected: string[] = [];
-    let invalid: string | null = null;
-    for (const part of normalized.split(/[\s,]+/).filter(Boolean)) {
-      const choice = findChoice(part, choices);
-      if (!choice) {
-        invalid = part;
-        break;
-      }
-      if (!selected.includes(choice.value)) selected.push(choice.value);
-    }
-    if (!invalid) return { kind: "answer", value: selected };
-    deps.log(`  Unknown messaging channel: ${invalid}`);
+    const parsed = parseMultiSelect(normalized, choices);
+    if ("selected" in parsed) return { kind: "answer", value: parsed.selected };
+    deps.log(`  Unknown messaging channel: ${parsed.invalid}`);

Also applies to: 496-507

🤖 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/intent-draft/ui.ts` around lines 451 - 462, Extract the
duplicated token parsing logic from promptMessaging and promptManagedTools into
a shared parseMultiSelect helper near the existing choice utilities. The helper
should split on whitespace or commas, resolve tokens with findChoice,
deduplicate selected values, and return either the selected values or the first
invalid token; update both prompts to use it while preserving their existing
labels and answer wrappers.

608-614: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow profileValue before building the resource answer.

profileValue is typed string | undefined from prior?.profile. Line 614 can send the stage directly to "gpu" for a Back entry, so the profile stage may never assign it. At runtime that path is safe, because Line 614 requires prior, and prior.profile is defined. The compiler does not check the mismatch, because DraftStep<OnboardIntentStepId, OnboardIntentDraft, unknown> types the prompt result as unknown. A later edit to the stage machine can therefore emit profile: undefined into OnboardResourceIntent with no type error.

Make the invariant explicit so the compiler enforces it.

🛡️ Proposed fix
-          return {
-            kind: "answer",
-            value: {
-              profile: profileValue,
+          if (!profileValue) throw new Error("Resource profile was not collected.");
+          return {
+            kind: "answer",
+            value: {
+              profile: profileValue,

Also applies to: 677-685

🤖 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/intent-draft/ui.ts` around lines 608 - 614, Make profileValue
non-optional in the resource prompt by narrowing or validating prior?.profile
before constructing the resource answer, while preserving the back-entry path
that starts at the "gpu" stage. Apply the same invariant to the corresponding
prompt logic around the second resource flow at lines 677-685, so any emitted
OnboardResourceIntent always has a defined profile.
src/lib/onboard/machine/handlers/sandbox-messaging.test.ts (1)

266-271: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Accepted-draft fixtures bypass parseOnboardIntentDraft in both tests. Both tests build a session with createSession() and then assign session.intentDraft directly. createSession runs intentDraft through parseOnboardIntentDraft (src/lib/state/onboard-session.ts Line 695), so post-construction assignment skips the parser. Neither test proves that a real persisted accepted draft reaches its handler, and a shape the parser would reject or normalize still passes.

  • src/lib/onboard/machine/handlers/sandbox-messaging.test.ts#L266-L271: pass the draft as createSession({ intentDraft: { version: 1, phase: "accepted", answers: { messaging: ["discord"] } } }) and drop the direct assignment.
  • src/lib/onboard/machine/handlers/provider-inference.test.ts#L1435-L1442: pass the draft as createSession({ intentDraft: { version: 1, phase: "accepted", answers: {} } }) and drop the direct assignment. Confirm that parseOnboardIntentDraft preserves an accepted draft with an empty answers object; if it does not, use a complete answer set, because production accepts only a complete draft.

As per path instructions: "Resume and repair bridges must correspond to real persisted older-session shapes, be idempotent across interruption/replay, keep secrets redacted, and converge on the same authoritative path as a fresh run."

🤖 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/machine/handlers/sandbox-messaging.test.ts` around lines 266
- 271, Update the accepted-draft fixtures in
src/lib/onboard/machine/handlers/sandbox-messaging.test.ts#L266-L271 and
src/lib/onboard/machine/handlers/provider-inference.test.ts#L1435-L1442 to pass
intentDraft through createSession, removing direct post-construction assignment
so parseOnboardIntentDraft is exercised. Preserve the intended accepted-draft
shapes, and in provider-inference.test.ts use a complete answer set if parsing
rejects an empty answers object.

Source: Path instructions

src/lib/onboard/intent-draft/controller.test.ts (1)

178-191: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the accepted phase in both assertion tests.

These tests exercise "collecting" and "materializing" only. collectOnboardIntentDraft in src/lib/onboard/intent-draft/ui.ts Line 720 persists phase: "accepted", so "accepted" is the phase a resumed post-Apply session actually carries. Both guards must reject it. Add that case so a later change to OnboardDraftPhase handling cannot silently re-enable Back navigation for an accepted draft.

💚 Proposed additions
   it("refuses Back once materialization has started", () => {
     expect(() => assertDraftNavigationAllowed("collecting", "nemoclaw")).not.toThrow();
+    expect(() => assertDraftNavigationAllowed("accepted", "nemoclaw")).toThrow(
+      "Back navigation is unavailable after Apply configuration",
+    );
     expect(() => assertDraftNavigationAllowed("materializing", "nemoclaw")).toThrow(
       "Back navigation is unavailable after Apply configuration",
     );
   });
 
   it("refuses a post-Apply retry that would revisit an accepted choice", () => {
+    expect(() => assertDraftRevisionAllowed("collecting", "the Ollama model", "nemoclaw")).not.toThrow();
+    expect(() => assertDraftRevisionAllowed("accepted", "the Ollama model", "nemoclaw")).toThrow(
+      "Cannot change the Ollama model after Apply configuration",
+    );
     expect(() =>
       assertDraftRevisionAllowed("materializing", "the Ollama model", "nemoclaw"),
     ).toThrow(
🤖 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/intent-draft/controller.test.ts` around lines 178 - 191,
Extend both tests around assertDraftNavigationAllowed and
assertDraftRevisionAllowed to cover the "accepted" phase, asserting it throws
the same post-Apply errors as "materializing". Preserve the existing collecting
and materializing assertions while ensuring resumed accepted drafts cannot
navigate Back or revise an accepted choice.
src/lib/onboard/intent-draft/controller.ts (1)

122-129: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the idempotence requirement for prepareReview.

Reference identity is the only loop-termination guard here. If a caller's prepareReview returns a new object on every call, this loop never reaches options.review, and the CLI hangs with no output. prepareDraftForReview in src/lib/onboard/intent-draft/ui.ts satisfies the requirement because it returns the same reference when the answers are unchanged. State that contract on the prepareReview option so future callers keep it.

♻️ Proposed doc-comment change
-  /** Revalidate a complete draft against current capabilities before review. */
+  /**
+   * Revalidate a complete draft against current capabilities before review.
+   *
+   * Must be idempotent and must return the same object reference when nothing
+   * changes. The collection loop repeats until the returned draft is reference
+   * equal to its input.
+   */
   readonly prepareReview?: (draft: Draft) => Promise<Draft> | Draft;
🤖 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/intent-draft/controller.ts` around lines 122 - 129, Document
the idempotence and reference-identity contract on the prepareReview option used
by the controller loop: callers must return the same draft object when no
changes are needed, and only return a new object when preparation changes it.
Update the option’s type or adjacent doc comment, using prepareDraftForReview as
the established behavior, without changing the loop logic.
src/lib/onboard/policy-selection.ts (1)

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

Extract the applied-preset preservation loop.

The loop at Lines 403-407 duplicates the loop at Lines 482-488, including the suppressedNames exclusion. Extract one helper that takes chosen, appliedForPreservation, and suppressedNames and returns the kept names. Both call sites then share one rule, and the non-interactive note can keep using the returned list.

🤖 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/policy-selection.ts` around lines 402 - 407, Extract the
duplicated applied-preset preservation logic into a helper that accepts chosen,
appliedForPreservation, and suppressedNames and returns the names retained after
excluding already chosen or suppressed entries. Replace both preservation loops
with calls to this helper, preserving the existing behavior and allowing the
non-interactive note to use the returned list.
src/lib/onboard.ts (1)

3937-3949: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Give the NEMOCLAW_ONBOARD_INTENT_ACCEPTED contract one owner. Two modules read the raw env name and compare it to "1" independently, so the accepted-intent contract has no single source of truth. Export one predicate from the intent-draft module and call it from both sites.

  • src/lib/onboard.ts#L3937-L3949: replace the literal inside hasAcceptedOnboardIntent with a call to the exported intent-draft predicate.
  • src/lib/onboard/web-search-flow.ts#L460-L478: replace env.NEMOCLAW_ONBOARD_INTENT_ACCEPTED === "1" with the same predicate, passing the injected env so the tests keep injecting it.
🤖 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.ts` around lines 3937 - 3949, The
NEMOCLAW_ONBOARD_INTENT_ACCEPTED check must have one shared owner. In
src/lib/onboard.ts lines 3937-3949, export a predicate from the intent-draft
module and update hasAcceptedOnboardIntent to call it; in
src/lib/onboard/web-search-flow.ts lines 460-478, replace the direct env
comparison with that same predicate, passing the injected env so tests remain
isolated.
src/lib/onboard/messaging-channel-setup.ts (1)

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

Report reviewed channels that the selected agent does not support.

The filter drops any reviewed channel that is missing from availableChannels, with no output. The user reviewed and applied that channel, so silence is confusing. Emit a note for each dropped channel, matching the pattern used by providerSupported in src/lib/onboard/web-search-flow.ts Line 384.

🤖 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/messaging-channel-setup.ts` around lines 183 - 189, Update
the channel filtering logic in the setup flow around the enabled Set to identify
reviewed channel IDs absent from availableChannels and emit a note for each
dropped channel, following the existing providerSupported notification pattern
from the web-search flow. Preserve the current filtering and enabled-channel
behavior while ensuring every unsupported reviewed channel is reported.
src/lib/onboard/machine/handlers/provider-inference.ts (1)

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

Derive both helpers from one accepted-intent predicate.

needsLegacyConfigurationConfirmation reads session?.intentDraft?.phase !== "accepted", and the call site at Line 985 computes the same condition again as reviewedIntentAccepted. Two places now encode the accepted-intent rule. Add one predicate, for example reviewedIntentAccepted(session), and use it in both helpers so a later phase rename touches one line.

🤖 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/machine/handlers/provider-inference.ts` around lines 410 -
425, The accepted-intent rule is duplicated between
needsLegacyConfigurationConfirmation and the reviewedIntentAccepted value at the
call site. Add a shared reviewedIntentAccepted(session) predicate and update
both helpers/call-site logic to use it, preserving the existing non-interactive
and summary behaviors while centralizing the phase check.
src/lib/onboard/credential-navigation.ts (1)

11-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a phase-specific never overload for assertDraftNavigationAllowed.

CredentialNavigationPolicy.onBackUnavailable can use never, but the change does not compile as written. assertDraftNavigationAllowed returns for "collecting", so its declared return type is void. Add a throwing overload or helper for "materializing", use it in the policy callback, then change onBackUnavailable to never.

🤖 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/credential-navigation.ts` around lines 11 - 14, Update the
draft-navigation flow around assertDraftNavigationAllowed so the "materializing"
phase has a throwing overload or helper with a never return type, while
preserving void behavior for "collecting". Use that phase-specific throwing path
in CredentialNavigationPolicy.onBackUnavailable, then change the callback’s
return type to never.
🤖 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/get-started/quickstart-langchain-deepagents-code.mdx`:
- Line 113: Update the Deep Agents Code wizard description to remove the web
search choice from the list of collected onboarding inputs, keeping the
remaining items unchanged. Ensure the surrounding documentation consistently
reflects that this flow has no NemoClaw-managed web-search prompt.

In `@docs/reference/commands.mdx`:
- Around line 249-253: Update the choice-collection documentation paragraph to
state that entering “exit” or “quit” exits onboarding, matching the existing
prompt hint and collection behavior. Also replace “nonapplicable” with “not
applicable,” while preserving the existing back-navigation details.

In `@src/lib/onboard/intent-draft/boundary.ts`:
- Around line 28-39: Update crossOnboardIntentDraftBoundary to explicitly reject
or throw when shouldCollect is false but options.existingDraft is a non-accepted
draft, such as a "collecting" phase. Preserve the current accepted-draft
handling and collection flow, while preventing the invalid disabled-collection
path from returning continue with a null draft.

In `@src/lib/onboard/intent-draft/schema.ts`:
- Around line 150-170: Update validateOnboardIntentEndpointUrl to reject or
remove URL fragments before returning the normalized URL, ensuring values in
parsed.hash cannot be persisted in the endpoint intent. Preserve the existing
protocol, userinfo, and credential-query validation behavior.

In `@src/lib/onboard/intent-draft/seed.ts`:
- Around line 55-65: Update the resource seeding logic around opts.sandboxGpu
and the resources assignment to preserve whether --gpu or --no-gpu was
explicitly selected, rather than treating both as null. Normalize that CLI
choice before constructing answers.resources so the GPU value reflects the
explicit selection instead of defaulting to "auto"; add boundary tests covering
both flags.

In `@src/lib/onboard/intent-draft/ui.ts`:
- Around line 301-315: Update the edit submenu loop around the prompt and
validation message to call the existing writeNavigationHint helper, so users can
discover the supported back and exit commands. Also change the prompt text from
“Choose a choice to edit” to “Choose a group to edit,” while preserving the
existing numeric selection and navigation handling.

In `@src/lib/onboard/machine/handlers/sandbox-messaging.ts`:
- Around line 377-383: Update setupSelectedMessagingChannels in
src/lib/onboard/machine/handlers/sandbox-messaging.ts:377-383 to pass
selectionProvided, or an equivalent credentials-only signal, alongside
selectionCompleted so resumed reviewed-channel runs with saved credentials do
not re-prompt. Add coverage in
src/lib/onboard/messaging-channel-setup.test.ts:458-473 by pre-setting
TELEGRAM_BOT_TOKEN, invoking the selectionProvided path, and asserting prompt is
not called for that credential.

In `@src/lib/onboard/policy-selection-recorded-tier.test.ts`:
- Around line 121-138: Add a paired test for the same suggested-mode harness
setup that omits acceptTierSuggestions while retaining tierName, and assert
selectTierPresetsAndAccess is called and selectPolicyTier is not called; keep
the existing reviewed-tier case and assertions so the pair isolates
acceptTierSuggestions from the ambient policy mode.

In `@src/lib/onboard/setup-nim-provider-discovery.test.ts`:
- Around line 18-35: Update the test case around prepareProviderDiscovery to
have getNonInteractiveProvider return a provider value distinct from the "build"
fallback, while keeping the expected reviewed model and getNonInteractiveModel
assertion aligned with that provider. This ensures the test verifies the
requested provider is forwarded rather than merely matching the fallback.

In `@src/lib/onboard/setup-nim-provider-discovery.ts`:
- Around line 109-112: Update the requestedModel logic in
setup-nim-provider-discovery so getNonInteractiveModel is invoked only for
non-interactive onboarding; interactive runs must continue to the provider menu
even when NEMOCLAW_MODEL is invalid. Add coverage for the interactive
invalid-model and provider-environment combination.

In `@src/lib/state/onboard-session.ts`:
- Line 777: Update normalizeSession around parseOnboardIntentDraft so a non-null
persisted intentDraft that fails parsing rejects the session instead of being
converted to null. Follow the existing rejection pattern used for the Station
Express fields, while preserving valid and genuinely null values; add resume
coverage verifying malformed intentDraft data is rejected after materialization.

In `@test/onboard-intent-draft-pty.test.ts`:
- Around line 27-36: Handle errors emitted by child.stdin in the
sendRepliesForVisiblePrompts flow, including EPIPE when the child exits before a
final stdout chunk is processed. Attach an stdin error handler that prevents the
unhandled stream error and allows the existing timeout diagnostic to be reported
instead; keep the child-level error handling unchanged.

---

Outside diff comments:
In `@src/lib/onboard/messaging-channel-setup.ts`:
- Around line 184-195: Update the channel selection initialization in the setup
flow around statusForChannel so the non-interactive path with selectionProvided
true preserves the accepted intentDraft channel IDs instead of deriving channels
from configured inputs; retain filtering to availableChannels as appropriate,
and add a test covering selectionProvided true with the accepted draft IDs.

---

Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 3937-3949: The NEMOCLAW_ONBOARD_INTENT_ACCEPTED check must have
one shared owner. In src/lib/onboard.ts lines 3937-3949, export a predicate from
the intent-draft module and update hasAcceptedOnboardIntent to call it; in
src/lib/onboard/web-search-flow.ts lines 460-478, replace the direct env
comparison with that same predicate, passing the injected env so tests remain
isolated.

In `@src/lib/onboard/credential-navigation.ts`:
- Around line 11-14: Update the draft-navigation flow around
assertDraftNavigationAllowed so the "materializing" phase has a throwing
overload or helper with a never return type, while preserving void behavior for
"collecting". Use that phase-specific throwing path in
CredentialNavigationPolicy.onBackUnavailable, then change the callback’s return
type to never.

In `@src/lib/onboard/intent-draft/controller.test.ts`:
- Around line 178-191: Extend both tests around assertDraftNavigationAllowed and
assertDraftRevisionAllowed to cover the "accepted" phase, asserting it throws
the same post-Apply errors as "materializing". Preserve the existing collecting
and materializing assertions while ensuring resumed accepted drafts cannot
navigate Back or revise an accepted choice.

In `@src/lib/onboard/intent-draft/controller.ts`:
- Around line 122-129: Document the idempotence and reference-identity contract
on the prepareReview option used by the controller loop: callers must return the
same draft object when no changes are needed, and only return a new object when
preparation changes it. Update the option’s type or adjacent doc comment, using
prepareDraftForReview as the established behavior, without changing the loop
logic.

In `@src/lib/onboard/intent-draft/ui.test.ts`:
- Around line 13-17: Update the test dependency factory’s prompt fake in
makeDeps to record each prompt text alongside its consumed reply, and ensure
queued replies are identified by the prompt they are intended for rather than
relying on unlabeled positional entries. Add assertions after every relevant
test flow that the reply queue is empty, while preserving the existing
missing-reply failure behavior and using the recorded prompt/reply pairs to make
each test’s navigation path explicit.
- Line 90: Relax layout-sensitive assertions in the intent-draft UI tests,
including the checks around deps.lines and the related assertions at the
referenced locations, by matching trimmed text or stable label substrings
instead of exact indentation. Preserve exact-string assertions only where
spacing is part of the prompt contract, such as the CPU default prompt.

In `@src/lib/onboard/intent-draft/ui.ts`:
- Around line 451-462: Extract the duplicated token parsing logic from
promptMessaging and promptManagedTools into a shared parseMultiSelect helper
near the existing choice utilities. The helper should split on whitespace or
commas, resolve tokens with findChoice, deduplicate selected values, and return
either the selected values or the first invalid token; update both prompts to
use it while preserving their existing labels and answer wrappers.
- Around line 608-614: Make profileValue non-optional in the resource prompt by
narrowing or validating prior?.profile before constructing the resource answer,
while preserving the back-entry path that starts at the "gpu" stage. Apply the
same invariant to the corresponding prompt logic around the second resource flow
at lines 677-685, so any emitted OnboardResourceIntent always has a defined
profile.

In `@src/lib/onboard/machine/handlers/provider-inference.ts`:
- Around line 410-425: The accepted-intent rule is duplicated between
needsLegacyConfigurationConfirmation and the reviewedIntentAccepted value at the
call site. Add a shared reviewedIntentAccepted(session) predicate and update
both helpers/call-site logic to use it, preserving the existing non-interactive
and summary behaviors while centralizing the phase check.

In `@src/lib/onboard/machine/handlers/sandbox-messaging.test.ts`:
- Around line 266-271: Update the accepted-draft fixtures in
src/lib/onboard/machine/handlers/sandbox-messaging.test.ts#L266-L271 and
src/lib/onboard/machine/handlers/provider-inference.test.ts#L1435-L1442 to pass
intentDraft through createSession, removing direct post-construction assignment
so parseOnboardIntentDraft is exercised. Preserve the intended accepted-draft
shapes, and in provider-inference.test.ts use a complete answer set if parsing
rejects an empty answers object.

In `@src/lib/onboard/messaging-channel-setup.test.ts`:
- Around line 458-473: Add a companion test near “uses reviewed channel IDs
while requesting their credentials after Apply (`#6005`)” that sets
TELEGRAM_BOT_TOKEN before calling setupMessagingChannels with selectionProvided:
true. Assert the Telegram channel remains selected and prompt is not called for
the token, preserving the existing credential without invoking saveCredential
again.

In `@src/lib/onboard/messaging-channel-setup.ts`:
- Around line 183-189: Update the channel filtering logic in the setup flow
around the enabled Set to identify reviewed channel IDs absent from
availableChannels and emit a note for each dropped channel, following the
existing providerSupported notification pattern from the web-search flow.
Preserve the current filtering and enabled-channel behavior while ensuring every
unsupported reviewed channel is reported.

In `@src/lib/onboard/policy-selection.ts`:
- Around line 402-407: Extract the duplicated applied-preset preservation logic
into a helper that accepts chosen, appliedForPreservation, and suppressedNames
and returns the names retained after excluding already chosen or suppressed
entries. Replace both preservation loops with calls to this helper, preserving
the existing behavior and allowing the non-interactive note to use the returned
list.

In `@src/lib/state/onboard-session/intent-draft.test.ts`:
- Around line 46-64: Add tests alongside the existing normalizeSession coverage
for both materialization boundaries: verify an intent draft with phase
"accepted" survives the save/load round trip unchanged, and verify a draft with
an unsupported version normalizes to null and is not persisted. Reuse the
existing session creation and normalization helpers in the test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3dfc15dc-7dd3-4336-bf94-0820bc102794

📥 Commits

Reviewing files that changed from the base of the PR and between 03fbf5e and 5f959e5.

📒 Files selected for processing (41)
  • ci/env-var-doc-allowlist.json
  • docs/get-started/quickstart-hermes.mdx
  • docs/get-started/quickstart-langchain-deepagents-code.mdx
  • docs/get-started/quickstart.mdx
  • docs/reference/commands.mdx
  • src/lib/onboard.ts
  • src/lib/onboard/credential-navigation.test.ts
  • src/lib/onboard/credential-navigation.ts
  • src/lib/onboard/intent-draft/boundary.test.ts
  • src/lib/onboard/intent-draft/boundary.ts
  • src/lib/onboard/intent-draft/controller.test.ts
  • src/lib/onboard/intent-draft/controller.ts
  • src/lib/onboard/intent-draft/index.ts
  • src/lib/onboard/intent-draft/runtime.test.ts
  • src/lib/onboard/intent-draft/runtime.ts
  • src/lib/onboard/intent-draft/schema.test.ts
  • src/lib/onboard/intent-draft/schema.ts
  • src/lib/onboard/intent-draft/seed.test.ts
  • src/lib/onboard/intent-draft/seed.ts
  • src/lib/onboard/intent-draft/ui.test.ts
  • src/lib/onboard/intent-draft/ui.ts
  • src/lib/onboard/machine/handlers/policies.test.ts
  • src/lib/onboard/machine/handlers/policies.ts
  • src/lib/onboard/machine/handlers/provider-inference.test.ts
  • src/lib/onboard/machine/handlers/provider-inference.ts
  • src/lib/onboard/machine/handlers/sandbox-messaging.test.ts
  • src/lib/onboard/machine/handlers/sandbox-messaging.ts
  • src/lib/onboard/messaging-channel-setup.test.ts
  • src/lib/onboard/messaging-channel-setup.ts
  • src/lib/onboard/policy-selection-recorded-tier.test.ts
  • src/lib/onboard/policy-selection.ts
  • src/lib/onboard/setup-nim-flow.test.ts
  • src/lib/onboard/setup-nim-flow.ts
  • src/lib/onboard/setup-nim-provider-discovery.test.ts
  • src/lib/onboard/setup-nim-provider-discovery.ts
  • src/lib/onboard/web-search-flow.test.ts
  • src/lib/onboard/web-search-flow.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/onboard-session/intent-draft.test.ts
  • test/fixtures/onboard-intent-draft-pty-driver.ts
  • test/onboard-intent-draft-pty.test.ts

Comment thread docs/get-started/quickstart-langchain-deepagents-code.mdx Outdated
Comment thread docs/reference/commands.mdx Outdated
Comment thread src/lib/onboard/intent-draft/boundary.ts
Comment thread src/lib/onboard/intent-draft/schema.ts
Comment thread src/lib/onboard/intent-draft/seed.ts Outdated
Comment thread src/lib/onboard/policy-selection-recorded-tier.test.ts
Comment thread src/lib/onboard/setup-nim-provider-discovery.test.ts
Comment thread src/lib/onboard/setup-nim-provider-discovery.ts Outdated
Comment thread src/lib/state/onboard-session.ts Outdated
Comment thread test/onboard-intent-draft-pty.test.ts
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas

prekshivyas commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

Sensitive-path security review refresh

Verdict

PASS on exact head c522b7f74. I found no security warnings or blocking findings. The PR keeps the persisted draft secret-free, validates operator-controlled metadata before review or resume, and places credential collection and every external mutation behind the explicit Apply boundary. The final review fixes strengthen the design by rejecting all endpoint URL fragments and malformed persisted drafts. The final test-only delta adds fail-closed callback assertions and CLI-over-environment precedence coverage without changing production behavior. The latest production delta rejects all custom endpoint URL query parameters, including short signed forms such as ?sig=..., and revalidates collecting and accepted drafts before Review or materialization so rejected values are neither persisted nor rendered.

Findings

No findings.

Detailed analysis

  1. Secrets and credentials — PASS. The fixed draft schema retains only allowlisted non-secret fields. Credentials remain in the existing post-Apply stores and prompts. Endpoint URLs reject userinfo, query parameters of every name, and every fragment. Hook gitleaks passed; test strings are non-production canaries.
  2. Input validation and sanitization — PASS. Agent/provider/menu choices are capability-backed, sandbox names use the existing validator, model IDs use isSafeModelId, endpoint URLs require HTTP(S) without userinfo, query parameters, or fragments, and persisted drafts are parsed against the fixed schema. Unsupported dependent choices reopen before Review.
  3. Authentication and authorization — PASS. No authentication, ownership, or permission contract changes. A non-accepted draft cannot cross the materialization boundary when collection is disabled.
  4. Dependencies and third-party libraries — PASS. No dependency or lockfile changes.
  5. Error handling and logging — PASS. Secret-bearing endpoint metadata is rejected before persistence or review rendering. Invalid models and drafts fail closed without logging credential values. Locked Ollama download/validation failures exit without looping, while the established bounded probe retry remains intact.
  6. Cryptography and data protection — PASS. No cryptographic behavior or sensitive-data-at-rest contract changes.
  7. Configuration and security headers — PASS. No container, port, CORS, CSP, network-policy, image, or privilege configuration changes.
  8. Security testing — PASS. Coverage includes credential-shaped unknown fields, URL userinfo/all-query/fragment rejection, signed-query session rejection, absence from Review output, malformed-session rejection, pre-Apply mutation denial, post-Apply revision denial, unsafe model rejection, and locked-model failure exits. Exact affected suites passed 89 tests; CLI type-check, source architecture, test-size, test-linearity, repository checks, gitleaks, and docs validation passed. The exact-head follow-up passed 68 focused tests and 10 changed tests. The stale-resume fix passed 81 focused tests and 1,037 changed tests. The endpoint-query follow-up passed 44/44 focused tests; CLI type-check, repository checks, and documentation validation also passed.
  9. System security — PASS. Draft collection is reversible only before Apply. Accepted intent is projected once into the existing forward-only workflow; post-Apply Back/revision attempts are refused. Resume parsing and materialization both fail closed, and the change adds no new external authority.

Files reviewed

  • Guardrails/docs: ci/env-var-doc-allowlist.json, ci/source-architecture-budget.json, docs/get-started/quickstart.mdx, docs/get-started/quickstart-hermes.mdx, docs/get-started/quickstart-langchain-deepagents-code.mdx, docs/reference/commands.mdx
  • Main onboarding and credential navigation: src/lib/onboard.ts, src/lib/onboard/credential-navigation.ts, src/lib/onboard/credential-navigation.test.ts
  • Draft boundary/controller/runtime/schema/seed/UI: src/lib/onboard/intent-draft/boundary.ts, boundary.test.ts, controller.ts, controller.test.ts, deps.ts, index.ts, runtime.ts, runtime.test.ts, schema.ts, schema.test.ts, seed.ts, seed.test.ts, ui.ts, ui.test.ts, ollama-model-selection.ts, ollama-model-selection.test.ts
  • Materialization handlers: src/lib/onboard/machine/handlers/policies.ts, policies.test.ts, provider-inference.ts, provider-inference.test.ts, sandbox-messaging.ts, sandbox-messaging.test.ts
  • Provider/policy/messaging/web-search flows: src/lib/onboard/messaging-channel-setup.ts, messaging-channel-setup.test.ts, policy-selection.ts, policy-selection-recorded-tier.test.ts, setup-nim-flow.ts, setup-nim-flow.test.ts, setup-nim-provider-discovery.ts, setup-nim-provider-discovery.test.ts, web-search-flow.ts, web-search-flow.test.ts
  • Persistence and PTY coverage: src/lib/state/onboard-session.ts, src/lib/state/onboard-session/intent-draft.test.ts, test/fixtures/onboard-intent-draft-pty-driver.ts, test/onboard-intent-draft-pty.test.ts

Signed-off-by: Prekshi Vyas <prekshiv@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

🧹 Nitpick comments (3)
src/lib/onboard/intent-draft/ollama-model-selection.ts (1)

97-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the injected abort instead of process.exit(1).

OllamaModelSelectorDeps declares abortNonInteractive: (message: string) => never for non-interactive termination. Lines 143 and 160 use it. This branch calls console.error and process.exit(1) directly. That gives two mechanisms for one concept, and it terminates the process during tests, so the branch cannot be asserted.

Route this branch through deps.abortNonInteractive as well.

♻️ Proposed refactor
         } else if (deps.isNonInteractive()) {
-          console.error(
-            `  Ollama model '${selectedModel}' (${sizeLabel}) is not installed and ` +
-              "non-interactive mode cannot prompt for confirmation. " +
-              "Re-run with --yes / -y (or NEMOCLAW_YES=1) to authorise the download.",
-          );
-          process.exit(1);
+          deps.abortNonInteractive(
+            `Ollama model '${selectedModel}' (${sizeLabel}) is not installed and ` +
+              "non-interactive mode cannot prompt for confirmation. " +
+              "Re-run with --yes / -y (or NEMOCLAW_YES=1) to authorise the download.",
+          );
         } else {
🤖 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/intent-draft/ollama-model-selection.ts` around lines 97 -
103, Update the non-interactive branch in the Ollama model selection flow to
call deps.abortNonInteractive with the existing download-authorization message
instead of calling process.exit(1). Preserve the current error context and
ensure this branch uses the same injected termination mechanism as the paths
near the other abortNonInteractive calls.
src/lib/onboard/intent-draft/deps.ts (2)

158-164: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Align compatibility.webSearch with compatibility.messaging.

compatibility.messaging reuses messagingChoices, so a persisted channel stays compatible only when it appears in the offered choices. compatibility.webSearch instead re-calls agentSupportsWebSearchProvider directly and casts an arbitrary string with provider as DraftWebSearchProvider. A persisted provider outside options.webSearchProviders can therefore pass compatibility while no matching choice exists in the UI.

Reuse webSearchChoices for the compatibility predicate. This removes the duplicated call, drops the unchecked cast, and makes both predicates use one rule.

♻️ Proposed refactor
   return {
     prompt: options.prompt,
     log: (message = "") => console.log(message),

Extract the web-search choice builder next to messagingChoices, then reuse it:

+  const webSearchChoices = (agentName: string) =>
+    options.webSearchProviders
+      .filter((provider) =>
+        agentSupportsWebSearchProvider(
+          draftAgent(options, agentName),
+          provider,
+          fromDockerfile,
+          options.rootDir,
+        ),
+      )
+      .map((provider) => ({ value: provider, label: options.webSearchLabelFor(provider) }));
-      webSearch: (agentName, provider) =>
-        agentSupportsWebSearchProvider(
-          draftAgent(options, agentName),
-          provider as DraftWebSearchProvider,
-          fromDockerfile,
-          options.rootDir,
-        ),
+      webSearch: (agentName, provider) =>
+        webSearchChoices(agentName).some((choice) => choice.value === provider),
🤖 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/intent-draft/deps.ts` around lines 158 - 164, Update the
compatibility.webSearch predicate to reuse webSearchChoices, matching
compatibility.messaging’s choice-based compatibility rule. Move or expose the
webSearchChoices builder alongside messagingChoices as needed, remove the direct
agentSupportsWebSearchProvider call and DraftWebSearchProvider cast, and ensure
persisted providers are compatible only when represented in the offered choices.

95-110: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider caching GPU detection and host probing across draft visits.

inferenceChoices calls detectGpu() on every invocation. discoverInferenceIntentChoices then calls detectInferenceProviderHostState with probeOllama: true and probeVllm: true (see src/lib/onboard/setup-nim-flow.ts lines 253-307). The draft flow adds Back and Review navigation, so the user can reach the inference step several times in one session. Each visit repeats GPU detection and provider probing on the prompt path.

If fresh probing per visit is not a requirement, cache the detection result for the draft session. If fresh probing is intended, this is acceptable as-is.

🤖 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/intent-draft/deps.ts` around lines 95 - 110, Cache the GPU
detection and inference-provider host probing within the draft session so
repeated inferenceChoices invocations reuse the existing results. Update the
inferenceChoices flow and its supporting discovery call, using session-scoped
memoization while preserving the current choice mapping and probe behavior;
avoid caching only if fresh detection is explicitly required.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard/intent-draft/ollama-model-selection.ts`:
- Around line 66-81: The locked-model loop can repeat indefinitely after
non-probe validation failures or declined downloads because those branches
continue with the same lockedModel. In the validation-failure and
download-declined branches, return { outcome: "back-to-selection" } when
validation.retry !== "selection" or the download is declined, and add tests
covering both outcomes while preserving the existing probe-failure retry
behavior.

---

Nitpick comments:
In `@src/lib/onboard/intent-draft/deps.ts`:
- Around line 158-164: Update the compatibility.webSearch predicate to reuse
webSearchChoices, matching compatibility.messaging’s choice-based compatibility
rule. Move or expose the webSearchChoices builder alongside messagingChoices as
needed, remove the direct agentSupportsWebSearchProvider call and
DraftWebSearchProvider cast, and ensure persisted providers are compatible only
when represented in the offered choices.
- Around line 95-110: Cache the GPU detection and inference-provider host
probing within the draft session so repeated inferenceChoices invocations reuse
the existing results. Update the inferenceChoices flow and its supporting
discovery call, using session-scoped memoization while preserving the current
choice mapping and probe behavior; avoid caching only if fresh detection is
explicitly required.

In `@src/lib/onboard/intent-draft/ollama-model-selection.ts`:
- Around line 97-103: Update the non-interactive branch in the Ollama model
selection flow to call deps.abortNonInteractive with the existing
download-authorization message instead of calling process.exit(1). Preserve the
current error context and ensure this branch uses the same injected termination
mechanism as the paths near the other abortNonInteractive calls.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b569ba39-4286-4645-8bf5-6dd4cc9da126

📥 Commits

Reviewing files that changed from the base of the PR and between 5f959e5 and 6fc9f60.

📒 Files selected for processing (6)
  • ci/source-architecture-budget.json
  • src/lib/onboard.ts
  • src/lib/onboard/intent-draft/deps.ts
  • src/lib/onboard/intent-draft/index.ts
  • src/lib/onboard/intent-draft/ollama-model-selection.ts
  • src/lib/onboard/intent-draft/runtime.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/onboard/intent-draft/index.ts
  • src/lib/onboard/intent-draft/runtime.ts
  • src/lib/onboard.ts

Comment thread src/lib/onboard/intent-draft/ollama-model-selection.ts
Signed-off-by: Prekshi Vyas <prekshiv@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lib/onboard/intent-draft/seed.test.ts (1)

9-24: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Prove CLI precedence with conflicting environment values.

This test does not distinguish CLI precedence from environment precedence. Add conflicting NEMOCLAW_AGENT and NEMOCLAW_POLICY_TIER values. Keep the expected CLI values.

Proposed test update
-  it("preserves explicit CLI and environment choices for review", () => {
+  it("uses CLI choices over environment choices for review", () => {
     const draft = seedOnboardIntentDraft(
       {
         agent: "hermes",
         sandboxGpu: "enable",
         policyTier: "restricted",
       },
       "hermes-demo",
       {
+        NEMOCLAW_AGENT: "openclaw",
         NEMOCLAW_PROVIDER: "hermesProvider",
         NEMOCLAW_MODEL: "claude",
         NEMOCLAW_HERMES_AUTH_METHOD: "oauth",
         NEMOCLAW_WEB_SEARCH_PROVIDER: "tavily",
         NEMOCLAW_RESOURCE_PROFILE: "large",
+        NEMOCLAW_POLICY_TIER: "balanced",
       },
     );

As per path instructions, review tests for behavioral confidence rather than implementation lock-in.

🤖 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/intent-draft/seed.test.ts` around lines 9 - 24, Update the
test case “preserves explicit CLI and environment choices for review” to add
environment values for NEMOCLAW_AGENT and NEMOCLAW_POLICY_TIER that conflict
with the CLI agent and policyTier inputs. Keep the expected assertions focused
on the existing CLI values so the test verifies CLI precedence while preserving
the current behavior checks.

Source: Path instructions

src/lib/onboard.ts (1)

4006-4061: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Complete intent-draft cutover coverage. runOnboard still calls selectOnboardAgent and setupNim after the boundary. Add public-entrypoint tests for fresh, resume, retry, rebuild, and exit flows that prove accepted values prevent superseded prompts and selections.

🤖 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.ts` around lines 4006 - 4061, Complete the intent-draft
migration in runOnboard by removing or bypassing post-boundary calls to
selectOnboardAgent and setupNim when accepted draft values already provide those
selections. Add public-entrypoint coverage for fresh, resume, retry, rebuild,
and exit flows, verifying accepted values prevent the superseded prompts and
selections while exit preserves the saved-draft return behavior.

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 `@src/lib/onboard/intent-draft/boundary.test.ts`:
- Around line 95-103: Update the rejection test for
crossOnboardIntentDraftBoundary to retain references to the collect and accept
mocks, then assert both were not called after the promise rejects. Keep the
existing rejection message assertion and verify the Apply boundary rejects
before invoking either operation.

---

Outside diff comments:
In `@src/lib/onboard.ts`:
- Around line 4006-4061: Complete the intent-draft migration in runOnboard by
removing or bypassing post-boundary calls to selectOnboardAgent and setupNim
when accepted draft values already provide those selections. Add
public-entrypoint coverage for fresh, resume, retry, rebuild, and exit flows,
verifying accepted values prevent the superseded prompts and selections while
exit preserves the saved-draft return behavior.

In `@src/lib/onboard/intent-draft/seed.test.ts`:
- Around line 9-24: Update the test case “preserves explicit CLI and environment
choices for review” to add environment values for NEMOCLAW_AGENT and
NEMOCLAW_POLICY_TIER that conflict with the CLI agent and policyTier inputs.
Keep the expected assertions focused on the existing CLI values so the test
verifies CLI precedence while preserving the current behavior checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3db04f2c-6c0f-4f90-9235-495fa17ee362

📥 Commits

Reviewing files that changed from the base of the PR and between b3e4d40 and 380d724.

📒 Files selected for processing (23)
  • docs/get-started/quickstart-langchain-deepagents-code.mdx
  • docs/reference/commands.mdx
  • src/lib/onboard.ts
  • src/lib/onboard/intent-draft/boundary.test.ts
  • src/lib/onboard/intent-draft/boundary.ts
  • src/lib/onboard/intent-draft/deps.ts
  • src/lib/onboard/intent-draft/ollama-model-selection.test.ts
  • src/lib/onboard/intent-draft/ollama-model-selection.ts
  • src/lib/onboard/intent-draft/schema.test.ts
  • src/lib/onboard/intent-draft/schema.ts
  • src/lib/onboard/intent-draft/seed.test.ts
  • src/lib/onboard/intent-draft/seed.ts
  • src/lib/onboard/intent-draft/ui.test.ts
  • src/lib/onboard/intent-draft/ui.ts
  • src/lib/onboard/messaging-channel-setup.test.ts
  • src/lib/onboard/policy-selection-recorded-tier.test.ts
  • src/lib/onboard/setup-nim-flow.ts
  • src/lib/onboard/setup-nim-provider-discovery.test.ts
  • src/lib/onboard/setup-nim-provider-discovery.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/onboard-session/intent-draft.test.ts
  • test/fixtures/onboard-intent-draft-pty-driver.ts
  • test/onboard-intent-draft-pty.test.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • src/lib/onboard/messaging-channel-setup.test.ts
  • src/lib/onboard/setup-nim-provider-discovery.test.ts
  • src/lib/state/onboard-session.ts
  • docs/get-started/quickstart-langchain-deepagents-code.mdx
  • src/lib/onboard/intent-draft/schema.test.ts
  • test/fixtures/onboard-intent-draft-pty-driver.ts
  • src/lib/onboard/setup-nim-flow.ts
  • docs/reference/commands.mdx
  • src/lib/onboard/intent-draft/deps.ts
  • test/onboard-intent-draft-pty.test.ts
  • src/lib/onboard/intent-draft/ollama-model-selection.ts
  • src/lib/onboard/intent-draft/seed.ts
  • src/lib/onboard/intent-draft/boundary.ts
  • src/lib/onboard/intent-draft/ui.ts
  • src/lib/onboard/intent-draft/schema.ts

Comment thread src/lib/onboard/intent-draft/boundary.test.ts
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas

Copy link
Copy Markdown
Collaborator Author

CodeRabbit final-pass follow-up on 112db8cef:

  • Added callback non-invocation assertions at the disabled-collection boundary.
  • Strengthened the seed test with conflicting agent and policy environment values, proving CLI precedence.
  • Kept selectOnboardAgent and setupNim intentionally. Apply projects accepted choices into their existing inputs; the selector still resolves the concrete agent object without reopening its picker, while setupNim performs the required post-Apply credential and route materialization. Removing either call would skip required materialization rather than merely remove a superseded prompt. Existing boundary, runtime, agent-selection, provider-discovery, controller, PTY, and provider-state tests cover fresh, resume, retry, rebuild, and exit behavior at the owning seams.

Validation: focused 68/68, changed 10/10, CLI typecheck, test-size, and test-conditional checks passed. Exact-head documentation writer review is PASS (docs-not-needed for this test-only delta).

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

Copy link
Copy Markdown
Collaborator Author

Addressed exact-head advisor blocker PRA-1 in b4af80a0a.

Accepted drafts are now revalidated against the current agent, inference provider/auth, web-search, messaging, managed-tool, resource-profile, sandbox-name, model-safety, and policy menus immediately before the materialization callback. If any recorded choice has become unavailable, onboarding throws the documented fail-closed diagnostic before projecting accepted inputs or starting provider, gateway, Docker, policy, or sandbox work. Regressions cover a removed provider on an accepted resume and prove the materialization callback is not invoked after validation rejects.

Validation: focused 81/81, test:changed 1,037/1,037, CLI typecheck, repository and architecture checks, docs build/variants, normal hooks, exact-head documentation writer review PASS, and exact-head sensitive-path review PASS.

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

Copy link
Copy Markdown
Collaborator Author

Addressed PRA-1 in c522b7f74: onboarding now rejects every custom endpoint URL query parameter (including short signed forms such as ?sig=...) instead of relying on credential-name matching. Seeded, resumed collecting, and accepted drafts revalidate the endpoint before Review or materialization; rejected values cannot persist or render. Added parser, session-persistence, and Review-output regressions. Focused validation passed 44/44 tests, plus CLI type-check, repository checks, docs variants, and docs build.

@prekshivyas

Copy link
Copy Markdown
Collaborator Author

Exact-head CI status for c522b7f74: all eight CLI shards, aggregate CLI tests, build/typecheck, static checks, installer integration, plugin tests, docs receipt/preview/parity, CodeQL, WSL, macOS, CodeRabbit, and the primary PR Review Advisor passed. The advisor recommendation is merge_as_is with 0 blockers, 0 warnings, and 0 suggestions. Remaining red checks are independent repository-wide dependency audits: #8156 updates the reviewed OpenClaw/mcporter/archive graphs, and #8180 updates the MCP tool-discovery runtime used by both sandbox-image builds. E2E cannot start from the failed images. This onboarding PR does not change dependency manifests or lockfiles.

@apurvvkumaria apurvvkumaria added the v0.0.102 Release target label Aug 4, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 4, 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.

@cjagwani

cjagwani commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Exact-head queue follow-up for 84fb9aee2: the bot-authored conflict-resolution merge did not emit the normal PR workflow events. The current head has only the two CodeQL analysis runs plus the CodeRabbit status; ordinary CI, docs receipt validation, advisors, platform checks, and the protected E2E gate are absent.

The PR body’s security and documentation receipts are still bound to c522b7f74, before two merges from main, and the final bot merge resolved overlap in src/lib/onboard.ts, docs/reference/commands.mdx, and the CI budget files. Please create a new signed, GitHub-verified head (or otherwise retrigger the pull_request/pull_request_target checks through the supported maintainer workflow), refresh the exact-head receipts where the effective diff changed, and let the complete required matrix run. I have not edited the author branch, reopened the PR, or treated the sparse CodeQL-only result as merge evidence.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed commit 84fb9aee2. The feature is tied to accepted issue #6005, keeps raw credentials out of the persisted draft, rejects endpoint userinfo/query/fragment input, and keeps materialization behind an accepted review boundary. The commits after the recorded security and documentation reviews are base-refresh merges; I found no new authored behavior or unresolved major review finding. The test inventory covers controller transitions, invalidation, resume revalidation, policy/provider/message handoff, schema, seed, and the PTY boundary.

Approval is blocked because this commit has none of the six required merge-gate checks attached. Do not infer readiness from the earlier local and review evidence. The documentation-writer and sensitive-path receipts also identify commit c522b7f74, so they must be rerun for the current commit before approval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.0.102 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platforms][Onboard][GitHub Issue #6005] nemoclaw onboard wizard has no back-navigation — users cannot correct a previous step without Ctrl+C

4 participants