Skip to content

refactor(onboard): finish oclif flag migration - #5916

Merged
cv merged 6 commits into
mainfrom
codex/refactor-onboard-typed-flags
Jun 28, 2026
Merged

cv merged 6 commits into
mainfrom
codex/refactor-onboard-typed-flags

Conversation

@cv

@cv cv commented Jun 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Finish the onboarding oclif migration by passing parsed flags through a typed command boundary instead of reconstructing argv and parsing it again. This removes the legacy parser and alias-specific action plumbing while preserving domain validation and the public sandbox-first dispatcher.

Changes

  • replace the oclif flags -> string[] -> legacy parser round trip with typed option resolution
  • move GPU flag exclusivity and device dependencies into oclif metadata while retaining file, agent-alias, manifest, and notice validation in the onboarding boundary
  • route setup and setup-spark through the shared onboard action and oclif's native, alias-aware deprecation support
  • delete the manual parser, manual usage renderer, and deprecated alias action facade, for 804 net lines removed
  • replace parser-internal tests with typed resolver, command-boundary, integration, package-contract, and alias-branding coverage
  • cap every function in the affected production cluster at cognitive complexity 10

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: the full CLI integration suite continues to cover onboarding, deprecated aliases, custom Dockerfiles, resume behavior, and agent-specific launchers
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: public commands, flags, and documented semantics are unchanged; existing docs already state that aliases share onboard flags and GPU device selection requires --sandbox-gpu
  • 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: reviewed the typed mapping against every legacy parser branch; targeted, coverage-ratchet, and full-matrix verification passed
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push, or npx prek run --from-ref main --to-ref HEAD passes
  • Targeted tests pass for changed behavior
  • Full npm test passes (broad runtime changes only)
  • 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: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • New Features
    • Onboarding now uses a unified, typed flag flow across commands, improving handling for GPU options, agent selection, and --from/--agents inputs.
  • Bug Fixes
    • Strengthened validation for incompatible GPU and sandbox GPU device combinations, improved errors for missing/invalid agent manifests and invalid Dockerfile --from paths, and tightened --control-ui-port checks.
  • Chores
    • Updated deprecated-alias messaging and help for setup and setup-spark to consistently direct to onboard.
  • Tests
    • Updated/expanded onboarding and compatibility test coverage to match the new typed-flag behavior.

@cv cv self-assigned this Jun 28, 2026
@coderabbitai

coderabbitai Bot commented Jun 28, 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 PR replaces legacy string-array onboarding CLI handling with typed OnboardFlags, adds a new onboarding resolver/executor module, removes legacy onboard helpers, and updates setup and setup-spark to deprecated aliases. Tests and supporting docs/config are updated accordingly.

Changes

Onboard flags migration and legacy removal

Layer / File(s) Summary
Flag contract and complexity override
src/lib/onboard/usage-notice.ts, src/lib/onboard/command-support.ts, biome.json
Adds NOTICE_ACCEPT_FLAG_NAME, updates onboarding flag wiring and GPU exclusivity rules, and adds a Biome complexity override for onboard/setup files.
Onboard option resolution
src/lib/onboard/command.ts, src/lib/actions/onboard.ts
Adds onboarding option resolution and execution helpers, including file and agent resolution, agents-manifest validation, sandbox GPU mapping, and environment setup before invoking onboarding.
Action layer and command entrypoints
src/lib/actions/global.ts, src/commands/onboard.ts, src/commands/setup.ts, src/commands/setup-spark.ts, src/commands/global-oclif-command-adapters.test.ts, src/commands/onboard.test.ts, src/lib/actions/global.test.ts
Updates global action facades to accept typed flags, removes setup action exports, passes onboard flags directly, and converts setup and setup-spark into deprecated aliases that forward to onboard.
Tests, compatibility, and docs support
src/lib/onboard/README.md, src/lib/onboard/legacy-command.ts, src/lib/onboard/legacy-command.test.ts, src/lib/onboard/command.test.ts, src/lib/onboard/command-agents.test.ts, test/cli/onboard-compatibility.test.ts, test/nemohermes-alias.test.ts, test/e2e/e2e-cloud-experimental/check-docs.sh
Updates CLI and resolver tests for typed flag objects and new validation behavior, refreshes deprecated-alias and GPU compatibility coverage, updates onboarding docs support, and removes the legacy onboarding command module and its tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

refactor, area: cli, area: onboarding

Suggested reviewers

  • cjagwani
  • prekshivyas
  • ericksoa
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% 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
Title check ✅ Passed The title is concise and accurately summarizes the main change: completing the onboard CLI's oclif flag migration.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/refactor-onboard-typed-flags

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

@github-code-quality

github-code-quality Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the codex/refactor-onboa... branch is 96%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main codex/refactor-onboa... 4aae41a +/-
nemoclaw/src/se...cret-scanner.ts — 100% —
nemoclaw/src/commands/slash.ts — 100% —
nemoclaw/src/li...bprocess-env.ts — 100% —
nemoclaw/src/bl...eprint/state.ts — 98% —
nemoclaw/src/onboard/config.ts — 98% —
nemoclaw/src/bl...int/snapshot.ts — 97% —
nemoclaw/src/bl...print/runner.ts — 95% —
nemoclaw/src/co...ration-state.ts — 94% —
nemoclaw/src/bl...ate-networks.ts — 94% —
nemoclaw/src/index.ts — 94% —

TypeScript / code-coverage/cli

The overall coverage in the codex/refactor-onboa... branch is 68%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main codex/refactor-onboa... 4aae41a +/-
src/lib/actions...all/run-plan.ts — 80% —
src/lib/state/o...oard-session.ts — 79% —
src/lib/actions...dbox/rebuild.ts — 74% —
src/lib/state/sandbox.ts — 72% —
src/lib/shields/index.ts — 70% —
src/lib/onboard/preflight.ts — 69% —
src/lib/actions...licy-channel.ts — 59% —
src/lib/onboard...er-gpu-patch.ts — 59% —
src/lib/policy/index.ts — 52% —
src/lib/onboard.ts — 20% —

Updated June 28, 2026 01:12 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: cloud-onboard-e2e, onboard-resume-e2e, onboard-repair-e2e, onboard-negative-paths-e2e
Optional E2E: double-onboard-e2e, docs-validation-e2e

Dispatch hint: cloud-onboard-e2e,onboard-resume-e2e,onboard-repair-e2e,onboard-negative-paths-e2e

