Skip to content

feat(contributor): add read-only developer environment doctor - #6109

Merged
apurvvkumaria merged 5 commits into
mainfrom
feat/contributor-dev-doctor
Jul 1, 2026
Merged

feat(contributor): add read-only developer environment doctor#6109
apurvvkumaria merged 5 commits into
mainfrom
feat/contributor-dev-doctor

Conversation

@apurvvkumaria

@apurvvkumaria apurvvkumaria commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a read-only contributor environment doctor so NemoClaw developers can identify source-checkout, toolchain, Git, GitHub, and Docker readiness issues before starting work or opening a pull request. This is the first independently useful contributor-onboarding slice from #6103 and complements the existing end-user installer and coding-agent starter prompt.

Related Issue

Closes #6105.

Changes

  • Add ./scripts/dev-setup.sh --doctor and expose it as npm run dev:doctor.
  • Check supported tools, repository dependencies, fresh build artifacts, prek hooks, contributor identity and signing, GitHub authentication, Docker availability/resources, and local CLI linkage without changing the host.
  • Align Docker results with the published 4-vCPU/8-GiB minimum and 16-GiB memory recommendation.
  • Add controlled integration fixtures for ready, missing, stale, invalid, authentication, redaction, runtime, and exit-code behavior.
  • Document the contributor readiness workflow and correct uv sync to run from the repository root.

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:
  • 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)

Verification evidence:

  • npx vitest run --project integration test/dev-setup-doctor.test.ts — 11 tests passed.
  • npm run typecheck:cli, npm run checks, npm run test:titles:check, and npm run test-size:check passed.
  • shfmt, ShellCheck, Biome, markdownlint, repository checks, commitlint, secret scanning, and the normal pre-push hooks passed.
  • npm run docs completed with 0 errors and 2 existing Fern warnings.
  • The final commit skipped the full test-cli pre-commit hook after its supported-toolchain run exposed five unrelated macOS integration failures in Deep Agents TUI, gateway-supervisor Python startup, and sandbox auto-pair approval tests. The new doctor integration suite passes independently; CI confirmation and any required maintainer acceptance remain pending while this PR is a draft.

Signed-off-by: Apurv Kumaria akumaria@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added a new dev:doctor check to validate contributor environment readiness.
    • Expanded setup guidance with a clear read-only environment verification workflow.
  • Bug Fixes

    • Updated install instructions to remove an extra directory change.
    • Clarified setup steps for handling environment check failures and reruns.
  • Documentation

    • Revised contributor and setup docs to point to the new environment check and updated pre-change workflow.

@copy-pr-bot

copy-pr-bot Bot commented Jul 1, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new read-only contributor environment doctor script (scripts/dev-setup.sh --doctor) that checks toolchain versions, build artifacts, Git configuration, GitHub auth, Docker, and local CLI installation. Exposes it via a new npm run dev:doctor script, updates AGENTS.md and CONTRIBUTING.md, and adds test coverage.

Changes

Contributor environment doctor

Layer / File(s) Summary
Script setup and version checks
scripts/dev-setup.sh
Establishes entrypoint, strict mode, path resolution, pass/warn/fail counters, output helpers, and version parsing/comparison utilities.
Artifact, git, auth, docker, and CLI checks
scripts/dev-setup.sh
Implements build artifact staleness checks, Git identity/signing/hooks verification, GitHub auth check, Docker reachability/resource checks, and local CLI installation consistency check.
Main flow and npm wiring
scripts/dev-setup.sh, package.json
Gates --doctor argument, verifies checkout, runs all checks in sequence, prints summary and exit status, and adds dev:doctor npm script.
Contributor documentation updates
AGENTS.md, CONTRIBUTING.md
Documents corrected root-level uv sync and new npm run dev:doctor readiness check across Quick Reference, prerequisites, setup instructions, and Main Tasks table.
Doctor test suite
test/dev-setup-doctor.test.ts
Adds fixture-based Vitest suite covering readiness, remediation messaging, redaction, staleness detection, and exit codes.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DevSetupScript
  participant GitConfig
  participant GitHubCLI
  participant Docker

  User->>DevSetupScript: npm run dev:doctor
  DevSetupScript->>GitConfig: check_git_configuration
  GitConfig-->>DevSetupScript: identity/signing/hooks result
  DevSetupScript->>GitHubCLI: gh auth status
  GitHubCLI-->>DevSetupScript: auth result
  DevSetupScript->>Docker: docker info
  Docker-->>DevSetupScript: CPU/memory/storage
  DevSetupScript-->>User: pass/warn/fail summary
Loading

Possibly related issues

Suggested labels: feature, area: cli, area: docs

Suggested reviewers: ericksoa, jyaunches

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main addition: a read-only contributor environment doctor.
Linked Issues check ✅ Passed The summaries show the requested read-only doctor, docs, and tests covering the required readiness checks and non-mutating behavior.
Out of Scope Changes check ✅ Passed Only the doctor script, its tests, and related contributor docs were changed; no unrelated scope is evident.
✨ 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 feat/contributor-dev-doctor

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

Comment thread scripts/dev-setup.sh
@github-code-quality

github-code-quality Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the feat/contributor-dev... 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 feat/contributor-dev... 88ab5fa +/-
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 feat/contributor-dev... 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 feat/contributor-dev... 88ab5fa +/-
src/lib/shields...nsition-lock.ts 86%
src/lib/actions...dbox/rebuild.ts 80%
src/lib/actions...all/run-plan.ts 80%
src/lib/state/o...oard-session.ts 80%
src/lib/state/sandbox.ts 72%
src/lib/shields/index.ts 69%
src/lib/onboard/preflight.ts 69%
src/lib/onboard...er-gpu-patch.ts 59%
src/lib/actions...licy-channel.ts 58%
src/lib/onboard.ts 20%

Updated July 01, 2026 18:47 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: None
Optional E2E: None

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • None. No E2E is required. This PR adds contributor-facing setup diagnostics and documentation, with focused non-live tests for the new doctor script. It does not modify installer/onboarding implementation, sandbox lifecycle, credential handling, security boundaries, network policy, inference routing, deployment, or real assistant user flows.

Optional E2E

  • None.

New E2E recommendations

  • None.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: None
Optional E2E targets: None

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • None. This PR changes contributor documentation, a root package script, a developer setup doctor script, and non-E2E unit/integration coverage. It does not change test/e2e/, .github/workflows/e2e.yaml, E2E target registry/runtime support, shared E2E fixtures, or target-relevant runtime paths.

Optional E2E targets

  • None.

Relevant changed files

  • None.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-6: Pre-release version suffixes silently accepted in extract_version; then add or justify PRA-T1.
Open items: 3 required · 17 warnings · 3 suggestions · 8 test follow-ups
Since last review: 0 prior items resolved · 23 still apply · 0 new items found