Auto-dispatched E2E: onboard-resume-e2e via nightly-e2e.yaml at 4aae41a71fb278c33ddf7acf975fb6a2b7184a6d — nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • cloud-onboard-e2e (high): Required because the PR changes the primary onboard command path and option resolution used by full hosted onboarding. This verifies install/public onboarding, sandbox health, policy presets, credential handling, and hosted inference still work through the real user flow.
  • onboard-resume-e2e (medium): Required because --resume forwarding and option construction moved from legacy string parsing to typed oclif flags. This E2E validates interrupted onboard sessions can resume and hydrate persisted credentials/sandbox state correctly.
  • onboard-repair-e2e (medium): Required alongside resume coverage because the command-layer refactor can affect requested sandbox name/provider/model inputs used by resume repair and invalidation paths. This verifies missing-sandbox repair and incompatible resume request rejection against real OpenShell state.
  • onboard-negative-paths-e2e (medium): Required because validation responsibility moves substantially to oclif and the new resolver for conflicting GPU flags, control UI port bounds, Dockerfile --from handling, provider/model honoring, invalid credentials, and friendly failure paths.

Optional E2E

  • double-onboard-e2e (medium): Useful adjacent confidence for repeated onboarding after the shared typed action changes, especially because setup/setup-spark now call the same onboard action directly and re-onboard semantics depend on the same option mapping.
  • docs-validation-e2e (low): Optional because command help/deprecation output and the docs CLI parity extractor changed. This is valuable for docs/help parity but not merge-blocking for runtime onboarding behavior if the required onboard E2Es pass.

New E2E recommendations

  • deprecated onboard aliases (medium): Existing E2Es primarily drive nemoclaw onboard; this PR changes real behavior for nemoclaw setup and nemoclaw setup-spark from legacy alias wrappers to native deprecated oclif commands. Unit/CLI compatibility tests cover parser behavior, but there is no focused E2E that runs a real non-interactive onboarding flow through each deprecated alias.
    • Suggested test: Add an alias-onboard-e2e that performs a minimal hermetic non-interactive onboard through setup and setup-spark, verifies deprecation messaging, and confirms the resulting sandbox/session state matches onboard.
  • OpenClaw agents manifest onboarding (medium): The new --agents resolver validates manifests and sets NEMOCLAW_EXTRA_AGENTS_JSON before onboarding, but existing E2E coverage does not appear to exercise a real sandbox build with a secondary OpenClaw agents manifest from the CLI.
    • Suggested test: Add an openclaw-agents-manifest-onboard-e2e that runs nemoclaw onboard --agents <agents.yaml> with hermetic inference and verifies generated secondary agent directories/configuration inside the sandbox.

Dispatch hint

  • Workflow: nightly-e2e.yaml
  • jobs input: cloud-onboard-e2e,onboard-resume-e2e,onboard-repair-e2e,onboard-negative-paths-e2e

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: ubuntu-repo-cloud-openclaw, onboard-resume-vitest, onboard-repair-vitest, onboard-negative-paths-vitest
Optional Vitest E2E scenarios: ubuntu-repo-cloud-langchain-deepagents-code

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field scenarios=ubuntu-repo-cloud-openclaw
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-repair-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-negative-paths-vitest

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • ubuntu-repo-cloud-openclaw: The PR refactors the onboard command/action boundary from legacy argv forwarding to typed oclif flags. The live-supported baseline OpenClaw scenario exercises the real nemoclaw onboard --non-interactive --yes --yes-i-accept-third-party-software path through Docker/OpenShell and validates the resulting ready state.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field scenarios=ubuntu-repo-cloud-openclaw
  • onboard-resume-vitest: The onboarding command refactor changes how --resume, --fresh, non-interactive, consent, and related flags are parsed and passed into the onboarding session bootstrap. The resume compatibility rule requires the focused live resume job for these paths.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest
  • onboard-repair-vitest: Because the same command/action refactor can affect onboarding repair/backstop behavior from persisted sessions, repair is required alongside resume for state-machine resume/session compatibility coverage.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-repair-vitest
  • onboard-negative-paths-vitest: The PR moves validation and flag handling into the typed onboard command path. This focused live job exercises the direct CLI non-interactive onboard boundary on a negative path and verifies clean user-facing failure output rather than parser/action regressions.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-negative-paths-vitest

Optional Vitest E2E scenarios

  • ubuntu-repo-cloud-langchain-deepagents-code: Optional adjacent coverage for the changed onboard option resolution around agent selection on a live-supported non-default onboarding profile.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field scenarios=ubuntu-repo-cloud-langchain-deepagents-code

Relevant changed files

  • src/commands/onboard.ts
  • src/commands/setup-spark.ts
  • src/commands/setup.ts
  • src/lib/actions/global.ts
  • src/lib/actions/onboard.ts
  • src/lib/onboard/command-support.ts
  • src/lib/onboard/command.ts
  • src/lib/onboard/usage-notice.ts
  • test/e2e/e2e-cloud-experimental/check-docs.sh

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-3: resolveSandboxGpu ignores legacy gpu/no-gpu flags while oclif permits conflicting combinations; then add or justify PRA-T1.
Open items: 2 required · 8 warnings · 2 suggestions · 8 test follow-ups
Since last review: 2 prior items resolved · 5 still apply · 6 new items found