Action checklist

  • PRA-6 Fix: Pre-release version suffixes silently accepted in extract_version in scripts/dev-setup.sh:45
  • PRA-7 Fix: Source-of-truth: pre-release version handling is a localized workaround in scripts/dev-setup.sh:45
  • PRA-8 Fix: Test asserts specific gpg.format but script accepts any format in test/dev-setup-doctor.test.ts:64
  • PRA-1 Resolve or justify: Source-of-truth review needed: extract_version regex (scripts/dev-setup.sh:45)
  • PRA-2 Resolve or justify: Source-of-truth review needed: check_build_artifact mtime check (scripts/dev-setup.sh:121)
  • PRA-3 Resolve or justify: Source-of-truth review needed: check_docker docker info parsing (scripts/dev-setup.sh:216)
  • PRA-4 Resolve or justify: Source-of-truth review needed: check_git_configuration gpg.format passthrough (scripts/dev-setup.sh:150)
  • PRA-5 Resolve or justify: Source-of-truth review needed: check_local_cli path grep (scripts/dev-setup.sh:250)
  • PRA-9 Resolve or justify: mtime-based staleness detection misses content changes with preserved timestamps in scripts/dev-setup.sh:121
  • PRA-10 Resolve or justify: Source-of-truth: mtime-based staleness detection is a localized workaround in scripts/dev-setup.sh:121
  • PRA-11 Resolve or justify: Docker resource check uses VM resources, not host resources on macOS/Windows in scripts/dev-setup.sh:216
  • PRA-12 Resolve or justify: Source-of-truth: Docker VM resource reporting is a localized workaround in scripts/dev-setup.sh:216
  • PRA-13 Resolve or justify: GitHub authentication doesn't cross-check authenticated user vs git identity in scripts/dev-setup.sh:185
  • PRA-T1 Add or justify test follow-up: Mocked behavioral coverage
  • PRA-T2 Add or justify test follow-up: Mocked behavioral coverage
  • PRA-T3 Add or justify test follow-up: Mocked behavioral coverage
  • PRA-T4 Add or justify test follow-up: Mocked behavioral coverage
  • PRA-T5 Add or justify test follow-up: Mocked behavioral coverage
  • PRA-T6 Add or justify test follow-up: Test asserts specific gpg.format but script accepts any format
  • PRA-T7 Add or justify test follow-up: Test suite missing coverage for several error branches
  • PRA-T8 Add or justify test follow-up: extract_version regex (scripts/dev-setup.sh:45)
  • PRA-21 In-scope improvement: Test suite missing coverage for several error branches in test/dev-setup-doctor.test.ts:1
  • PRA-22 In-scope improvement: Complete source-of-truth analysis for pre-release version handling in scripts/dev-setup.sh:45
  • PRA-23 In-scope improvement: Complete source-of-truth analysis for Docker VM resource reporting in scripts/dev-setup.sh:216

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 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-4 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-5 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-6 Required correctness scripts/dev-setup.sh:45 Either reject pre-release versions explicitly in extract_version (e.g., fail if input matches -rc|-beta|-alpha|-dev), or document that pre-releases are unsupported and the check treats them as their base version. Add test case for 'v22.16.0-rc.1'.
PRA-7 Required architecture scripts/dev-setup.sh:45 Fix the invalid state at source by rejecting pre-releases in extract_version, or explicitly document the limitation with a regression test proving pre-releases are handled intentionally.
PRA-8 Required tests test/dev-setup-doctor.test.ts:64 Either validate gpg.format against allowed values (openpgp, ssh, x509) in the script, or update the test to not assert a specific format in the output (just assert 'Git commit signing configured').
PRA-9 Resolve/justify correctness scripts/dev-setup.sh:121 Document the mtime limitation in a comment above check_build_artifact. Consider adding a content-hash fallback (e.g., sha256sum of source tree vs stored hash) for critical artifacts if this becomes a real issue in practice.
PRA-10 Resolve/justify architecture scripts/dev-setup.sh:121 Document the limitation explicitly. Add content-hash fallback for critical artifacts if needed.
PRA-11 Resolve/justify correctness scripts/dev-setup.sh:216 Document in the remediation message that this checks Docker VM/container-runtime resources, not host resources. Consider adding an env var override (e.g., NEMOCLAW_DEV_DOCTOR_MIN_MEMORY_GIB) for CI environments with constrained Docker VMs.
PRA-12 Resolve/justify architecture scripts/dev-setup.sh:216 Document that check uses container-runtime (VM) resources. Add env var override for CI.
PRA-13 Resolve/justify security scripts/dev-setup.sh:185 Add a cross-check: after 'gh auth status' succeeds, run 'gh api user --jq .login' and compare with git config user.email domain or warn if they appear unrelated. Or document as known limitation.
PRA-14 Resolve/justify security scripts/dev-setup.sh:192 Consider using the full path to docker (e.g., /usr/bin/docker) or validate the docker binary is the expected one (check version output format). Document that the script trusts the PATH-resolved docker.
PRA-15 Resolve/justify correctness test/dev-setup-doctor.test.ts:85 Update test to verify the executable check: create .venv/bin/python without execute bit and assert failure, or document that the test only covers missing directory.
PRA-16 Resolve/justify correctness scripts/dev-setup.sh:243 Add a lightweight invocation test after path verification: 'nemoclaw --version 2>/dev/null || fail "Local NemoClaw CLI is not functional" "Run: npm install"'.
PRA-17 Resolve/justify correctness scripts/dev-setup.sh:192 Add a version format check after 'docker --version' to verify it's the real Docker CLI before calling 'docker info'.
PRA-18 Resolve/justify scope scripts/dev-setup.sh:50 Add a comment explaining why pure bash is used (portability, works even if Node is broken). This is already a reasonable design decision; just needs documentation.
PRA-19 Resolve/justify docs AGENTS.md:14 Add a one-line note in AGENTS.md quick reference: 'The doctor is read-only — it never installs packages, changes configuration, or starts services.'
PRA-20 Resolve/justify scope scripts/dev-setup.sh:230 Strengthen the check: verify the CLI file is the actual launcher (e.g., check shebang, or that it's a symlink to the real file), not just a text match.

🚨 Required before merge

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

PRA-6 Required — Pre-release version suffixes silently accepted in extract_version

  • Location: scripts/dev-setup.sh:45
  • Category: correctness
  • Problem: The extract_version regex `s/^[^0-9]*([0-9]+([.][0-9]+){0,2}).*/\1/` drops pre-release suffixes (-rc, -beta, -alpha, -dev). Input 'v22.16.0-rc.1' becomes '22.16.0' and passes the minimum version check. Node.js 22.16.0 is a stable release requirement; pre-releases should not satisfy it.
  • Impact: A contributor using Node.js 22.16.0-rc.1 (or any pre-release) would pass the minimum version check even though pre-releases are not supported. Minimum versions checked (Node 22.16.0, npm 10.0.0, Python 3.11.0) are stable releases, so practical risk is low but behavior is undocumented and inconsistent with semver.
  • Required action: Either reject pre-release versions explicitly in extract_version (e.g., fail if input matches -rc|-beta|-alpha|-dev), or document that pre-releases are unsupported and the check treats them as their base version. Add test case for 'v22.16.0-rc.1'.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run: echo 'v22.16.0-rc.1' | sed -E 's/^[^0-9]*([0-9]+([.][0-9]+){0,2}).*/\1/' — returns '22.16.0'. Mock node --version to return 'v22.16.0-rc.1' and run doctor; it passes incorrectly.
  • Missing regression test: Add test case in test/dev-setup-doctor.test.ts: mock node to return 'v22.16.0-rc.1' and assert doctor fails or warns about pre-release version.
  • Done when: The required change is committed and verification passes: Run: echo 'v22.16.0-rc.1' | sed -E 's/^[^0-9]*([0-9]+([.][0-9]+){0,2}).*/\1/' — returns '22.16.0'. Mock node --version to return 'v22.16.0-rc.1' and run doctor; it passes incorrectly.
  • Evidence: scripts/dev-setup.sh lines 45-70: extract_version function and version_at_least comparison

PRA-7 Required — Source-of-truth: pre-release version handling is a localized workaround

  • Location: scripts/dev-setup.sh:45
  • Category: architecture
  • Problem: Pre-release version handling is a localized workaround. Invalid state: pre-release versions (v22.16.0-rc.1) pass as stable. Source boundary: version extraction regex. Source-fix constraint: Node.js --version output format is stable; could reject pre-releases at source. Regression test: mock pre-release version. Removal condition: when version extraction is replaced by a proper semver parser.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear. The script silently accepts pre-releases as stable versions.
  • Required action: Fix the invalid state at source by rejecting pre-releases in extract_version, or explicitly document the limitation with a regression test proving pre-releases are handled intentionally.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Inspect extract_version function and test coverage for pre-release inputs.
  • Missing regression test: Add test case mocking node --version = 'v22.16.0-rc.1' and assert failure or explicit warning.
  • Done when: The required change is committed and verification passes: Inspect extract_version function and test coverage for pre-release inputs.
  • Evidence: scripts/dev-setup.sh lines 45-70

PRA-8 Required — Test asserts specific gpg.format but script accepts any format

  • Location: test/dev-setup-doctor.test.ts:64
  • Category: tests
  • Problem: Test expects 'Git commit signing configured (ssh)' but script passes any gpg.format value (openpgp, ssh, x509, or arbitrary string) without validation.
  • Impact: Test is brittle and asserts behavior the script doesn't guarantee. Invalid gpg.format values would pass the doctor silently.
  • Required action: Either validate gpg.format against allowed values (openpgp, ssh, x509) in the script, or update the test to not assert a specific format in the output (just assert 'Git commit signing configured').
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Set git config gpg.format=invalid and run doctor; it passes with '(invalid)' in output.
  • Missing regression test: Add test case with invalid gpg.format and assert warning or failure, or update existing test to accept any format.
  • Done when: The required change is committed and verification passes: Set git config gpg.format=invalid and run doctor; it passes with '(invalid)' in output.
  • Evidence: test/dev-setup-doctor.test.ts line 64 expects '(ssh)'; scripts/dev-setup.sh line 150 uses ${sign_format:-openpgp} without validation
Review findings by urgency: 3 required fixes, 17 items to resolve/justify, 3 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: extract_version regex (scripts/dev-setup.sh:45)

  • 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: Mock node --version = 'v22.16.0-rc.1' and assert doctor fails or warns
  • 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: scripts/dev-setup.sh lines 45-70

PRA-2 Resolve/justify — Source-of-truth review needed: check_build_artifact mtime check (scripts/dev-setup.sh:121)

  • 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: Touch file, change content, preserve mtime with touch -d; assert doctor detects staleness
  • 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: scripts/dev-setup.sh lines 121-136

PRA-3 Resolve/justify — Source-of-truth review needed: check_docker docker info parsing (scripts/dev-setup.sh:216)

  • 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: Mock docker info with 2 CPU / 4 GiB; assert failure with VM-specific message or env var override
  • 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: scripts/dev-setup.sh lines 216-230

PRA-4 Resolve/justify — Source-of-truth review needed: check_git_configuration gpg.format passthrough (scripts/dev-setup.sh:150)

  • 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: Set gpg.format=invalid and run doctor; should warn or fail
  • 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: scripts/dev-setup.sh line 150: ${sign_format:-openpgp} without validation

PRA-5 Resolve/justify — Source-of-truth review needed: check_local_cli path grep (scripts/dev-setup.sh:250)

  • 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: Create shim with path string but different target; assert doctor detects or documents limitation
  • 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: scripts/dev-setup.sh lines 243-265

PRA-9 Resolve/justify — mtime-based staleness detection misses content changes with preserved timestamps

  • Location: scripts/dev-setup.sh:121
  • Category: correctness
  • Problem: check_build_artifact uses find -newer and file -nt which compare mtime. If a source file's content changes but mtime is preserved (e.g., git checkout, some editors, build systems), the artifact is incorrectly considered fresh.
  • Impact: Contributors may run with stale build artifacts without warning, leading to confusing test failures or runtime behavior mismatches.
  • Recommended action: Document the mtime limitation in a comment above check_build_artifact. Consider adding a content-hash fallback (e.g., sha256sum of source tree vs stored hash) for critical artifacts if this becomes a real issue in practice.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Touch a source file to update mtime, change its content, then restore original mtime with touch -d. Run doctor; it reports artifact as fresh.
  • Missing regression test: Add test case: create source file, build artifact, modify source content while preserving mtime, assert doctor detects staleness.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Touch a source file to update mtime, change its content, then restore original mtime with touch -d. Run doctor; it reports artifact as fresh.
  • Evidence: scripts/dev-setup.sh lines 121-136: check_build_artifact function

PRA-10 Resolve/justify — Source-of-truth: mtime-based staleness detection is a localized workaround

  • Location: scripts/dev-setup.sh:121
  • Category: architecture
  • Problem: Invalid state: content changes with preserved timestamps not detected. Source boundary: filesystem timestamps. Source-fix constraint: timestamp resolution limit; content hash would be heavier. Regression test: touch file, change content, preserve mtime. Removal condition: content-hash fallback for critical artifacts.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Document the limitation explicitly. Add content-hash fallback for critical artifacts if needed.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect check_build_artifact and test coverage for mtime-preserved content changes.
  • Missing regression test: Add test case demonstrating mtime-preserved content change detection gap.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect check_build_artifact and test coverage for mtime-preserved content changes.
  • Evidence: scripts/dev-setup.sh lines 121-136

PRA-11 Resolve/justify — Docker resource check uses VM resources, not host resources on macOS/Windows

  • Location: scripts/dev-setup.sh:216
  • Category: correctness
  • Problem: docker info reports container-runtime (VM) resources, not host resources. On Docker Desktop (macOS/Windows), MemTotal and NCPU reflect the VM allocation, not the physical host.
  • Impact: Contributors on macOS/Windows with adequate host resources but constrained Docker VMs will see false failures. Conversely, contributors with large VM allocations on small hosts may see false passes.
  • Recommended action: Document in the remediation message that this checks Docker VM/container-runtime resources, not host resources. Consider adding an env var override (e.g., NEMOCLAW_DEV_DOCTOR_MIN_MEMORY_GIB) for CI environments with constrained Docker VMs.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: On macOS with Docker Desktop set to 4 GiB, run doctor on a 16 GiB host; it fails with 'below minimum 8 GiB' despite host having 16 GiB.
  • Missing regression test: Add test case with NEMOCLAW_DEV_DOCTOR_MIN_MEMORY_GIB override and mocked docker info showing constrained VM.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: On macOS with Docker Desktop set to 4 GiB, run doctor on a 16 GiB host; it fails with 'below minimum 8 GiB' despite host having 16 GiB.
  • Evidence: scripts/dev-setup.sh lines 216-230: check_docker function

PRA-12 Resolve/justify — Source-of-truth: Docker VM resource reporting is a localized workaround

  • Location: scripts/dev-setup.sh:216
  • Category: architecture
  • Problem: Invalid state: VM resources reported as host. Source boundary: docker info API. Source-fix constraint: Docker Desktop virtualizes; host API not portable. Regression test: mock constrained VM. Removal condition: env var override or host API.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Document that check uses container-runtime (VM) resources. Add env var override for CI.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect check_docker and test coverage for VM vs host resource distinction.
  • Missing regression test: Add test case with mocked docker info showing 2 CPU / 4 GiB and assert failure with VM-specific message.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect check_docker and test coverage for VM vs host resource distinction.
  • Evidence: scripts/dev-setup.sh lines 216-230

PRA-13 Resolve/justify — GitHub authentication doesn't cross-check authenticated user vs git identity

  • Location: scripts/dev-setup.sh:185
  • Category: security
  • Problem: gh auth status only verifies that some token is valid. It does not verify that the authenticated GitHub user matches the git user.email or user.name configured in the repository.
  • Impact: A contributor could have gh authenticated as user A but git config set to user B. Commits would be attributed to user B but PRs pushed as user A, causing confusion in DCO verification and commit signing.
  • Recommended action: Add a cross-check: after 'gh auth status' succeeds, run 'gh api user --jq .login' and compare with git config user.email domain or warn if they appear unrelated. Or document as known limitation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Configure gh auth as user A, git user.email as user B@example.com. Run doctor; it passes without warning.
  • Missing regression test: Add test case with mismatched gh user and git email, assert warning.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Configure gh auth as user A, git user.email as user B@example.com. Run doctor; it passes without warning.
  • Evidence: scripts/dev-setup.sh lines 185-190: check_github_authentication function

PRA-14 Resolve/justify — docker command resolved via PATH without validation

  • Location: scripts/dev-setup.sh:192
  • Category: security
  • Problem: command -v docker trusts the first docker in PATH. A malicious or misconfigured PATH could resolve to a wrapper that exfiltrates credentials or returns falsified docker info output.
  • Impact: In compromised environments, doctor could report false Docker resource info or leak credentials via docker command stderr.
  • Recommended action: Consider using the full path to docker (e.g., /usr/bin/docker) or validate the docker binary is the expected one (check version output format). Document that the script trusts the PATH-resolved docker.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create a fake docker in PATH that echoes fake resources; doctor reports fake resources.
  • Missing regression test: Add test case with fake docker in PATH returning false resources, assert doctor detects or documents trust assumption.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create a fake docker in PATH that echoes fake resources; doctor reports fake resources.
  • Evidence: scripts/dev-setup.sh line 192: command -v docker

PRA-15 Resolve/justify — Python environment test doesn't verify executable bit check

  • Location: test/dev-setup-doctor.test.ts:85
  • Category: correctness
  • Problem: Test only removes .venv directory to test missing Python. It does not test the case where .venv/bin/python exists but lacks execute permissions.
  • Impact: If a contributor's Python binary loses execute bit (e.g., filesystem issue, bad checkout), doctor would report 'missing or not executable' but the test doesn't cover this path.
  • Recommended action: Update test to verify the executable check: create .venv/bin/python without execute bit and assert failure, or document that the test only covers missing directory.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: chmod -x .venv/bin/python and run doctor; it fails with 'missing or not executable'.
  • Missing regression test: Add test case: create .venv/bin/python without execute bit, assert doctor fails with executable error.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: chmod -x .venv/bin/python and run doctor; it fails with 'missing or not executable'.
  • Evidence: test/dev-setup-doctor.test.ts lines 110-117: only tests missing directory

PRA-16 Resolve/justify — Local CLI check verifies path but not execution

  • Location: scripts/dev-setup.sh:243
  • Category: correctness
  • Problem: check_local_cli verifies that nemoclaw on PATH resolves to this checkout via path string matching. It does not actually invoke the CLI to verify it executes correctly.
  • Impact: A broken symlink, corrupted bin/nemoclaw.js, or version mismatch would pass the path check but fail at runtime.
  • Recommended action: Add a lightweight invocation test after path verification: 'nemoclaw --version 2>/dev/null || fail "Local NemoClaw CLI is not functional" "Run: npm install"'.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create a broken nemoclaw symlink pointing to this checkout but with invalid content; doctor passes path check.
  • Missing regression test: Add test case with broken CLI executable that passes path check but fails --version invocation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create a broken nemoclaw symlink pointing to this checkout but with invalid content; doctor passes path check.
  • Evidence: scripts/dev-setup.sh lines 243-265: check_local_cli function

PRA-17 Resolve/justify — docker version format not validated before docker info call

  • Location: scripts/dev-setup.sh:192
  • Category: correctness
  • Problem: Script calls docker info without first verifying docker --version output matches expected format. A fake docker binary could pass command -v but fail docker info or return malicious output.
  • Impact: Reduces confidence that docker info output is from genuine Docker CLI.
  • Recommended action: Add a version format check after 'docker --version' to verify it's the real Docker CLI before calling 'docker info'.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create fake docker that returns 'Docker version 999.999.999' but docker info returns fake resources; doctor accepts it.
  • Missing regression test: Add test case with fake docker version format, assert validation or documented trust.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create fake docker that returns 'Docker version 999.999.999' but docker info returns fake resources; doctor accepts it.
  • Evidence: scripts/dev-setup.sh lines 192-214: check_docker function

PRA-18 Resolve/justify — Custom bash semver comparison could use comment explaining portability rationale

  • Location: scripts/dev-setup.sh:50
  • Category: scope
  • Problem: version_at_least implements semver comparison in pure bash. No comment explains why not using Node/Python/uv for this.
  • Impact: Future maintainers may incorrectly assume this is a bug or attempt to replace with external dependency.
  • Recommended action: Add a comment explaining why pure bash is used (portability, works even if Node is broken). This is already a reasonable design decision; just needs documentation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect version_at_least function for explanatory comment.
  • Missing regression test: N/A — documentation improvement
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect version_at_least function for explanatory comment.
  • Evidence: scripts/dev-setup.sh lines 50-70: version_at_least function

PRA-19 Resolve/justify — AGENTS.md quick reference doesn't explicitly state doctor is read-only

  • Location: AGENTS.md:14
  • Category: docs
  • Problem: CONTRIBUTING.md documents that the doctor is read-only, but AGENTS.md quick reference table only shows the command without the read-only guarantee.
  • Impact: Contributors reading AGENTS.md may not know the doctor is safe to run repeatedly without side effects.
  • Recommended action: Add a one-line note in AGENTS.md quick reference: 'The doctor is read-only — it never installs packages, changes configuration, or starts services.'
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read AGENTS.md quick reference table; no read-only mention for dev:doctor.
  • Missing regression test: N/A — documentation improvement
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read AGENTS.md quick reference table; no read-only mention for dev:doctor.
  • Evidence: AGENTS.md line 14: quick reference table entry for dev:doctor

PRA-20 Resolve/justify — CLI path grep check could false-pass on shim containing path string

  • Location: scripts/dev-setup.sh:230
  • Category: scope
  • Problem: grep -Fq "${REPO_ROOT}/bin/nemoclaw.js" "${cli_path}" checks if the repo path appears anywhere in the CLI file content. A shim script containing that path string (e.g., as a comment or variable) would false-pass.
  • Impact: A wrapper/shim that references the real CLI path but executes something else would pass the check.
  • Recommended action: Strengthen the check: verify the CLI file is the actual launcher (e.g., check shebang, or that it's a symlink to the real file), not just a text match.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create a shim script containing the repo path string but executing different code; doctor passes.
  • Missing regression test: Add test case with shim containing path string but different target, assert doctor detects or documents limitation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create a shim script containing the repo path string but executing different code; doctor passes.
  • Evidence: scripts/dev-setup.sh line 250: grep -Fq check

💡 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-21 Improvement — Test suite missing coverage for several error branches

  • Location: test/dev-setup-doctor.test.ts:1
  • Category: tests
  • Problem: Prior review identified 8 missing test scenarios (PRA-T1 through PRA-T8): pre-release versions, executable bit, gpg.format validation, mtime edge cases, Docker VM vs host, gh auth cross-check, docker PATH validation, Python version comparison.
  • Impact: Reduced confidence in edge case handling. Bugs in these paths would not be caught by regression tests.
  • Suggested action: Add test cases for each missing scenario to improve confidence in edge cases. Prioritize: pre-release version rejection, Python executable bit, gpg.format validation, mtime edge case.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Run test suite and verify coverage report shows gaps in these branches.
  • Missing regression test: Add 8 new test cases covering: pre-release Node version, non-executable Python, invalid gpg.format, mtime-preserved content change, Docker VM override, gh/git identity mismatch, fake docker PATH, Python version_at_least unit tests.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: test/dev-setup-doctor.test.ts: 11 tests, missing 8+ scenarios from prior review

PRA-22 Improvement — Complete source-of-truth analysis for pre-release version handling

  • Location: scripts/dev-setup.sh:45
  • Category: architecture
  • Problem: Prior review PRA-19: Complete source-of-truth analysis: invalid state = pre-releases accepted as stable; source boundary = version extraction regex; source-fix constraint = Node --version format stable; regression test = mock pre-release; removal condition = proper semver parser.
  • Impact: Without completing the analysis, the workaround remains undocumented and the removal condition unknown.
  • Suggested action: Complete the source-of-truth analysis by documenting: invalid state, source boundary, why source can't be fixed in this PR, regression test proving source can't regress, and removal condition.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Review extract_version function and surrounding comments for source-of-truth documentation.
  • Missing regression test: Add documentation comment and regression test for pre-release handling.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: scripts/dev-setup.sh lines 45-70

PRA-23 Improvement — Complete source-of-truth analysis for Docker VM resource reporting

  • Location: scripts/dev-setup.sh:216
  • Category: architecture
  • Problem: Prior review PRA-20: Complete source-of-truth analysis: invalid state = VM resources reported as host; source boundary = docker info API; source-fix constraint = Docker Desktop virtualizes; regression test = mock constrained VM; removal condition = env var override or host API.
  • Impact: Without completing the analysis, the workaround remains undocumented and the removal condition unknown.
  • Suggested action: Complete the source-of-truth analysis by documenting: invalid state, source boundary, why source can't be fixed in this PR, regression test proving source can't regress, and removal condition.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Review check_docker function and surrounding comments for source-of-truth documentation.
  • Missing regression test: Add documentation comment and regression test for Docker VM vs host.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: scripts/dev-setup.sh lines 216-230
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 Mocked behavioral coverage — it("rejects pre-release Node version v22.16.0-rc.1"). Runtime/sandbox/infrastructure paths need behavioral runtime validation for the new doctor script. Current tests use controlled command stubs (good) but miss 8+ edge case scenarios identified in prior review.
  • PRA-T2 Mocked behavioral coverage — it("rejects non-executable Python binary"). Runtime/sandbox/infrastructure paths need behavioral runtime validation for the new doctor script. Current tests use controlled command stubs (good) but miss 8+ edge case scenarios identified in prior review.
  • PRA-T3 Mocked behavioral coverage — it("validates gpg.format against allowed values"). Runtime/sandbox/infrastructure paths need behavioral runtime validation for the new doctor script. Current tests use controlled command stubs (good) but miss 8+ edge case scenarios identified in prior review.
  • PRA-T4 Mocked behavioral coverage — it("detects content change with preserved mtime"). Runtime/sandbox/infrastructure paths need behavioral runtime validation for the new doctor script. Current tests use controlled command stubs (good) but miss 8+ edge case scenarios identified in prior review.
  • PRA-T5 Mocked behavioral coverage — it("allows NEMOCLAW_DEV_DOCTOR_MIN_MEMORY_GIB override for Docker VM"). Runtime/sandbox/infrastructure paths need behavioral runtime validation for the new doctor script. Current tests use controlled command stubs (good) but miss 8+ edge case scenarios identified in prior review.
  • PRA-T6 Test asserts specific gpg.format but script accepts any format — Either validate gpg.format against allowed values (openpgp, ssh, x509) in the script, or update the test to not assert a specific format in the output (just assert 'Git commit signing configured').
  • PRA-T7 Test suite missing coverage for several error branches — Add test cases for each missing scenario to improve confidence in edge cases. Prioritize: pre-release version rejection, Python executable bit, gpg.format validation, mtime edge case.
  • PRA-T8 extract_version regex (scripts/dev-setup.sh:45) — Mock node --version = 'v22.16.0-rc.1' and assert doctor fails or warns. scripts/dev-setup.sh lines 45-70
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: extract_version regex (scripts/dev-setup.sh:45)

  • 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: Mock node --version = 'v22.16.0-rc.1' and assert doctor fails or warns
  • 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: scripts/dev-setup.sh lines 45-70

PRA-2 Resolve/justify — Source-of-truth review needed: check_build_artifact mtime check (scripts/dev-setup.sh:121)

  • 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: Touch file, change content, preserve mtime with touch -d; assert doctor detects staleness
  • 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: scripts/dev-setup.sh lines 121-136

PRA-3 Resolve/justify — Source-of-truth review needed: check_docker docker info parsing (scripts/dev-setup.sh:216)

  • 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: Mock docker info with 2 CPU / 4 GiB; assert failure with VM-specific message or env var override
  • 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: scripts/dev-setup.sh lines 216-230

PRA-4 Resolve/justify — Source-of-truth review needed: check_git_configuration gpg.format passthrough (scripts/dev-setup.sh:150)

  • 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: Set gpg.format=invalid and run doctor; should warn or fail
  • 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: scripts/dev-setup.sh line 150: ${sign_format:-openpgp} without validation

PRA-5 Resolve/justify — Source-of-truth review needed: check_local_cli path grep (scripts/dev-setup.sh:250)

  • 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: Create shim with path string but different target; assert doctor detects or documents limitation
  • 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: scripts/dev-setup.sh lines 243-265

PRA-6 Required — Pre-release version suffixes silently accepted in extract_version

  • Location: scripts/dev-setup.sh:45
  • Category: correctness
  • Problem: The extract_version regex `s/^[^0-9]*([0-9]+([.][0-9]+){0,2}).*/\1/` drops pre-release suffixes (-rc, -beta, -alpha, -dev). Input 'v22.16.0-rc.1' becomes '22.16.0' and passes the minimum version check. Node.js 22.16.0 is a stable release requirement; pre-releases should not satisfy it.
  • Impact: A contributor using Node.js 22.16.0-rc.1 (or any pre-release) would pass the minimum version check even though pre-releases are not supported. Minimum versions checked (Node 22.16.0, npm 10.0.0, Python 3.11.0) are stable releases, so practical risk is low but behavior is undocumented and inconsistent with semver.
  • Required action: Either reject pre-release versions explicitly in extract_version (e.g., fail if input matches -rc|-beta|-alpha|-dev), or document that pre-releases are unsupported and the check treats them as their base version. Add test case for 'v22.16.0-rc.1'.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Run: echo 'v22.16.0-rc.1' | sed -E 's/^[^0-9]*([0-9]+([.][0-9]+){0,2}).*/\1/' — returns '22.16.0'. Mock node --version to return 'v22.16.0-rc.1' and run doctor; it passes incorrectly.
  • Missing regression test: Add test case in test/dev-setup-doctor.test.ts: mock node to return 'v22.16.0-rc.1' and assert doctor fails or warns about pre-release version.
  • Done when: The required change is committed and verification passes: Run: echo 'v22.16.0-rc.1' | sed -E 's/^[^0-9]*([0-9]+([.][0-9]+){0,2}).*/\1/' — returns '22.16.0'. Mock node --version to return 'v22.16.0-rc.1' and run doctor; it passes incorrectly.
  • Evidence: scripts/dev-setup.sh lines 45-70: extract_version function and version_at_least comparison

PRA-7 Required — Source-of-truth: pre-release version handling is a localized workaround

  • Location: scripts/dev-setup.sh:45
  • Category: architecture
  • Problem: Pre-release version handling is a localized workaround. Invalid state: pre-release versions (v22.16.0-rc.1) pass as stable. Source boundary: version extraction regex. Source-fix constraint: Node.js --version output format is stable; could reject pre-releases at source. Regression test: mock pre-release version. Removal condition: when version extraction is replaced by a proper semver parser.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear. The script silently accepts pre-releases as stable versions.
  • Required action: Fix the invalid state at source by rejecting pre-releases in extract_version, or explicitly document the limitation with a regression test proving pre-releases are handled intentionally.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Inspect extract_version function and test coverage for pre-release inputs.
  • Missing regression test: Add test case mocking node --version = 'v22.16.0-rc.1' and assert failure or explicit warning.
  • Done when: The required change is committed and verification passes: Inspect extract_version function and test coverage for pre-release inputs.
  • Evidence: scripts/dev-setup.sh lines 45-70

PRA-8 Required — Test asserts specific gpg.format but script accepts any format

  • Location: test/dev-setup-doctor.test.ts:64
  • Category: tests
  • Problem: Test expects 'Git commit signing configured (ssh)' but script passes any gpg.format value (openpgp, ssh, x509, or arbitrary string) without validation.
  • Impact: Test is brittle and asserts behavior the script doesn't guarantee. Invalid gpg.format values would pass the doctor silently.
  • Required action: Either validate gpg.format against allowed values (openpgp, ssh, x509) in the script, or update the test to not assert a specific format in the output (just assert 'Git commit signing configured').
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Set git config gpg.format=invalid and run doctor; it passes with '(invalid)' in output.
  • Missing regression test: Add test case with invalid gpg.format and assert warning or failure, or update existing test to accept any format.
  • Done when: The required change is committed and verification passes: Set git config gpg.format=invalid and run doctor; it passes with '(invalid)' in output.
  • Evidence: test/dev-setup-doctor.test.ts line 64 expects '(ssh)'; scripts/dev-setup.sh line 150 uses ${sign_format:-openpgp} without validation

PRA-9 Resolve/justify — mtime-based staleness detection misses content changes with preserved timestamps

  • Location: scripts/dev-setup.sh:121
  • Category: correctness
  • Problem: check_build_artifact uses find -newer and file -nt which compare mtime. If a source file's content changes but mtime is preserved (e.g., git checkout, some editors, build systems), the artifact is incorrectly considered fresh.
  • Impact: Contributors may run with stale build artifacts without warning, leading to confusing test failures or runtime behavior mismatches.
  • Recommended action: Document the mtime limitation in a comment above check_build_artifact. Consider adding a content-hash fallback (e.g., sha256sum of source tree vs stored hash) for critical artifacts if this becomes a real issue in practice.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Touch a source file to update mtime, change its content, then restore original mtime with touch -d. Run doctor; it reports artifact as fresh.
  • Missing regression test: Add test case: create source file, build artifact, modify source content while preserving mtime, assert doctor detects staleness.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Touch a source file to update mtime, change its content, then restore original mtime with touch -d. Run doctor; it reports artifact as fresh.
  • Evidence: scripts/dev-setup.sh lines 121-136: check_build_artifact function

PRA-10 Resolve/justify — Source-of-truth: mtime-based staleness detection is a localized workaround

  • Location: scripts/dev-setup.sh:121
  • Category: architecture
  • Problem: Invalid state: content changes with preserved timestamps not detected. Source boundary: filesystem timestamps. Source-fix constraint: timestamp resolution limit; content hash would be heavier. Regression test: touch file, change content, preserve mtime. Removal condition: content-hash fallback for critical artifacts.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Document the limitation explicitly. Add content-hash fallback for critical artifacts if needed.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect check_build_artifact and test coverage for mtime-preserved content changes.
  • Missing regression test: Add test case demonstrating mtime-preserved content change detection gap.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect check_build_artifact and test coverage for mtime-preserved content changes.
  • Evidence: scripts/dev-setup.sh lines 121-136

PRA-11 Resolve/justify — Docker resource check uses VM resources, not host resources on macOS/Windows

  • Location: scripts/dev-setup.sh:216
  • Category: correctness
  • Problem: docker info reports container-runtime (VM) resources, not host resources. On Docker Desktop (macOS/Windows), MemTotal and NCPU reflect the VM allocation, not the physical host.
  • Impact: Contributors on macOS/Windows with adequate host resources but constrained Docker VMs will see false failures. Conversely, contributors with large VM allocations on small hosts may see false passes.
  • Recommended action: Document in the remediation message that this checks Docker VM/container-runtime resources, not host resources. Consider adding an env var override (e.g., NEMOCLAW_DEV_DOCTOR_MIN_MEMORY_GIB) for CI environments with constrained Docker VMs.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: On macOS with Docker Desktop set to 4 GiB, run doctor on a 16 GiB host; it fails with 'below minimum 8 GiB' despite host having 16 GiB.
  • Missing regression test: Add test case with NEMOCLAW_DEV_DOCTOR_MIN_MEMORY_GIB override and mocked docker info showing constrained VM.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: On macOS with Docker Desktop set to 4 GiB, run doctor on a 16 GiB host; it fails with 'below minimum 8 GiB' despite host having 16 GiB.
  • Evidence: scripts/dev-setup.sh lines 216-230: check_docker function

PRA-12 Resolve/justify — Source-of-truth: Docker VM resource reporting is a localized workaround

  • Location: scripts/dev-setup.sh:216
  • Category: architecture
  • Problem: Invalid state: VM resources reported as host. Source boundary: docker info API. Source-fix constraint: Docker Desktop virtualizes; host API not portable. Regression test: mock constrained VM. Removal condition: env var override or host API.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Document that check uses container-runtime (VM) resources. Add env var override for CI.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect check_docker and test coverage for VM vs host resource distinction.
  • Missing regression test: Add test case with mocked docker info showing 2 CPU / 4 GiB and assert failure with VM-specific message.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect check_docker and test coverage for VM vs host resource distinction.
  • Evidence: scripts/dev-setup.sh lines 216-230

PRA-13 Resolve/justify — GitHub authentication doesn't cross-check authenticated user vs git identity

  • Location: scripts/dev-setup.sh:185
  • Category: security
  • Problem: gh auth status only verifies that some token is valid. It does not verify that the authenticated GitHub user matches the git user.email or user.name configured in the repository.
  • Impact: A contributor could have gh authenticated as user A but git config set to user B. Commits would be attributed to user B but PRs pushed as user A, causing confusion in DCO verification and commit signing.
  • Recommended action: Add a cross-check: after 'gh auth status' succeeds, run 'gh api user --jq .login' and compare with git config user.email domain or warn if they appear unrelated. Or document as known limitation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Configure gh auth as user A, git user.email as user B@example.com. Run doctor; it passes without warning.
  • Missing regression test: Add test case with mismatched gh user and git email, assert warning.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Configure gh auth as user A, git user.email as user B@example.com. Run doctor; it passes without warning.
  • Evidence: scripts/dev-setup.sh lines 185-190: check_github_authentication function

PRA-14 Resolve/justify — docker command resolved via PATH without validation

  • Location: scripts/dev-setup.sh:192
  • Category: security
  • Problem: command -v docker trusts the first docker in PATH. A malicious or misconfigured PATH could resolve to a wrapper that exfiltrates credentials or returns falsified docker info output.
  • Impact: In compromised environments, doctor could report false Docker resource info or leak credentials via docker command stderr.
  • Recommended action: Consider using the full path to docker (e.g., /usr/bin/docker) or validate the docker binary is the expected one (check version output format). Document that the script trusts the PATH-resolved docker.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create a fake docker in PATH that echoes fake resources; doctor reports fake resources.
  • Missing regression test: Add test case with fake docker in PATH returning false resources, assert doctor detects or documents trust assumption.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create a fake docker in PATH that echoes fake resources; doctor reports fake resources.
  • Evidence: scripts/dev-setup.sh line 192: command -v docker

PRA-15 Resolve/justify — Python environment test doesn't verify executable bit check

  • Location: test/dev-setup-doctor.test.ts:85
  • Category: correctness
  • Problem: Test only removes .venv directory to test missing Python. It does not test the case where .venv/bin/python exists but lacks execute permissions.
  • Impact: If a contributor's Python binary loses execute bit (e.g., filesystem issue, bad checkout), doctor would report 'missing or not executable' but the test doesn't cover this path.
  • Recommended action: Update test to verify the executable check: create .venv/bin/python without execute bit and assert failure, or document that the test only covers missing directory.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: chmod -x .venv/bin/python and run doctor; it fails with 'missing or not executable'.
  • Missing regression test: Add test case: create .venv/bin/python without execute bit, assert doctor fails with executable error.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: chmod -x .venv/bin/python and run doctor; it fails with 'missing or not executable'.
  • Evidence: test/dev-setup-doctor.test.ts lines 110-117: only tests missing directory

PRA-16 Resolve/justify — Local CLI check verifies path but not execution

  • Location: scripts/dev-setup.sh:243
  • Category: correctness
  • Problem: check_local_cli verifies that nemoclaw on PATH resolves to this checkout via path string matching. It does not actually invoke the CLI to verify it executes correctly.
  • Impact: A broken symlink, corrupted bin/nemoclaw.js, or version mismatch would pass the path check but fail at runtime.
  • Recommended action: Add a lightweight invocation test after path verification: 'nemoclaw --version 2>/dev/null || fail "Local NemoClaw CLI is not functional" "Run: npm install"'.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create a broken nemoclaw symlink pointing to this checkout but with invalid content; doctor passes path check.
  • Missing regression test: Add test case with broken CLI executable that passes path check but fails --version invocation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create a broken nemoclaw symlink pointing to this checkout but with invalid content; doctor passes path check.
  • Evidence: scripts/dev-setup.sh lines 243-265: check_local_cli function

PRA-17 Resolve/justify — docker version format not validated before docker info call

  • Location: scripts/dev-setup.sh:192
  • Category: correctness
  • Problem: Script calls docker info without first verifying docker --version output matches expected format. A fake docker binary could pass command -v but fail docker info or return malicious output.
  • Impact: Reduces confidence that docker info output is from genuine Docker CLI.
  • Recommended action: Add a version format check after 'docker --version' to verify it's the real Docker CLI before calling 'docker info'.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create fake docker that returns 'Docker version 999.999.999' but docker info returns fake resources; doctor accepts it.
  • Missing regression test: Add test case with fake docker version format, assert validation or documented trust.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create fake docker that returns 'Docker version 999.999.999' but docker info returns fake resources; doctor accepts it.
  • Evidence: scripts/dev-setup.sh lines 192-214: check_docker function

PRA-18 Resolve/justify — Custom bash semver comparison could use comment explaining portability rationale

  • Location: scripts/dev-setup.sh:50
  • Category: scope
  • Problem: version_at_least implements semver comparison in pure bash. No comment explains why not using Node/Python/uv for this.
  • Impact: Future maintainers may incorrectly assume this is a bug or attempt to replace with external dependency.
  • Recommended action: Add a comment explaining why pure bash is used (portability, works even if Node is broken). This is already a reasonable design decision; just needs documentation.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect version_at_least function for explanatory comment.
  • Missing regression test: N/A — documentation improvement
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect version_at_least function for explanatory comment.
  • Evidence: scripts/dev-setup.sh lines 50-70: version_at_least function

PRA-19 Resolve/justify — AGENTS.md quick reference doesn't explicitly state doctor is read-only

  • Location: AGENTS.md:14
  • Category: docs
  • Problem: CONTRIBUTING.md documents that the doctor is read-only, but AGENTS.md quick reference table only shows the command without the read-only guarantee.
  • Impact: Contributors reading AGENTS.md may not know the doctor is safe to run repeatedly without side effects.
  • Recommended action: Add a one-line note in AGENTS.md quick reference: 'The doctor is read-only — it never installs packages, changes configuration, or starts services.'
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read AGENTS.md quick reference table; no read-only mention for dev:doctor.
  • Missing regression test: N/A — documentation improvement
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read AGENTS.md quick reference table; no read-only mention for dev:doctor.
  • Evidence: AGENTS.md line 14: quick reference table entry for dev:doctor

PRA-20 Resolve/justify — CLI path grep check could false-pass on shim containing path string

  • Location: scripts/dev-setup.sh:230
  • Category: scope
  • Problem: grep -Fq "${REPO_ROOT}/bin/nemoclaw.js" "${cli_path}" checks if the repo path appears anywhere in the CLI file content. A shim script containing that path string (e.g., as a comment or variable) would false-pass.
  • Impact: A wrapper/shim that references the real CLI path but executes something else would pass the check.
  • Recommended action: Strengthen the check: verify the CLI file is the actual launcher (e.g., check shebang, or that it's a symlink to the real file), not just a text match.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Create a shim script containing the repo path string but executing different code; doctor passes.
  • Missing regression test: Add test case with shim containing path string but different target, assert doctor detects or documents limitation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Create a shim script containing the repo path string but executing different code; doctor passes.
  • Evidence: scripts/dev-setup.sh line 250: grep -Fq check

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 Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-2: Validate gpg.format before reporting contributor readiness; then add or justify PRA-T1.
Open items: 1 required · 2 warnings · 0 suggestions · 8 test follow-ups
Since last review: 0 prior items resolved · 2 still apply · 0 new items found

Action checklist

  • PRA-2 Fix: Validate gpg.format before reporting contributor readiness in scripts/dev-setup.sh:179
  • PRA-1 Resolve or justify: Source-of-truth review needed: Git signing readiness in scripts/dev-setup.sh
  • PRA-3 Resolve or justify: Define or enforce supported versions for uv, Git, GitHub CLI, and hadolint in scripts/dev-setup.sh:286
  • 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: Acceptance clause
  • PRA-T7 Add or justify test follow-up: Acceptance clause
  • PRA-T8 Add or justify test follow-up: Acceptance clause

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 Required acceptance scripts/dev-setup.sh:179 Require gpg.format to be unset/default or one of the supported Git signing formats used by this project, such as openpgp, ssh, or x509. For any other value, fail with a precise remediation that tells the contributor to set a supported signing format or unset the invalid value.
PRA-3 Resolve/justify acceptance scripts/dev-setup.sh:286 Either add explicit minimum-version checks for uv, Git, GitHub CLI, and hadolint, or narrow the documented/issue-facing contract to presence checks when this repository does not require a supported minimum for those tools.

🚨 Required before merge

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

PRA-2 Required — Validate gpg.format before reporting contributor readiness

  • Location: scripts/dev-setup.sh:179
  • Category: acceptance
  • Problem: The linked issue requires the doctor to verify repository Git signing format, but check_git_configuration only reads gpg.format for display. A checkout with commit.gpgsign=true, a nonempty user.signingkey, and gpg.format=bogus still passes the signing check and can reach the ready state.
  • Impact: Contributors can be told their environment is ready even though commit signing is misconfigured. That weakens the contributor PR-readiness and verified-commit workflow boundary this doctor is intended to enforce.
  • Required action: Require gpg.format to be unset/default or one of the supported Git signing formats used by this project, such as openpgp, ssh, or x509. For any other value, fail with a precise remediation that tells the contributor to set a supported signing format or unset the invalid value.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read scripts/dev-setup.sh in check_git_configuration: sign_format is assigned, then the pass condition checks only sign_enabled and signing_key before printing Git commit signing configured.
  • Missing regression test: Add test/dev-setup-doctor.test.ts coverage named like "rejects an unsupported Git signing format before reporting contributor readiness": stub git config --get gpg.format to bogus, expect exit status 1, assert a supported-format or unset-format remediation, and assert "Ready to create a feature branch." is absent.
  • Done when: The required change is committed and verification passes: Read scripts/dev-setup.sh in check_git_configuration: sign_format is assigned, then the pass condition checks only sign_enabled and signing_key before printing Git commit signing configured.
  • Evidence: sign_format="$(git_config gpg.format)" is followed by if [ "${sign_enabled}" = "true" ] && [ -n "${signing_key}" ]; then pass "Git commit signing configured (${sign_format:-openpgp})" with no allowed-value validation.
Review findings by urgency: 1 required fix, 2 items to resolve/justify, 0 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: Git signing readiness in scripts/dev-setup.sh

  • 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 a doctor integration test that stubs git config --get gpg.format to bogus, expects exit status 1, verifies supported-format or unset-format remediation, and verifies readiness is not printed.
  • 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: scripts/dev-setup.sh reads sign_format but the pass condition checks only commit.gpgsign and user.signingkey.

PRA-3 Resolve/justify — Define or enforce supported versions for uv, Git, GitHub CLI, and hadolint

  • Location: scripts/dev-setup.sh:286
  • Category: acceptance
  • Problem: The linked issue design says to verify supported versions of Node.js, npm, Python, uv, Git, GitHub CLI, and hadolint. This implementation enforces minimum versions for Node.js, npm, and the repository Python environment, but uv, Git, GitHub CLI, and hadolint are checked only for presence and successful --version output.
  • Impact: A contributor can pass the doctor with a too-old uv, Git, GitHub CLI, or hadolint if those tools are present, which weakens the command's promise to catch unsupported contributor toolchains up front.
  • Recommended action: Either add explicit minimum-version checks for uv, Git, GitHub CLI, and hadolint, or narrow the documented/issue-facing contract to presence checks when this repository does not require a supported minimum for those tools.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read the bottom of scripts/dev-setup.sh: Node.js, npm, and .venv/bin/python call check_minimum_version, while uv, Git, GitHub CLI, and hadolint call check_command.
  • Missing regression test: If minimums are required, add behavior tests such as "rejects unsupported uv versions with remediation", "rejects unsupported Git versions with remediation", "rejects unsupported GitHub CLI versions with remediation", and "rejects unsupported hadolint versions with remediation"; if presence-only is intended, add documentation/test evidence that no minimum is required.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read the bottom of scripts/dev-setup.sh: Node.js, npm, and .venv/bin/python call check_minimum_version, while uv, Git, GitHub CLI, and hadolint call check_command.
  • Evidence: check_command "uv" uv, check_command "Git" git, check_command "GitHub CLI" gh, and check_command "hadolint" hadolint only verify command existence plus --version success.

💡 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.

  • None.
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 — rejects an unsupported Git signing format before reporting contributor readiness. The PR changes onboarding/host shell behavior and appropriately adds Bash-spawning integration tests with controlled command stubs. Remaining confidence gaps are concrete negative paths for unsupported Git signing format, the implemented hooksPath override branch, and supported minimums if uv/Git/GitHub CLI/hadolint are intended to be version-gated.
  • PRA-T2 Runtime validation — rejects a repository core.hooksPath override before reporting hooks installed. The PR changes onboarding/host shell behavior and appropriately adds Bash-spawning integration tests with controlled command stubs. Remaining confidence gaps are concrete negative paths for unsupported Git signing format, the implemented hooksPath override branch, and supported minimums if uv/Git/GitHub CLI/hadolint are intended to be version-gated.
  • PRA-T3 Runtime validation — rejects unsupported uv versions with remediation if uv has a supported minimum. The PR changes onboarding/host shell behavior and appropriately adds Bash-spawning integration tests with controlled command stubs. Remaining confidence gaps are concrete negative paths for unsupported Git signing format, the implemented hooksPath override branch, and supported minimums if uv/Git/GitHub CLI/hadolint are intended to be version-gated.
  • PRA-T4 Runtime validation — rejects unsupported Git versions with remediation if Git has a supported minimum. The PR changes onboarding/host shell behavior and appropriately adds Bash-spawning integration tests with controlled command stubs. Remaining confidence gaps are concrete negative paths for unsupported Git signing format, the implemented hooksPath override branch, and supported minimums if uv/Git/GitHub CLI/hadolint are intended to be version-gated.
  • PRA-T5 Runtime validation — rejects unsupported GitHub CLI versions with remediation if gh has a supported minimum. The PR changes onboarding/host shell behavior and appropriately adds Bash-spawning integration tests with controlled command stubs. Remaining confidence gaps are concrete negative paths for unsupported Git signing format, the implemented hooksPath override branch, and supported minimums if uv/Git/GitHub CLI/hadolint are intended to be version-gated.
  • PRA-T6 Acceptance clause — 2. Verify supported versions of Node.js, npm, Python, uv, Git, GitHub CLI, and hadolint. — add test evidence or identify existing coverage. Node.js, npm, and the repository Python environment use check_minimum_version; uv, Git, GitHub CLI, and hadolint use check_command and are not checked against supported minimums.
  • PRA-T7 Acceptance clause — 6. Verify repository Git name, email, signing format, signing key, and `commit.gpgsign=true` without changing configuration. — add test evidence or identify existing coverage. The script reads user.name, user.email, commit.gpgsign, gpg.format, and user.signingkey via git config --get, but it does not reject unsupported gpg.format values.
  • PRA-T8 Acceptance clause — The doctor covers the required toolchain, dependencies, builds, hooks, Git identity/signing, GitHub authentication, Docker, and local CLI resolution. — add test evidence or identify existing coverage. The surfaces are covered, but signing format validation and supported minimum versions for uv/Git/GitHub CLI/hadolint remain incomplete.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: Git signing readiness in scripts/dev-setup.sh

  • 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 a doctor integration test that stubs git config --get gpg.format to bogus, expects exit status 1, verifies supported-format or unset-format remediation, and verifies readiness is not printed.
  • 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: scripts/dev-setup.sh reads sign_format but the pass condition checks only commit.gpgsign and user.signingkey.

PRA-2 Required — Validate gpg.format before reporting contributor readiness

  • Location: scripts/dev-setup.sh:179
  • Category: acceptance
  • Problem: The linked issue requires the doctor to verify repository Git signing format, but check_git_configuration only reads gpg.format for display. A checkout with commit.gpgsign=true, a nonempty user.signingkey, and gpg.format=bogus still passes the signing check and can reach the ready state.
  • Impact: Contributors can be told their environment is ready even though commit signing is misconfigured. That weakens the contributor PR-readiness and verified-commit workflow boundary this doctor is intended to enforce.
  • Required action: Require gpg.format to be unset/default or one of the supported Git signing formats used by this project, such as openpgp, ssh, or x509. For any other value, fail with a precise remediation that tells the contributor to set a supported signing format or unset the invalid value.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read scripts/dev-setup.sh in check_git_configuration: sign_format is assigned, then the pass condition checks only sign_enabled and signing_key before printing Git commit signing configured.
  • Missing regression test: Add test/dev-setup-doctor.test.ts coverage named like "rejects an unsupported Git signing format before reporting contributor readiness": stub git config --get gpg.format to bogus, expect exit status 1, assert a supported-format or unset-format remediation, and assert "Ready to create a feature branch." is absent.
  • Done when: The required change is committed and verification passes: Read scripts/dev-setup.sh in check_git_configuration: sign_format is assigned, then the pass condition checks only sign_enabled and signing_key before printing Git commit signing configured.
  • Evidence: sign_format="$(git_config gpg.format)" is followed by if [ "${sign_enabled}" = "true" ] && [ -n "${signing_key}" ]; then pass "Git commit signing configured (${sign_format:-openpgp})" with no allowed-value validation.

PRA-3 Resolve/justify — Define or enforce supported versions for uv, Git, GitHub CLI, and hadolint

  • Location: scripts/dev-setup.sh:286
  • Category: acceptance
  • Problem: The linked issue design says to verify supported versions of Node.js, npm, Python, uv, Git, GitHub CLI, and hadolint. This implementation enforces minimum versions for Node.js, npm, and the repository Python environment, but uv, Git, GitHub CLI, and hadolint are checked only for presence and successful --version output.
  • Impact: A contributor can pass the doctor with a too-old uv, Git, GitHub CLI, or hadolint if those tools are present, which weakens the command's promise to catch unsupported contributor toolchains up front.
  • Recommended action: Either add explicit minimum-version checks for uv, Git, GitHub CLI, and hadolint, or narrow the documented/issue-facing contract to presence checks when this repository does not require a supported minimum for those tools.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read the bottom of scripts/dev-setup.sh: Node.js, npm, and .venv/bin/python call check_minimum_version, while uv, Git, GitHub CLI, and hadolint call check_command.
  • Missing regression test: If minimums are required, add behavior tests such as "rejects unsupported uv versions with remediation", "rejects unsupported Git versions with remediation", "rejects unsupported GitHub CLI versions with remediation", and "rejects unsupported hadolint versions with remediation"; if presence-only is intended, add documentation/test evidence that no minimum is required.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read the bottom of scripts/dev-setup.sh: Node.js, npm, and .venv/bin/python call check_minimum_version, while uv, Git, GitHub CLI, and hadolint call check_command.
  • Evidence: check_command "uv" uv, check_command "Git" git, check_command "GitHub CLI" gh, and check_command "hadolint" hadolint only verify command existence plus --version success.

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.

@apurvvkumaria
apurvvkumaria marked this pull request as ready for review July 1, 2026 07:54

@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 (1)
test/dev-setup-doctor.test.ts (1)

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

Consider hashing file contents for the non-mutation check.

readdirSync(..., { recursive: true }) only compares directory entries, so a content-only mutation to an existing file (without adding/removing entries) wouldn't be caught. Since "never mutates the checkout" is the doctor's core contract, comparing content hashes (or mtimes) would give stronger assurance.
[optional_refactor]

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

In `@test/dev-setup-doctor.test.ts` around lines 180 - 193, Strengthen the
non-mutation assertion in dev-setup-doctor.test by checking file contents, not
just directory entries. In the "reports a ready environment without mutating the
fixture" test, keep the existing runDoctor and readdirSync coverage but add a
content-based snapshot of the fixture before and after (for example via hashing
or file mtimes) using the fixture.repo path so changes to existing files are
detected. Ensure the assertion still targets the fixture created by
createFixture and verifies the checkout remains unchanged after runDoctor.
🤖 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 `@scripts/dev-setup.sh`:
- Line 281: The version verification for uv, Git, GitHub CLI, and hadolint
currently only checks that the commands exist, not that they meet supported
minimum versions. Update the setup checks around check_command in the dev-setup
script to use the same minimum-version validation flow as Node.js, npm, and
Python by comparing the installed versions for uv, git, gh, and hadolint against
the required baselines. Keep the existing tool identifiers (uv, git, gh,
hadolint) so the checks remain easy to locate and maintain.

---

Nitpick comments:
In `@test/dev-setup-doctor.test.ts`:
- Around line 180-193: Strengthen the non-mutation assertion in
dev-setup-doctor.test by checking file contents, not just directory entries. In
the "reports a ready environment without mutating the fixture" test, keep the
existing runDoctor and readdirSync coverage but add a content-based snapshot of
the fixture before and after (for example via hashing or file mtimes) using the
fixture.repo path so changes to existing files are detected. Ensure the
assertion still targets the fixture created by createFixture and verifies the
checkout remains unchanged after runDoctor.
🪄 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: 6efbae36-07f1-4200-9638-d50ef48e6f68

📥 Commits

Reviewing files that changed from the base of the PR and between acacf93 and c53c858.

📒 Files selected for processing (5)
  • AGENTS.md
  • CONTRIBUTING.md
  • package.json
  • scripts/dev-setup.sh
  • test/dev-setup-doctor.test.ts

Comment thread scripts/dev-setup.sh
@apurvvkumaria

Copy link
Copy Markdown
Collaborator Author

Advisor follow-up for head c53c858d0

The standard PR Review Advisor items are resolved with evidence or explicitly deferred as follows:

  • PRA-1 / PRA-2 / PRA-T1 / PRA-T2 / PRA-T4 / PRA-T5 / PRA-T7 — Git signing readiness: deferred to child issue fix(contributor): validate Git signing format in developer doctor #6119. That issue scopes validation of unset, openpgp, ssh, and x509 formats; rejection and precise remediation for unsupported values; and the requested negative-path regression test proving readiness is not printed for gpg.format=bogus. This PR retains its current signing-readiness behavior. The PR already has maintainer approval, and the maintainer retains the final merge decision.
  • PRA-T3 — Shell and language requirements: scripts/dev-setup.sh passed the repository-managed shfmt and ShellCheck hooks. The new test/support code is TypeScript. GitHub's ShellCheck and static checks also pass on the current head.
  • PRA-T6 — Verification evidence: the focused contributor-doctor integration suite passes all 11 tests. npm run typecheck:cli, npm run checks, npm run test:titles:check, npm run test-size:check, the applicable prek hooks, and npm run docs completed successfully. On GitHub, all five CLI shards, the CLI aggregate, build/typecheck, installer integration, macOS and WSL E2E, CodeQL, DCO, commit lint, and the aggregate required checks pass.

The separate CodeRabbit request to enforce minimum versions for uv, Git, GitHub CLI, and hadolint was reviewed in its inline thread. The contributor documentation defines no authoritative minimums for those tools; the response explains why inventing an undocumented support matrix is out of scope for this PR.

@apurvvkumaria
apurvvkumaria merged commit 4543f05 into main Jul 1, 2026
44 checks passed
@apurvvkumaria
apurvvkumaria deleted the feat/contributor-dev-doctor branch July 1, 2026 20:28
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow feature PR adds or expands user-visible functionality labels Jul 1, 2026
apurvvkumaria added a commit that referenced this pull request Jul 3, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Adds a single, idempotent contributor setup command and a matching
coding-agent skill so a new NemoClaw engineer can prepare a source
checkout and understand first-PR requirements from one supported
workflow.
Keeps setup and repair repository-local, with host-visible CLI exposure
and runtime sandbox onboarding available only through explicit opt-in
modes.

## Related Issue
Fixes #6103
Related to #3827
Builds on #6109

## Changes
- Extend `scripts/dev-setup.sh` with default setup, `--repair`,
machine-readable `--doctor --json`, explicit `--expose-cli`, and opt-in
`--with-runtime` modes.
- Keep setup inside the trusted checkout: reject mutating root
overrides, include development dependencies, reuse a local Python 3.11+
interpreter without downloads, and stop on non-local Git hook overrides.
- Keep the doctor read-only by invoking only installed TypeScript
binaries, and verify the PATH-resolved CLI itself before accepting a
link or managed shim.
- Add stable `npm run dev:setup` and repository-pinned `npm run agent`
aliases.
- Add the `nemoclaw-contributor-onboard` skill with intent-specific
routing and whole-checkout trust review, then route contributors to it
from the skill catalog and `AGENTS.md`.
- Update `CONTRIBUTING.md` and `README.md` with the one-command and
one-prompt paths, explicit CLI/runtime boundaries, and first-PR
signing/DCO requirements.
- Expand integration coverage for setup, repair, idempotency, missing
dependencies, JSON readiness, authentication redaction, trust
boundaries, CLI validation, and runtime delegation.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] 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
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — setup mutation, executable resolution, Python download, Git
hook scope, CLI exposure, and trusted-checkout boundaries reviewed with
focused regression coverage
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
no CI waiver requested; post-push CI is pending

## 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
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes — all applicable
static/format/security hooks and normal pre-push hooks passed; the broad
local `test-cli` hook was skipped after its current-main
Linux/permission-sensitive tests failed on macOS, so Linux CI remains
authoritative
- [x] Targeted tests pass for changed behavior
- [ ] 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) —
validation completed with 0 errors and 2 existing Fern warnings
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only) — no Fern source page changed
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new doc page added

Verification evidence:

- `npx vitest run --project integration test/dev-setup-doctor.test.ts` —
38 tests passed.
- `npx vitest run --project integration test/skills-frontmatter.test.ts`
— 24 tests passed.
- `npx vitest run --project cli
src/lib/actions/sandbox/rebuild-gateway-drift.test.ts` — 4 tests passed
on the merged head with a writable test HOME.
- `npm run typecheck:cli`, `npm run test-size:check`, ShellCheck, shfmt,
Biome, repository checks, markdownlint, secret scanning, skill
validation, source-shape budget, and commitlint passed.
- Normal pre-push TypeScript and package-version hooks passed.
- `npm run docs` completed with 0 errors and 2 Fern warnings; the
documentation-writer review found no Fern source change necessary
because this workflow is contributor-facing.
- The two new commits are signed and GitHub reports both as `Verified`;
DCO CI passes.

---
<!-- 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: Apurv Kumaria <akumaria@nvidia.com>


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

* **New Features**
* Added a contributor onboarding agent skill and updated first-PR
readiness workflow.
* Introduced `dev:setup`, `dev:doctor` enhancements (including `--doctor
--json`), and an `agent` command.
* Added `--with-runtime` mode for cases requiring sandbox/runtime
validation.
* **Bug Fixes**
* Improved setup/repair and readiness reporting with safer prerequisite
checks, clearer ordered remediations, and reliable stop-on-failure
behavior.
* **Documentation**
* Updated README, AGENTS.md, and CONTRIBUTING.md to standardize
script-driven setup and doctor-guided fixes.
* **Tests**
* Expanded tests for setup/repair sequencing, JSON output correctness,
and runtime-onboarding triggering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…#6109)