Action checklist

  • PRA-3 Fix: resolveSandboxGpu ignores legacy gpu/no-gpu flags while oclif permits conflicting combinations in src/lib/onboard/command.ts:95
  • PRA-4 Fix: PR feat(mcp): add OpenShell-managed MCP servers #5876 merge conflict risk in src/lib/actions/onboard.ts in src/lib/actions/onboard.ts:1
  • PRA-1 Resolve or justify: Source-of-truth review needed: src/lib/onboard/command-support.ts:45-58 readAgentRegistryNames() lazy require
  • PRA-2 Resolve or justify: Source-of-truth review needed: src/lib/onboard/command-support.ts:63 agentFlagDescription() bare catch
  • PRA-5 Resolve or justify: Credential denylist uses substring matching with false positive/negative risk in src/lib/onboard/agents-manifest.ts:45
  • PRA-6 Resolve or justify: agentFlagDescription catches all exceptions silently in src/lib/onboard/command-support.ts:63
  • PRA-7 Resolve or justify: Lazy require('../agent/defs') creates hidden coupling and load-cycle risk in src/lib/onboard/command-support.ts:45
  • PRA-8 Resolve or justify: Dynamic require('yaml') bypasses static dependency analysis in src/lib/onboard/agents-manifest.ts:23
  • PRA-9 Resolve or justify: Missing credential denylist edge case tests in src/lib/onboard/command-agents.test.ts:1
  • PRA-10 Resolve or justify: Incomplete GPU flag combination test coverage in src/lib/onboard/command.test.ts:1
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Missing credential denylist edge case tests
  • PRA-T7 Add or justify test follow-up: Incomplete GPU flag combination test coverage
  • PRA-T8 Add or justify test follow-up: Legacy gpu/no-gpu flag forwarding not tested through typed action
  • PRA-11 In-scope improvement: Legacy gpu/no-gpu flag forwarding not tested through typed action in src/commands/onboard.test.ts:1
  • PRA-12 In-scope improvement: toLegacyOnboardArgs() removed - good simplification in src/lib/onboard/command-support.ts:1

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture — Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify architecture — Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-3 Required correctness src/lib/onboard/command.ts:95 Add cross-group validation in resolveOnboardOptions that rejects conflicting legacy+sandbox GPU flag combinations, or document that gpu/no-gpu are gateway-level only and sandbox-gpu/no-sandbox-gpu are sandbox-level only with no cross-validation. Add tests for all 16 combinations.
PRA-4 Required architecture src/lib/actions/onboard.ts:1 Coordinate with PR #5876 author to ensure compatible changes. Verify merged result maintains typed OnboardFlags signature and MCP integration works.
PRA-5 Resolve/justify security src/lib/onboard/agents-manifest.ts:45 Document the denylist as advisory-only in code comments. Add tests verifying known credential-like names are caught and known safe names pass.
PRA-6 Resolve/justify correctness src/lib/onboard/command-support.ts:63 Narrow catch to only expected errors (e.g., module not found / MODULE_NOT_FOUND) or log the caught error in debug builds before falling back.
PRA-7 Resolve/justify architecture src/lib/onboard/command-support.ts:45 Either resolve the load cycle to enable static import, or formally document as accepted technical debt with a follow-up issue tracking the removal condition.
PRA-8 Resolve/justify architecture src/lib/onboard/agents-manifest.ts:23 Acceptable for cold-start sensitivity if measurable. Consider if yaml can be optional dependency or if build tooling changes make static import viable. Re-evaluate when build tooling changes.
PRA-9 Resolve/justify tests src/lib/onboard/command-agents.test.ts:1 Add tests for credential denylist edge cases to document expected behavior.
PRA-10 Resolve/justify tests src/lib/onboard/command.test.ts:1 Add test matrix covering all 16 combinations of {gpu, no-gpu, sandbox-gpu, no-sandbox-gpu} to verify parser-level and resolver-level behavior matches expectations.
PRA-11 Improvement tests src/commands/onboard.test.ts:1 Add tests verifying runOnboardAction receives both legacy and sandbox GPU flags correctly, and document expected downstream behavior.
PRA-12 Improvement correctness src/lib/onboard/command-support.ts:1 No action needed - this is a positive simplification.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-3 Required — resolveSandboxGpu ignores legacy gpu/no-gpu flags while oclif permits conflicting combinations

  • Location: src/lib/onboard/command.ts:95
  • Category: correctness
  • Problem: resolveSandboxGpu() only evaluates sandbox-gpu/no-sandbox-gpu flags, ignoring legacy gpu/no-gpu flags entirely. Legacy validation rejected combinations like --gpu --no-sandbox-gpu, but oclif exclusive constraints only cover within each flag group. The two flag systems can now express conflicting intent that passes parsing but produces undefined behavior downstream.
  • Impact: Users can pass --gpu --no-sandbox-gpu or --no-gpu --sandbox-gpu and receive no error; downstream behavior is undefined because resolver only looks at sandbox flags while action layer may still read legacy flags.
  • Required action: Add cross-group validation in resolveOnboardOptions that rejects conflicting legacy+sandbox GPU flag combinations, or document that gpu/no-gpu are gateway-level only and sandbox-gpu/no-sandbox-gpu are sandbox-level only with no cross-validation. Add tests for all 16 combinations.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check command.ts resolveSandboxGpu function and command-support.ts exclusive constraints for gpu/no-gpu vs sandbox-gpu/no-sandbox-gpu groups
  • Missing regression test: Add parametrized test for resolveOnboardOptions with all GPU flag combinations (legacy x sandbox) verifying rejection or documented behavior
  • Done when: The required change is committed and verification passes: Check command.ts resolveSandboxGpu function and command-support.ts exclusive constraints for gpu/no-gpu vs sandbox-gpu/no-sandbox-gpu groups.
  • Evidence: command.ts:95 resolveSandboxGpu only checks flags['sandbox-gpu'] and flags['no-sandbox-gpu']; command-support.ts:49-70 oclif exclusive constraints are within-group only

PRA-4 Required — PR #5876 merge conflict risk in src/lib/actions/onboard.ts

  • Location: src/lib/actions/onboard.ts:1
  • Category: architecture
  • Problem: PR feat(mcp): add OpenShell-managed MCP servers #5876 (feat: MCP servers) also modifies src/lib/actions/onboard.ts. Current PR changes the function signature from string[] to OnboardFlags. Merge conflict is likely. Previous review (PRA-10) flagged this.
  • Impact: Merging either PR first will cause the other to conflict on the runOnboardAction signature and call sites. The typed OnboardFlags signature must be preserved in the merged result.
  • Required action: Coordinate with PR feat(mcp): add OpenShell-managed MCP servers #5876 author to ensure compatible changes. Verify merged result maintains typed OnboardFlags signature and MCP integration works.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Compare this PR's onboard.ts changes with PR feat(mcp): add OpenShell-managed MCP servers #5876 diff for runOnboardAction signature and call sites
  • Missing regression test: Integration test after merge verifying both typed flags and MCP server functionality
  • Done when: The required change is committed and verification passes: Compare this PR's onboard.ts changes with PR feat(mcp): add OpenShell-managed MCP servers #5876 diff for runOnboardAction signature and call sites.
  • Evidence: openPrOverlaps shows PR feat(mcp): add OpenShell-managed MCP servers #5876 modifies src/lib/actions/onboard.ts; this PR changes runOnboardAction signature from string[] to OnboardFlags
Review findings by urgency: 2 required fixes, 8 items to resolve/justify, 2 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: src/lib/onboard/command-support.ts:45-58 readAgentRegistryNames() lazy require

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Not directly testable - architectural constraint. Document in follow-up issue.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: command-support.ts lines 45-58 with comment 'Remove this fallback only after command-class load no longer crosses the agent/defs -> runner chain...'