<!-- markdownlint-disable MD041 -->
## Summary

Adds a read-only contributor environment doctor so NemoClaw developers
can identify source-checkout, toolchain, Git, GitHub, and Docker
readiness issues before starting work or opening a pull request. This is
the first independently useful contributor-onboarding slice from NVIDIA#6103
and complements the existing end-user installer and coding-agent starter
prompt.

## Related Issue

Closes NVIDIA#6105.

## Changes

- Add `./scripts/dev-setup.sh --doctor` and expose it as `npm run
dev:doctor`.
- Check supported tools, repository dependencies, fresh build artifacts,
prek hooks, contributor identity and signing, GitHub authentication,
Docker availability/resources, and local CLI linkage without changing
the host.
- Align Docker results with the published 4-vCPU/8-GiB minimum and
16-GiB memory recommendation.
- Add controlled integration fixtures for ready, missing, stale,
invalid, authentication, redaction, runtime, and exit-code behavior.
- Document the contributor readiness workflow and correct `uv sync` to
run from the repository root.

## Type of Change

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

## Quality Gates

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

## Verification

- [x] 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
- [x] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [ ] 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)

Verification evidence:

- `npx vitest run --project integration test/dev-setup-doctor.test.ts` —
11 tests passed.
- `npm run typecheck:cli`, `npm run checks`, `npm run
test:titles:check`, and `npm run test-size:check` passed.
- shfmt, ShellCheck, Biome, markdownlint, repository checks, commitlint,
secret scanning, and the normal pre-push hooks passed.
- `npm run docs` completed with 0 errors and 2 existing Fern warnings.
- The final commit skipped the full `test-cli` pre-commit hook after its
supported-toolchain run exposed five unrelated macOS integration
failures in Deep Agents TUI, gateway-supervisor Python startup, and
sandbox auto-pair approval tests. The new doctor integration suite
passes independently; CI confirmation and any required maintainer
acceptance remain pending while this PR is a draft.