PRA-2 Resolve/justify — Source-of-truth review needed: src/lib/onboard/command-support.ts:63 agentFlagDescription() bare catch

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Add test verifying agentFlagDescription returns valid string even when listAgents throws unexpected error type
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: command-support.ts line 63: catch { return describeAgentFlag([]); } with no error narrowing or logging

PRA-5 Resolve/justify — Credential denylist uses substring matching with false positive/negative risk

  • Location: src/lib/onboard/agents-manifest.ts:45
  • Category: security
  • Problem: Credential denylist in assertNoCredentialFields uses substring matching (CREDENTIAL_NAME_SUBSTRINGS) which may produce false positives (e.g., 'passphrase' catches 'passphraseless') and false negatives (e.g., 'apisecret' not caught). Comment acknowledges this is defense-in-depth with authoritative validation at build-time.
  • Impact: Operators may be confused by false positives blocking legitimate config, or false negatives allowing credential-like names to reach build context (though build validator catches them).
  • Recommended action: Document the denylist as advisory-only in code comments. Add tests verifying known credential-like names are caught and known safe names pass.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check agents-manifest.ts assertNoCredentialFields function and CREDENTIAL_NAME_SUBSTRINGS array
  • Missing regression test: Add test for credential denylist false positive/negative cases documenting expected behavior
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check agents-manifest.ts assertNoCredentialFields function and CREDENTIAL_NAME_SUBSTRINGS array.
  • Evidence: agents-manifest.ts:45-70 CREDENTIAL_NAME_SUBSTRINGS includes 'passphrase', 'token', 'secret', 'password' etc. with substring matching

PRA-6 Resolve/justify — agentFlagDescription catches all exceptions silently

  • Location: src/lib/onboard/command-support.ts:63
  • Category: correctness
  • Problem: agentFlagDescription() catches all exceptions and falls back to empty agent list. This masks genuine errors (e.g., agent/defs module corruption, import errors) behind silent degradation. Previous review (PRA-3/PRA-6) flagged this.
  • Impact: If agent/defs module has a genuine error (syntax error, missing dependency, corruption), users see generic help instead of actionable error message. Debugging becomes harder.
  • Recommended action: Narrow catch to only expected errors (e.g., module not found / MODULE_NOT_FOUND) or log the caught error in debug builds before falling back.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect command-support.ts line 63 catch block: catch { return describeAgentFlag([]); }
  • Missing regression test: Add test verifying agentFlagDescription returns valid string even when listAgents throws unexpected error type
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect command-support.ts line 63 catch block: catch { return describeAgentFlag([]); }.
  • Evidence: command-support.ts:63 bare catch with no error logging or narrowing

PRA-7 Resolve/justify — Lazy require('../agent/defs') creates hidden coupling and load-cycle risk

  • Location: src/lib/onboard/command-support.ts:45
  • Category: architecture
  • Problem: readAgentRegistryNames() uses lazy require('../agent/defs') to avoid load cycle during command-class static flag evaluation. This bypasses static dependency analysis and creates hidden coupling. Previous review (PRA-1/PRA-4) flagged this. Comment documents removal condition: 'command-class load no longer crosses agent/defs -> runner chain.'
  • Impact: Static analysis cannot trace this dependency; load cycle risk if agent/defs imports change; test mocking requires setAgentRegistryReaderForTest() workaround.
  • Recommended action: Either resolve the load cycle to enable static import, or formally document as accepted technical debt with a follow-up issue tracking the removal condition.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Search for 'Remove this fallback only after' comment in command-support.ts around line 45-58; check if agent/defs still imports runner
  • Missing regression test: Not directly testable - architectural constraint. Document in follow-up issue.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Search for 'Remove this fallback only after' comment in command-support.ts around line 45-58; check if agent/defs still imports runner.
  • Evidence: command-support.ts:45-58 readAgentRegistryNames uses require('../agent/defs') with comment documenting load cycle and removal condition

PRA-8 Resolve/justify — Dynamic require('yaml') bypasses static dependency analysis

  • Location: src/lib/onboard/agents-manifest.ts:23
  • Category: architecture
  • Problem: loadYaml() uses dynamic require('yaml') for lazy loading to avoid cold-start cost. This bypasses static dependency analysis. Previous review (PRA-2/PRA-5) flagged this. Pattern existed in legacy code.
  • Impact: Static analysis tools cannot see yaml dependency; bundlers may not include it correctly; dependency audit tools miss it.
  • Recommended action: Acceptable for cold-start sensitivity if measurable. Consider if yaml can be optional dependency or if build tooling changes make static import viable. Re-evaluate when build tooling changes.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check agents-manifest.ts loadYaml function at line 23
  • Missing regression test: Not applicable - infrastructure pattern
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check agents-manifest.ts loadYaml function at line 23.
  • Evidence: agents-manifest.ts:23-28 loadYaml() returns require('yaml') with comment about cold-start

PRA-9 Resolve/justify — Missing credential denylist edge case tests

  • Location: src/lib/onboard/command-agents.test.ts:1
  • Category: tests
  • Problem: New command-agents.test.ts covers --agents manifest lifecycle but doesn't test the credential denylist behavior (false positives/negatives) which is defense-in-depth security control.
  • Impact: No automated verification that denylist behaves as expected for edge cases; future refactors could change behavior silently.
  • Recommended action: Add tests for credential denylist edge cases to document expected behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check command-agents.test.ts for denylist tests (none present)
  • Missing regression test: Add tests for agents manifest credential denylist false positive/negative cases
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check command-agents.test.ts for denylist tests (none present).
  • Evidence: command-agents.test.ts has 4 tests covering path resolution, missing file, non-OpenClaw rejection, env application - no denylist tests

PRA-10 Resolve/justify — Incomplete GPU flag combination test coverage

  • Location: src/lib/onboard/command.test.ts:1
  • Category: tests
  • Problem: The new resolveOnboardOptions tests don't cover conflicting legacy gpu/no-gpu with sandbox-gpu/no-sandbox-gpu combinations that oclif now permits but legacy validation rejected.
  • Impact: No automated verification that resolver handles all 16 GPU flag combinations correctly; behavior is undefined for cross-group conflicts.
  • Recommended action: Add test matrix covering all 16 combinations of {gpu, no-gpu, sandbox-gpu, no-sandbox-gpu} to verify parser-level and resolver-level behavior matches expectations.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check command.test.ts for GPU flag test cases - only sandbox-gpu tests present
  • Missing regression test: Add parametrized test for all GPU flag combinations
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check command.test.ts for GPU flag test cases - only sandbox-gpu tests present.
  • Evidence: command.test.ts has 10 tests but only one tests sandbox-gpu; no tests for legacy gpu/no-gpu or cross-group combinations

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