---
<!-- 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: Apurv Kumaria <akumaria@nvidia.com>


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

## Summary by CodeRabbit

* **New Features**
* Added a new `dev:doctor` check to validate contributor environment
readiness.
* Expanded setup guidance with a clear read-only environment
verification workflow.

* **Bug Fixes**
  * Updated install instructions to remove an extra directory change.
* Clarified setup steps for handling environment check failures and
reruns.

* **Documentation**
* Revised contributor and setup docs to point to the new environment
check and updated pre-change workflow.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Adds a single, idempotent contributor setup command and a matching
coding-agent skill so a new NemoClaw engineer can prepare a source
checkout and understand first-PR requirements from one supported
workflow.
Keeps setup and repair repository-local, with host-visible CLI exposure
and runtime sandbox onboarding available only through explicit opt-in
modes.

## Related Issue
Fixes NVIDIA#6103
Related to NVIDIA#3827
Builds on NVIDIA#6109

## Changes
- Extend `scripts/dev-setup.sh` with default setup, `--repair`,
machine-readable `--doctor --json`, explicit `--expose-cli`, and opt-in
`--with-runtime` modes.
- Keep setup inside the trusted checkout: reject mutating root
overrides, include development dependencies, reuse a local Python 3.11+
interpreter without downloads, and stop on non-local Git hook overrides.
- Keep the doctor read-only by invoking only installed TypeScript
binaries, and verify the PATH-resolved CLI itself before accepting a
link or managed shim.
- Add stable `npm run dev:setup` and repository-pinned `npm run agent`
aliases.
- Add the `nemoclaw-contributor-onboard` skill with intent-specific
routing and whole-checkout trust review, then route contributors to it
from the skill catalog and `AGENTS.md`.
- Update `CONTRIBUTING.md` and `README.md` with the one-command and
one-prompt paths, explicit CLI/runtime boundaries, and first-PR
signing/DCO requirements.
- Expand integration coverage for setup, repair, idempotency, missing
dependencies, JSON readiness, authentication redaction, trust
boundaries, CLI validation, and runtime delegation.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] 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
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — setup mutation, executable resolution, Python download, Git
hook scope, CLI exposure, and trusted-checkout boundaries reviewed with
focused regression coverage
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
no CI waiver requested; post-push CI is pending

## 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
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes — all applicable
static/format/security hooks and normal pre-push hooks passed; the broad
local `test-cli` hook was skipped after its current-main
Linux/permission-sensitive tests failed on macOS, so Linux CI remains
authoritative
- [x] Targeted tests pass for changed behavior
- [ ] 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) —
validation completed with 0 errors and 2 existing Fern warnings
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only) — no Fern source page changed
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new doc page added

Verification evidence:

- `npx vitest run --project integration test/dev-setup-doctor.test.ts` —
38 tests passed.
- `npx vitest run --project integration test/skills-frontmatter.test.ts`
— 24 tests passed.
- `npx vitest run --project cli
src/lib/actions/sandbox/rebuild-gateway-drift.test.ts` — 4 tests passed
on the merged head with a writable test HOME.
- `npm run typecheck:cli`, `npm run test-size:check`, ShellCheck, shfmt,
Biome, repository checks, markdownlint, secret scanning, skill
validation, source-shape budget, and commitlint passed.
- Normal pre-push TypeScript and package-version hooks passed.
- `npm run docs` completed with 0 errors and 2 Fern warnings; the
documentation-writer review found no Fern source change necessary
because this workflow is contributor-facing.
- The two new commits are signed and GitHub reports both as `Verified`;
DCO CI passes.

---
<!-- 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: Apurv Kumaria <akumaria@nvidia.com>


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

* **New Features**
* Added a contributor onboarding agent skill and updated first-PR
readiness workflow.
* Introduced `dev:setup`, `dev:doctor` enhancements (including `--doctor
--json`), and an `agent` command.
* Added `--with-runtime` mode for cases requiring sandbox/runtime
validation.
* **Bug Fixes**
* Improved setup/repair and readiness reporting with safer prerequisite
checks, clearer ordered remediations, and reliable stop-on-failure
behavior.
* **Documentation**
* Updated README, AGENTS.md, and CONTRIBUTING.md to standardize
script-driven setup and doctor-guided fixes.
* **Tests**
* Expanded tests for setup/repair sequencing, JSON output correctness,
and runtime-onboarding triggering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
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: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(contributor): add read-only developer environment doctor

4 participants