PRA-11 Improvement — Legacy gpu/no-gpu flag forwarding not tested through typed action

  • Location: src/commands/onboard.test.ts:1
  • Category: tests
  • Problem: onboard.test.ts now tests oclif-level GPU flag exclusivity but doesn't test the resolver behavior for the legacy gpu/no-gpu flags which are still accepted by oclif but ignored by resolveSandboxGpu().
  • Impact: No verification that runOnboardAction receives both legacy and sandbox GPU flags correctly, and no documentation of expected downstream behavior.
  • Suggested action: Add tests verifying runOnboardAction receives both legacy and sandbox GPU flags correctly, and document expected downstream behavior.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check onboard.test.ts GPU flag tests - only sandbox-gpu tests present
  • Missing regression test: Add test for legacy gpu/no-gpu flag forwarding through typed action
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: onboard.test.ts tests sandbox-gpu and no-sandbox-gpu but not legacy gpu/no-gpu

PRA-12 Improvement — toLegacyOnboardArgs() removed - good simplification

  • Location: src/lib/onboard/command-support.ts:1
  • Category: correctness
  • Problem: toLegacyOnboardArgs() removed entirely. Direct typed flag passing through action layer eliminates conversion layer.
  • Impact: Positive simplification - removes 43 lines of flag-to-argv conversion code that was a source of bugs.
  • Suggested action: No action needed - this is a positive simplification.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Verify toLegacyOnboardArgs no longer exists in codebase
  • Missing regression test: N/A - simplification verified by removal
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: command-support.ts diff shows -43 lines for toLegacyOnboardArgs function
Simplification opportunities: 1 possible cut, net -43 lines possible

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-12 delete (src/lib/onboard/command-support.ts:1): toLegacyOnboardArgs() function (43 lines) converting OnboardFlags to string[]
    • Replacement: Direct OnboardFlags object passed through action layer
    • Net: -43 lines
    • Safety boundary: Action layer runOnboardAction signature changed from string[] to OnboardFlags; all call sites updated
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Add parametrized test for resolveOnboardOptions with all 16 GPU flag combinations (legacy gpu/no-gpu x sandbox-gpu/no-sandbox-gpu) verifying rejection or documented behavior. Runtime/sandbox/infrastructure paths need behavioral runtime validation: biome.json, src/commands/onboard.ts, src/commands/setup-spark.ts, src/commands/setup.ts, src/lib/actions/global.ts, src/lib/actions/onboard.ts, src/lib/onboard/README.md, src/lib/onboard/command-support.ts. GPU flag cross-validation gap requires runtime verification of downstream behavior.
  • PRA-T2 Runtime validation — Add test for credential denylist false positive/negative cases in agents-manifest. Runtime/sandbox/infrastructure paths need behavioral runtime validation: biome.json, src/commands/onboard.ts, src/commands/setup-spark.ts, src/commands/setup.ts, src/lib/actions/global.ts, src/lib/actions/onboard.ts, src/lib/onboard/README.md, src/lib/onboard/command-support.ts. GPU flag cross-validation gap requires runtime verification of downstream behavior.
  • PRA-T3 Runtime validation — Add test verifying agentFlagDescription returns valid string when listAgents throws unexpected error type. Runtime/sandbox/infrastructure paths need behavioral runtime validation: biome.json, src/commands/onboard.ts, src/commands/setup-spark.ts, src/commands/setup.ts, src/lib/actions/global.ts, src/lib/actions/onboard.ts, src/lib/onboard/README.md, src/lib/onboard/command-support.ts. GPU flag cross-validation gap requires runtime verification of downstream behavior.
  • PRA-T4 Runtime validation — Add test for legacy gpu/no-gpu flag forwarding through typed action to verify downstream receives both flag sets. Runtime/sandbox/infrastructure paths need behavioral runtime validation: biome.json, src/commands/onboard.ts, src/commands/setup-spark.ts, src/commands/setup.ts, src/lib/actions/global.ts, src/lib/actions/onboard.ts, src/lib/onboard/README.md, src/lib/onboard/command-support.ts. GPU flag cross-validation gap requires runtime verification of downstream behavior.
  • PRA-T5 Runtime validation — Integration test after PR feat(mcp): add OpenShell-managed MCP servers #5876 merge verifying both typed flags and MCP server functionality. Runtime/sandbox/infrastructure paths need behavioral runtime validation: biome.json, src/commands/onboard.ts, src/commands/setup-spark.ts, src/commands/setup.ts, src/lib/actions/global.ts, src/lib/actions/onboard.ts, src/lib/onboard/README.md, src/lib/onboard/command-support.ts. GPU flag cross-validation gap requires runtime verification of downstream behavior.
  • PRA-T6 Missing credential denylist edge case tests — Add tests for credential denylist edge cases to document expected behavior.
  • PRA-T7 Incomplete GPU flag combination test coverage — Add test matrix covering all 16 combinations of {gpu, no-gpu, sandbox-gpu, no-sandbox-gpu} to verify parser-level and resolver-level behavior matches expectations.
  • PRA-T8 Legacy gpu/no-gpu flag forwarding not tested through typed action — Add tests verifying runOnboardAction receives both legacy and sandbox GPU flags correctly, and document expected downstream behavior.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: src/lib/onboard/command-support.ts:45-58 readAgentRegistryNames() lazy require

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Not directly testable - architectural constraint. Document in follow-up issue.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: command-support.ts lines 45-58 with comment 'Remove this fallback only after command-class load no longer crosses the agent/defs -> runner chain...'

PRA-2 Resolve/justify — Source-of-truth review needed: src/lib/onboard/command-support.ts:63 agentFlagDescription() bare catch

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Add test verifying agentFlagDescription returns valid string even when listAgents throws unexpected error type
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: command-support.ts line 63: catch { return describeAgentFlag([]); } with no error narrowing or logging

PRA-3 Required — resolveSandboxGpu ignores legacy gpu/no-gpu flags while oclif permits conflicting combinations

  • Location: src/lib/onboard/command.ts:95
  • Category: correctness
  • Problem: resolveSandboxGpu() only evaluates sandbox-gpu/no-sandbox-gpu flags, ignoring legacy gpu/no-gpu flags entirely. Legacy validation rejected combinations like --gpu --no-sandbox-gpu, but oclif exclusive constraints only cover within each flag group. The two flag systems can now express conflicting intent that passes parsing but produces undefined behavior downstream.
  • Impact: Users can pass --gpu --no-sandbox-gpu or --no-gpu --sandbox-gpu and receive no error; downstream behavior is undefined because resolver only looks at sandbox flags while action layer may still read legacy flags.
  • Required action: Add cross-group validation in resolveOnboardOptions that rejects conflicting legacy+sandbox GPU flag combinations, or document that gpu/no-gpu are gateway-level only and sandbox-gpu/no-sandbox-gpu are sandbox-level only with no cross-validation. Add tests for all 16 combinations.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check command.ts resolveSandboxGpu function and command-support.ts exclusive constraints for gpu/no-gpu vs sandbox-gpu/no-sandbox-gpu groups
  • Missing regression test: Add parametrized test for resolveOnboardOptions with all GPU flag combinations (legacy x sandbox) verifying rejection or documented behavior
  • Done when: The required change is committed and verification passes: Check command.ts resolveSandboxGpu function and command-support.ts exclusive constraints for gpu/no-gpu vs sandbox-gpu/no-sandbox-gpu groups.
  • Evidence: command.ts:95 resolveSandboxGpu only checks flags['sandbox-gpu'] and flags['no-sandbox-gpu']; command-support.ts:49-70 oclif exclusive constraints are within-group only

PRA-4 Required — PR #5876 merge conflict risk in src/lib/actions/onboard.ts

  • Location: src/lib/actions/onboard.ts:1
  • Category: architecture
  • Problem: PR feat(mcp): add OpenShell-managed MCP servers #5876 (feat: MCP servers) also modifies src/lib/actions/onboard.ts. Current PR changes the function signature from string[] to OnboardFlags. Merge conflict is likely. Previous review (PRA-10) flagged this.
  • Impact: Merging either PR first will cause the other to conflict on the runOnboardAction signature and call sites. The typed OnboardFlags signature must be preserved in the merged result.
  • Required action: Coordinate with PR feat(mcp): add OpenShell-managed MCP servers #5876 author to ensure compatible changes. Verify merged result maintains typed OnboardFlags signature and MCP integration works.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Compare this PR's onboard.ts changes with PR feat(mcp): add OpenShell-managed MCP servers #5876 diff for runOnboardAction signature and call sites
  • Missing regression test: Integration test after merge verifying both typed flags and MCP server functionality
  • Done when: The required change is committed and verification passes: Compare this PR's onboard.ts changes with PR feat(mcp): add OpenShell-managed MCP servers #5876 diff for runOnboardAction signature and call sites.
  • Evidence: openPrOverlaps shows PR feat(mcp): add OpenShell-managed MCP servers #5876 modifies src/lib/actions/onboard.ts; this PR changes runOnboardAction signature from string[] to OnboardFlags

PRA-5 Resolve/justify — Credential denylist uses substring matching with false positive/negative risk

  • Location: src/lib/onboard/agents-manifest.ts:45
  • Category: security
  • Problem: Credential denylist in assertNoCredentialFields uses substring matching (CREDENTIAL_NAME_SUBSTRINGS) which may produce false positives (e.g., 'passphrase' catches 'passphraseless') and false negatives (e.g., 'apisecret' not caught). Comment acknowledges this is defense-in-depth with authoritative validation at build-time.
  • Impact: Operators may be confused by false positives blocking legitimate config, or false negatives allowing credential-like names to reach build context (though build validator catches them).
  • Recommended action: Document the denylist as advisory-only in code comments. Add tests verifying known credential-like names are caught and known safe names pass.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check agents-manifest.ts assertNoCredentialFields function and CREDENTIAL_NAME_SUBSTRINGS array
  • Missing regression test: Add test for credential denylist false positive/negative cases documenting expected behavior
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check agents-manifest.ts assertNoCredentialFields function and CREDENTIAL_NAME_SUBSTRINGS array.
  • Evidence: agents-manifest.ts:45-70 CREDENTIAL_NAME_SUBSTRINGS includes 'passphrase', 'token', 'secret', 'password' etc. with substring matching

PRA-6 Resolve/justify — agentFlagDescription catches all exceptions silently

  • Location: src/lib/onboard/command-support.ts:63
  • Category: correctness
  • Problem: agentFlagDescription() catches all exceptions and falls back to empty agent list. This masks genuine errors (e.g., agent/defs module corruption, import errors) behind silent degradation. Previous review (PRA-3/PRA-6) flagged this.
  • Impact: If agent/defs module has a genuine error (syntax error, missing dependency, corruption), users see generic help instead of actionable error message. Debugging becomes harder.
  • Recommended action: Narrow catch to only expected errors (e.g., module not found / MODULE_NOT_FOUND) or log the caught error in debug builds before falling back.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect command-support.ts line 63 catch block: catch { return describeAgentFlag([]); }
  • Missing regression test: Add test verifying agentFlagDescription returns valid string even when listAgents throws unexpected error type
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect command-support.ts line 63 catch block: catch { return describeAgentFlag([]); }.
  • Evidence: command-support.ts:63 bare catch with no error logging or narrowing

PRA-7 Resolve/justify — Lazy require('../agent/defs') creates hidden coupling and load-cycle risk

  • Location: src/lib/onboard/command-support.ts:45
  • Category: architecture
  • Problem: readAgentRegistryNames() uses lazy require('../agent/defs') to avoid load cycle during command-class static flag evaluation. This bypasses static dependency analysis and creates hidden coupling. Previous review (PRA-1/PRA-4) flagged this. Comment documents removal condition: 'command-class load no longer crosses agent/defs -> runner chain.'
  • Impact: Static analysis cannot trace this dependency; load cycle risk if agent/defs imports change; test mocking requires setAgentRegistryReaderForTest() workaround.
  • Recommended action: Either resolve the load cycle to enable static import, or formally document as accepted technical debt with a follow-up issue tracking the removal condition.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Search for 'Remove this fallback only after' comment in command-support.ts around line 45-58; check if agent/defs still imports runner
  • Missing regression test: Not directly testable - architectural constraint. Document in follow-up issue.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Search for 'Remove this fallback only after' comment in command-support.ts around line 45-58; check if agent/defs still imports runner.
  • Evidence: command-support.ts:45-58 readAgentRegistryNames uses require('../agent/defs') with comment documenting load cycle and removal condition

PRA-8 Resolve/justify — Dynamic require('yaml') bypasses static dependency analysis

  • Location: src/lib/onboard/agents-manifest.ts:23
  • Category: architecture
  • Problem: loadYaml() uses dynamic require('yaml') for lazy loading to avoid cold-start cost. This bypasses static dependency analysis. Previous review (PRA-2/PRA-5) flagged this. Pattern existed in legacy code.
  • Impact: Static analysis tools cannot see yaml dependency; bundlers may not include it correctly; dependency audit tools miss it.
  • Recommended action: Acceptable for cold-start sensitivity if measurable. Consider if yaml can be optional dependency or if build tooling changes make static import viable. Re-evaluate when build tooling changes.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check agents-manifest.ts loadYaml function at line 23
  • Missing regression test: Not applicable - infrastructure pattern
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check agents-manifest.ts loadYaml function at line 23.
  • Evidence: agents-manifest.ts:23-28 loadYaml() returns require('yaml') with comment about cold-start

PRA-9 Resolve/justify — Missing credential denylist edge case tests

  • Location: src/lib/onboard/command-agents.test.ts:1
  • Category: tests
  • Problem: New command-agents.test.ts covers --agents manifest lifecycle but doesn't test the credential denylist behavior (false positives/negatives) which is defense-in-depth security control.
  • Impact: No automated verification that denylist behaves as expected for edge cases; future refactors could change behavior silently.
  • Recommended action: Add tests for credential denylist edge cases to document expected behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check command-agents.test.ts for denylist tests (none present)
  • Missing regression test: Add tests for agents manifest credential denylist false positive/negative cases
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check command-agents.test.ts for denylist tests (none present).
  • Evidence: command-agents.test.ts has 4 tests covering path resolution, missing file, non-OpenClaw rejection, env application - no denylist tests

PRA-10 Resolve/justify — Incomplete GPU flag combination test coverage

  • Location: src/lib/onboard/command.test.ts:1
  • Category: tests
  • Problem: The new resolveOnboardOptions tests don't cover conflicting legacy gpu/no-gpu with sandbox-gpu/no-sandbox-gpu combinations that oclif now permits but legacy validation rejected.
  • Impact: No automated verification that resolver handles all 16 GPU flag combinations correctly; behavior is undefined for cross-group conflicts.
  • Recommended action: Add test matrix covering all 16 combinations of {gpu, no-gpu, sandbox-gpu, no-sandbox-gpu} to verify parser-level and resolver-level behavior matches expectations.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check command.test.ts for GPU flag test cases - only sandbox-gpu tests present
  • Missing regression test: Add parametrized test for all GPU flag combinations
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check command.test.ts for GPU flag test cases - only sandbox-gpu tests present.
  • Evidence: command.test.ts has 10 tests but only one tests sandbox-gpu; no tests for legacy gpu/no-gpu or cross-group combinations

PRA-11 Improvement — Legacy gpu/no-gpu flag forwarding not tested through typed action

  • Location: src/commands/onboard.test.ts:1
  • Category: tests
  • Problem: onboard.test.ts now tests oclif-level GPU flag exclusivity but doesn't test the resolver behavior for the legacy gpu/no-gpu flags which are still accepted by oclif but ignored by resolveSandboxGpu().
  • Impact: No verification that runOnboardAction receives both legacy and sandbox GPU flags correctly, and no documentation of expected downstream behavior.
  • Suggested action: Add tests verifying runOnboardAction receives both legacy and sandbox GPU flags correctly, and document expected downstream behavior.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check onboard.test.ts GPU flag tests - only sandbox-gpu tests present
  • Missing regression test: Add test for legacy gpu/no-gpu flag forwarding through typed action
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: onboard.test.ts tests sandbox-gpu and no-sandbox-gpu but not legacy gpu/no-gpu

PRA-12 Improvement — toLegacyOnboardArgs() removed - good simplification

  • Location: src/lib/onboard/command-support.ts:1
  • Category: correctness
  • Problem: toLegacyOnboardArgs() removed entirely. Direct typed flag passing through action layer eliminates conversion layer.
  • Impact: Positive simplification - removes 43 lines of flag-to-argv conversion code that was a source of bugs.
  • Suggested action: No action needed - this is a positive simplification.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Verify toLegacyOnboardArgs no longer exists in codebase
  • Missing regression test: N/A - simplification verified by removal
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: command-support.ts diff shows -43 lines for toLegacyOnboardArgs function

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: No advisor follow-up required beyond maintainer review.
Open items: 0 required · 0 warnings · 0 suggestions · 0 test follow-ups
Since last review: 0 prior items resolved · 0 still apply · 0 new items found

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Run cancelled — no signal

Run: 28306797930
Target ref: 293796e315e004c9c91adffb6817015812e67dfc
Workflow ref: main
Requested jobs: onboard-resume-e2e
Summary: 0 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
onboard-resume-e2e ⚠️ cancelled

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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

Inline comments:
In `@src/lib/onboard/command-agents.test.ts`:
- Around line 17-24: The test in resolveOnboardOptions is still using an
already-absolute manifestPath, so it does not verify canonicalization behavior.
Update the setup in command-agents.test.ts to pass a relative agents manifest
input and then assert the returned agentsManifest matches path.resolve(...) of
that input, keeping the test focused on behavior rather than implementation
details.

In `@src/lib/onboard/command.test.ts`:
- Around line 169-171: The cleanup in the test’s finally block uses an if
statement that triggers the guardrail; rewrite the restore logic in
onbboard/command.test.ts using a conditional expression instead. Keep the same
behavior for process.env.NEMOCLAW_OLLAMA_NO_AUTOSTART by preserving the previous
value when defined and deleting it when undefined, but do so without introducing
a new if inside the cleanup path.
- Around line 101-107: The test for resolveOnboardOptions() is locking in an
absolute-path implementation by passing an already resolved Dockerfile path and
expecting it back unchanged. Update the case in command.test.ts to use a
relative --from input while still validating the file on disk, and assert that
the original relative string is preserved by resolve() via fromDockerfile
instead of comparing against an absolute path.
🪄 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: bc1e1b40-a016-47c8-9da1-bf64c9a12d8e

📥 Commits

Reviewing files that changed from the base of the PR and between 30261d5 and 293796e.

📒 Files selected for processing (19)
  • biome.json
  • src/commands/global-oclif-command-adapters.test.ts
  • src/commands/onboard.test.ts
  • src/commands/onboard.ts
  • src/commands/setup-spark.ts
  • src/commands/setup.ts
  • src/lib/actions/global.test.ts
  • src/lib/actions/global.ts
  • src/lib/actions/onboard.ts
  • src/lib/onboard/README.md
  • src/lib/onboard/command-agents.test.ts
  • src/lib/onboard/command-support.ts
  • src/lib/onboard/command.test.ts
  • src/lib/onboard/command.ts
  • src/lib/onboard/legacy-command.test.ts
  • src/lib/onboard/legacy-command.ts
  • src/lib/onboard/usage-notice.ts
  • test/cli/onboard-compatibility.test.ts
  • test/nemohermes-alias.test.ts
💤 Files with no reviewable changes (2)
  • src/lib/onboard/legacy-command.test.ts
  • src/lib/onboard/legacy-command.ts

Comment thread src/lib/onboard/command-agents.test.ts Resolved
Comment thread src/lib/onboard/command.test.ts Resolved
Comment thread src/lib/onboard/command.test.ts Resolved
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Run cancelled — no signal

Run: 28306916072
Target ref: 8ce452f4c9eb5216beb9ff058d1d7c1bab27b12a
Workflow ref: main
Requested jobs: onboard-resume-e2e
Summary: 0 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
onboard-resume-e2e ⚠️ cancelled

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28306983686
Target ref: d2354b09a65eacba9190d65efba467be03cf765b
Workflow ref: main
Requested jobs: onboard-resume-e2e
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
onboard-resume-e2e ✅ success

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Run cancelled — no signal

Run: 28307130192
Target ref: 90af8b473010fa77c540a3d3691d883ab1f320cc
Workflow ref: main
Requested jobs: onboard-resume-e2e
Summary: 0 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
onboard-resume-e2e ⚠️ cancelled

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ⚠️ Run cancelled — no signal

Run: 28307184939
Target ref: 3ab966e1eb5bde4d5059ca9c968e416036d15e34
Workflow ref: main
Requested jobs: onboard-resume-e2e
Summary: 0 passed, 0 failed, 1 cancelled, 0 skipped

Job Result
onboard-resume-e2e ⚠️ cancelled

@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Automated-review follow-up for the Nemotron findings:

  • PRA-3, PRA-10, and PRA-11 do not require another code change. buildOnboardFlags() already declares the cross-group exclusions: gpu excludes no-sandbox-gpu, and no-gpu excludes sandbox-gpu, with the reciprocal exclusions on the sandbox flags. The parameterized test in src/commands/onboard.test.ts covers all four incompatible pairs (gpu/no-gpu, sandbox-gpu/no-sandbox-gpu, gpu/no-sandbox-gpu, and no-gpu/sandbox-gpu) and verifies dispatch never occurs. Direct CLI verification of both cross-group pairs exits 2. resolveSandboxGpu() intentionally maps only the sandbox dimension; the gateway-level values remain separately represented as gpu and noGpu in OnboardCommandOptions.
  • PRA-4 is a merge-order concern, not a defect in this branch. PR feat(mcp): add OpenShell-managed MCP servers #5876 is still open and also touches src/lib/actions/onboard.ts; after this typed boundary lands, feat(mcp): add OpenShell-managed MCP servers #5876 must rebase and preserve the OnboardFlags action signature while resolving its MCP changes.
  • PRA-1, PRA-2, and PRA-5 through PRA-9 describe pre-existing code unchanged from main, or tests the advisor overlooked. In particular, src/lib/onboard/agents-manifest.test.ts already covers credential-shaped nested keys and benign field names. Expanding this focused migration into the existing lazy-load/cold-start architecture would add unrelated risk.
  • The actionable test follow-ups were completed in this PR: alias/canonical typed-option equivalence, rejection before manifest environment mutation, the control-UI port lower bound, and relative --from/--agents path contracts.

The final head has green CLI shards, checks, CLI/docs parity, growth guardrails, CodeQL, CodeRabbit, both review advisors, WSL/macOS, installer, and sandbox smoke lanes.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28307280628
Target ref: 4aae41a71fb278c33ddf7acf975fb6a2b7184a6d
Workflow ref: main
Requested jobs: onboard-resume-e2e
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
onboard-resume-e2e ✅ success

@cv
cv merged commit 047cc89 into main Jun 28, 2026
51 checks passed
@cv
cv deleted the codex/refactor-onboard-typed-flags branch June 28, 2026 01:25
@cv cv mentioned this pull request Jun 28, 2026
11 of 21 tasks
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Finish the onboarding oclif migration by passing parsed flags through a
typed command boundary instead of reconstructing argv and parsing it
again. This removes the legacy parser and alias-specific action plumbing
while preserving domain validation and the public sandbox-first
dispatcher.

## Changes

- replace the `oclif flags -> string[] -> legacy parser` round trip with
typed option resolution
- move GPU flag exclusivity and device dependencies into oclif metadata
while retaining file, agent-alias, manifest, and notice validation in
the onboarding boundary
- route `setup` and `setup-spark` through the shared onboard action and
oclif's native, alias-aware deprecation support
- delete the manual parser, manual usage renderer, and deprecated alias
action facade, for 804 net lines removed
- replace parser-internal tests with typed resolver, command-boundary,
integration, package-contract, and alias-branding coverage
- cap every function in the affected production cluster at cognitive
complexity 10

## Type of Change

- [x] 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
<!-- Check all that apply. For any "covered by existing tests", "not
applicable", or waiver entry, add a brief justification on the same line
or in the Changes section. -->
- [x] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification: the full
CLI integration suite continues to cover onboarding, deprecated aliases,
custom Dockerfiles, resume behavior, and agent-specific launchers
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: public commands, flags, and
documented semantics are unchanged; existing docs already state that
aliases share onboard flags and GPU device selection requires
`--sandbox-gpu`
- [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: reviewed the typed
mapping against every legacy parser branch; targeted, coverage-ratchet,
and full-matrix verification passed
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each item you ran and confirmed. Leave unchecked items you
skipped. Doc-only changes do not require npm test unless you ran it. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [x] Full `npm test` passes (broad runtime changes only)
- [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)
- [ ] 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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


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

* **New Features**
* Onboarding now uses a unified, typed flag flow across commands,
improving handling for GPU options, agent selection, and
`--from`/`--agents` inputs.
* **Bug Fixes**
* Strengthened validation for incompatible GPU and sandbox GPU device
combinations, improved errors for missing/invalid agent manifests and
invalid Dockerfile `--from` paths, and tightened `--control-ui-port`
checks.
* **Chores**
* Updated deprecated-alias messaging and help for `setup` and
`setup-spark` to consistently direct to `onboard`.
* **Tests**
* Updated/expanded onboarding and compatibility test coverage to match
the new typed-flag behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow refactor PR restructures code without intended behavior change labels Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow refactor PR restructures code without intended behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants