Skip to content

test(e2e): bridge onboard negative paths to Vitest#5152

Merged
jyaunches merged 10 commits into
mainfrom
e2e-migrate/test-onboard-negative-paths
Jun 10, 2026
Merged

test(e2e): bridge onboard negative paths to Vitest#5152
jyaunches merged 10 commits into
mainfrom
e2e-migrate/test-onboard-negative-paths

Conversation

@jyaunches

@jyaunches jyaunches commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a focused, free-standing Vitest live test for the first contract from test/e2e/test-onboard-negative-paths.sh: invalid NVIDIA API key handling during non-interactive onboard.

This is intentionally not a registry-driven bridge and does not retire the legacy bash script. Per #5126 and #5098 migration guidance, this PR keeps the scope narrow and preserves the real CLI/onboard boundary from Vitest instead of expanding typed registry/state-validation machinery for one script migration.

Scope

Covered in this PR:

  • invalid NVIDIA key exits non-zero
  • invalid NVIDIA key message is explicit (Invalid NVIDIA API key + Must start with nvapi-)
  • invalid NVIDIA key no stack trace

Not covered / left for follow-up slices:

  • gateway port conflict behavior
  • custom policy/model live onboard behavior
  • full legacy bash script retirement
  • registry-driven scenario IDs such as ubuntu-invalid-nvidia-key-negative, ubuntu-gateway-port-conflict-negative, or ubuntu-repo-cloud-openclaw-custom-policies

Shape

  • Adds test/e2e-scenario/live/onboard-negative-paths.test.ts as a direct live Vitest test.
  • Adds onboard-negative-paths-vitest to .github/workflows/e2e-vitest-scenarios.yaml as a free-standing job.
  • Updates workflow-boundary validation so the new free-standing job stays manual, pinned, artifact-scoped, and independent of registry scenario fan-out.

Simplicity check

  • Test shape: focused direct Vitest over the real CLI/onboard boundary.
  • New shared helpers: none; helpers stay local to the test file.
  • New registry/state-validation/framework changes: none.
  • Legacy bash deletion: none.

Verification

  • npm run build:cli
  • npm run typecheck:cli
  • npx vitest run --project cli test/e2e-scenario/live/onboard-negative-paths.test.ts --silent=false --reporter=default
  • NEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project e2e-scenarios-live test/e2e-scenario/live/onboard-negative-paths.test.ts --silent=false --reporter=default
  • npx vitest run --project e2e-vitest-support test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts --silent=false --reporter=default

Refs #5098, #2573

Summary by CodeRabbit

Release Notes

  • Tests
    • Introduced comprehensive end-to-end test coverage for the onboard command's negative scenarios when provided with invalid API credentials, ensuring the system displays appropriate error messages while preventing exposure of internal implementation details through stack traces.
    • Strengthened CI/CD workflow validation mechanisms to enforce consistent test execution standards and infrastructure requirements across all automated testing scenarios and quality assurance processes.

@jyaunches jyaunches added the area: e2e End-to-end tests, nightly failures, or validation infrastructure label Jun 10, 2026
@copy-pr-bot

copy-pr-bot Bot commented Jun 10, 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 Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4c68f096-c8f3-4f62-a8f0-3b21f292d21f

📥 Commits

Reviewing files that changed from the base of the PR and between e025a80 and 82f4286.

📒 Files selected for processing (1)
  • .github/workflows/e2e-vitest-scenarios.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/e2e-vitest-scenarios.yaml

📝 Walkthrough

Walkthrough

This PR introduces an E2E test for the nemoclaw onboard command's negative-path handling with an invalid NVIDIA API key. It includes the test implementation, CI workflow job configuration, job structure validators, and test-level verification of the workflow shape.

Changes

Onboard negative-path E2E test and workflow validation

Layer / File(s) Summary
E2E negative-path test implementation
test/e2e-scenario/live/onboard-negative-paths.test.ts
Test setup defines invalid API key, stack-trace detection regexes, Docker availability checks, CLI entrypoint verification, and best-effort cleanup. Test execution runs nemoclaw onboard and asserts non-zero exit, explicit error messaging ("Invalid NVIDIA API key", "Must start with nvapi-"), and absence of detected JavaScript stack traces.
CI workflow job configuration
.github/workflows/e2e-vitest-scenarios.yaml
New onboard-negative-paths-vitest job runs on ubuntu-latest with 15-minute timeout, sets E2E_ARTIFACT_DIR and NEMOCLAW_RUN_E2E_SCENARIOS, performs checkout, Node 22 setup, root dependency install, CLI build, and direct vitest execution against the negative-path test, then uploads outputs to e2e-vitest-scenarios-onboard-negative-paths artifact with 14-day retention and ignored missing files.
Workflow boundary validator
tools/e2e-scenarios/workflow-boundary.mts
New validator function validateOnboardNegativePathsVitestJob enforces runs-on: ubuntu-latest, job independence from generate-matrix and scenario filters, required env values, secret non-exposure (no NVIDIA_API_KEY), pinned full-SHA action/checkout/setup-node steps with persist-credentials: false, specific install/build/test/upload command patterns, and artifact naming/path/options/retention constraints. Validator is invoked in the exported validateE2eVitestScenariosWorkflowBoundary entrypoint.
Workflow test validation and formatting
test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts, .github/workflows/e2e-vitest-scenarios.yaml
Test expands inline workflow YAML to include onboard-negative-paths-vitest job with matrix gating, env setup, test step, and artifact upload. Expected validation errors extended to verify job independence, env correctness, pinned steps, and artifact upload rules. Non-functional multi-line reformatting of existing openclaw-tui-chat-correlation-vitest job's vitest invocation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5150: Both PRs extend the same E2E Vitest workflow and boundary validation machinery—adding standalone e2e-vitest-scenarios.yaml jobs with corresponding job-specific validators in tools/e2e-scenarios/workflow-boundary.mts for different CLI commands (onboard vs. openclaw-tui-chat).

Suggested labels

area: onboarding, area: ci

Suggested reviewers

  • cv
  • prekshivyas

Poem

🐰 A test that watches when things go wrong,
With invalid keys and cleanup strong,
The workflow guards each step with care,
No stack traces hiding anywhere!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.30% 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 'test(e2e): bridge onboard negative paths to Vitest' clearly and specifically summarizes the main change: migrating an E2E test for invalid onboard scenarios from bash to Vitest.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch e2e-migrate/test-onboard-negative-paths

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

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: None
Optional E2E: onboard-negative-paths-vitest, onboard-negative-paths-e2e

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • None. No merge-blocking E2E is required because this PR only changes E2E workflow/test/support tooling and adds coverage; it does not change product runtime behavior or user-flow implementation. The optional jobs above are recommended only to validate the newly added E2E coverage itself.

Optional E2E

  • onboard-negative-paths-vitest (low-medium): Useful targeted validation for the newly added standalone Vitest E2E job and test. It directly exercises the changed onboarding invalid-key coverage and verifies the workflow can build the CLI, run the test, and upload artifacts.
  • onboard-negative-paths-e2e (medium): Optional broader comparison against the existing legacy onboarding negative-path E2E, since the new Vitest test intentionally covers only the invalid NVIDIA key contract from the legacy script.

New E2E recommendations

  • onboarding-negative-paths (medium): The new Vitest live test covers the invalid NVIDIA key contract, but the legacy onboard-negative-paths script still contains additional contracts for policy-mode fallback, non-NVIDIA provider keys, gateway port conflict handling, custom policy presets, and provider/model environment honoring.
    • Suggested test: Add Vitest live onboarding negative-path tests for the remaining test/e2e/test-onboard-negative-paths.sh contracts.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: e2e-scenarios-all
Optional Vitest E2E scenarios: None

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref>

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • e2e-scenarios-all: The PR changes the canonical Vitest scenario workflow and its workflow-boundary validation, and adds a live Vitest onboard negative-path job/test. Workflow changes require the full Vitest scenario fan-out to verify matrix dispatch, artifacts, and free-standing live jobs together.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref>

Optional Vitest E2E scenarios

  • None.

Relevant changed files

  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/live/onboard-negative-paths.test.ts
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/workflow-boundary.mts

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor

Findings: 0 needs attention, 4 worth checking, 0 nice ideas
Since last review: 0 prior items resolved, 3 still apply, 0 new items found

Review findings

🛠️ Needs attention

  • None.

🔎 Worth checking

  • Source-of-truth review needed: test/e2e-scenario/live/onboard-negative-paths.test.ts: ignoreCleanupError / cleanupInvalidKeyState: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: `ignoreCleanupError()` contains an empty `catch` and is used around all cleanup commands in `cleanupInvalidKeyState()`.
  • Source-of-truth rationale is incomplete for cleanup tolerance (test/e2e-scenario/live/onboard-negative-paths.test.ts:43): The localized tolerant cleanup path identifies expected absence states, but it does not define tolerated failure signatures, why this cannot be handled at the cleanup/source boundary, what regression test proves only expected absence is tolerated, or when the workaround can be removed.
    • Recommendation: Document and enforce the tolerance boundary: explicitly allow only expected missing-tool or resource-not-found outcomes, fail or record unexpected cleanup failures, and state the removal condition for any remaining best-effort behavior.
    • Evidence: `ignoreCleanupError()` wraps cleanup calls in `try { await run(); } catch {}` with only a comment that cleanup is best-effort because OpenShell or sandbox/gateway state may not exist.
  • Cleanup hides unexpected sandbox/gateway teardown failures (test/e2e-scenario/live/onboard-negative-paths.test.ts:46): The new live test silently catches every cleanup exception while destroying NemoClaw/OpenShell sandbox and gateway state. That is risky at the sandbox lifecycle boundary because unexpected command failures, tool-contract regressions, or leftover gateway/sandbox resources can be hidden while the test still passes.
    • Recommendation: Limit tolerated cleanup failures to expected absence cases such as ENOENT or resource-not-found output, and either fail the test or persist explicit diagnostics for any unexpected cleanup failure.
    • Evidence: `cleanupInvalidKeyState()` calls `nemoclaw <sandbox> destroy`, `openshell sandbox delete`, and `openshell gateway destroy`, and each call is wrapped by `ignoreCleanupError()` which has an empty catch block.
  • Invalid-key test does not assert forbidden gateway or sandbox side effects (test/e2e-scenario/live/onboard-negative-paths.test.ts:134): The direct invalid-key test verifies non-zero exit, explicit error text, and no JavaScript stack trace, but it does not verify that credential rejection happened before gateway or sandbox creation. Nearby canonical scenario metadata treats `gateway-started` and `sandbox-created` as forbidden side effects for the same invalid-key path.
    • Recommendation: After the invalid-key failure, assert that the NemoClaw gateway is absent or its health endpoint is unreachable, and that the sandbox is absent from NemoClaw/OpenShell listings, or wire this direct test through the existing absent-state probes.
    • Evidence: The new `scenario.json` contract and assertions cover only `nonZeroExit`, `explicitMessage`, and `noStackTrace`; `test/e2e-scenario/scenarios/scenarios/baseline.ts` declares invalid-key `forbiddenSideEffects: ["gateway-started", "sandbox-created"]` and `expected-states.ts` requires gateway and sandbox to be absent.

🌱 Nice ideas

  • None.
Consider writing more tests for
  • **Runtime validation** — Direct invalid NVIDIA key onboard leaves the NemoClaw gateway absent and the health endpoint unreachable after failure.. This PR changes a GitHub Actions live E2E workflow and exercises real CLI onboarding around sandbox/gateway lifecycle behavior. Workflow-boundary support tests cover job invariants, but runtime confidence would improve by locking resource absence and cleanup-error behavior.
  • **Runtime validation** — Direct invalid NVIDIA key onboard leaves the sandbox absent from `nemoclaw list` and `openshell sandbox list` after failure.. This PR changes a GitHub Actions live E2E workflow and exercises real CLI onboarding around sandbox/gateway lifecycle behavior. Workflow-boundary support tests cover job invariants, but runtime confidence would improve by locking resource absence and cleanup-error behavior.
  • **Runtime validation** — `cleanupInvalidKeyState` tolerates only expected OpenShell missing or resource-not-found cleanup failures and records or fails unexpected cleanup command failures.. This PR changes a GitHub Actions live E2E workflow and exercises real CLI onboarding around sandbox/gateway lifecycle behavior. Workflow-boundary support tests cover job invariants, but runtime confidence would improve by locking resource absence and cleanup-error behavior.
  • **Runtime validation** — Invalid NVIDIA key live onboard exits exactly `1` if legacy shell parity for exit code remains required.. This PR changes a GitHub Actions live E2E workflow and exercises real CLI onboarding around sandbox/gateway lifecycle behavior. Workflow-boundary support tests cover job invariants, but runtime confidence would improve by locking resource absence and cleanup-error behavior.
  • **Runtime validation** — Gateway port conflict onboard path exits cleanly with a friendly port-conflict message and no stack trace.. This PR changes a GitHub Actions live E2E workflow and exercises real CLI onboarding around sandbox/gateway lifecycle behavior. Workflow-boundary support tests cover job invariants, but runtime confidence would improve by locking resource absence and cleanup-error behavior.
  • **Invalid-key test does not assert forbidden gateway or sandbox side effects** — After the invalid-key failure, assert that the NemoClaw gateway is absent or its health endpoint is unreachable, and that the sandbox is absent from NemoClaw/OpenShell listings, or wire this direct test through the existing absent-state probes.
  • **Acceptance clause:** Adds a focused, free-standing Vitest live test for the first contract from `test/e2e/test-onboard-negative-paths.sh`: invalid NVIDIA API key handling during non-interactive onboard. — add test evidence or identify existing coverage. The new `test/e2e-scenario/live/onboard-negative-paths.test.ts` exercises the real CLI invalid-key path, but it does not preserve the legacy exact exit-code `1` assertion or the nearby forbidden side-effect/absent-state contract.
  • **Acceptance clause:** gateway port conflict behavior — add test evidence or identify existing coverage. The PR body explicitly lists this as not covered / left for follow-up; the diff adds only invalid-key coverage and the legacy shell script still contains the port-conflict phase.
Since last review details

Current findings:

  • Source-of-truth review needed: test/e2e-scenario/live/onboard-negative-paths.test.ts: ignoreCleanupError / cleanupInvalidKeyState: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: `ignoreCleanupError()` contains an empty `catch` and is used around all cleanup commands in `cleanupInvalidKeyState()`.
  • Source-of-truth rationale is incomplete for cleanup tolerance (test/e2e-scenario/live/onboard-negative-paths.test.ts:43): The localized tolerant cleanup path identifies expected absence states, but it does not define tolerated failure signatures, why this cannot be handled at the cleanup/source boundary, what regression test proves only expected absence is tolerated, or when the workaround can be removed.
    • Recommendation: Document and enforce the tolerance boundary: explicitly allow only expected missing-tool or resource-not-found outcomes, fail or record unexpected cleanup failures, and state the removal condition for any remaining best-effort behavior.
    • Evidence: `ignoreCleanupError()` wraps cleanup calls in `try { await run(); } catch {}` with only a comment that cleanup is best-effort because OpenShell or sandbox/gateway state may not exist.
  • Cleanup hides unexpected sandbox/gateway teardown failures (test/e2e-scenario/live/onboard-negative-paths.test.ts:46): The new live test silently catches every cleanup exception while destroying NemoClaw/OpenShell sandbox and gateway state. That is risky at the sandbox lifecycle boundary because unexpected command failures, tool-contract regressions, or leftover gateway/sandbox resources can be hidden while the test still passes.
    • Recommendation: Limit tolerated cleanup failures to expected absence cases such as ENOENT or resource-not-found output, and either fail the test or persist explicit diagnostics for any unexpected cleanup failure.
    • Evidence: `cleanupInvalidKeyState()` calls `nemoclaw <sandbox> destroy`, `openshell sandbox delete`, and `openshell gateway destroy`, and each call is wrapped by `ignoreCleanupError()` which has an empty catch block.
  • Invalid-key test does not assert forbidden gateway or sandbox side effects (test/e2e-scenario/live/onboard-negative-paths.test.ts:134): The direct invalid-key test verifies non-zero exit, explicit error text, and no JavaScript stack trace, but it does not verify that credential rejection happened before gateway or sandbox creation. Nearby canonical scenario metadata treats `gateway-started` and `sandbox-created` as forbidden side effects for the same invalid-key path.
    • Recommendation: After the invalid-key failure, assert that the NemoClaw gateway is absent or its health endpoint is unreachable, and that the sandbox is absent from NemoClaw/OpenShell listings, or wire this direct test through the existing absent-state probes.
    • Evidence: The new `scenario.json` contract and assertions cover only `nonZeroExit`, `explicitMessage`, and `noStackTrace`; `test/e2e-scenario/scenarios/scenarios/baseline.ts` declares invalid-key `forbiddenSideEffects: ["gateway-started", "sandbox-created"]` and `expected-states.ts` requires gateway and sandbox to be absent.

Workflow run details

This is an automated advisory review. A human maintainer must make the final merge decision.

@jyaunches jyaunches marked this pull request as ready for review June 10, 2026 15:26
@cv

cv commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Thanks for pushing the onboard-negative-paths slice forward. This needs to rebase/reshape before review because #5126 is now green and establishes the migration policy for this stack. Concrete blockers: targets main; should target #5126 foundation; edits legacy-inventory.json; writes under framework-tests/; body uses bridge/runner-class framing. Slice looks useful as part of onboard recovery after #5126, but should not merge current shape. If follow-up deletes test/e2e/test-onboard-negative-paths.sh, include #5126 Legacy E2E deletion evidence block.

@cv

cv commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Update after #5126 moved the foundation to the fixtures namespace: this onboard-negative-paths slice should be reshaped onto #5126 before review, with no retired ledger update and no framework-tests/ or test/e2e-scenario/framework/ paths. Use test/e2e-scenario/fixtures/ for shared helpers, and consider splitting hermetic validation from live onboard behavior if the PR stays large.

@jyaunches

jyaunches commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Migration-principle review for #5098: this PR is currently not aligned with the “simple Vitest tests, not new unnecessary framework” direction.

Reference from test/e2e-scenario/docs/MIGRATION.md: identify the actual contract, add only the fixture/helper needed, preserve real boundaries from Vitest, and use GitHub PRs/issues as the migration source of truth. The registry/matrix should describe stable scenario IDs, not become the default place to encode every migrated bash assertion.

Concerns in this PR:

  • It adds substantial onboarding fixture, state-validation, expected-state, runtime-support, and type changes for a bridge PR.
  • The PR does not retire the legacy bash script, so the framework expansion is not buying a clean deletion yet.
  • The “registry-driven bridge coverage” framing makes the registry/state-validation layer carry bespoke negative-path assertions that could be simpler direct Vitest tests.
  • local-registry-fields-match and custom onboarding profiles may be durable, but that needs stronger justification than one script migration.

Recommended path:

  • Do not land this as a broad registry/framework expansion.
  • Rewrite/split into focused direct Vitest tests for the actual contracts:
    1. invalid NVIDIA key exits non-zero, prints clear validation text, no stack trace;
    2. gateway port conflict exits non-zero, prints clear conflict text, no stack trace;
    3. custom policy/model env is honored.
  • For live behavior, use a simple test/e2e-scenario/live/onboard-negative-paths.test.ts with local helpers for port holding, CLI spawn, and text assertions. Spawn the real CLI/onboard path from Vitest; do not add registry/state-validation machinery unless needed by multiple scenarios.
  • Keep unit-shaped checks in focused unit tests (policy-tiers-onboard, validation helpers, etc.) rather than promoting them into live E2E.

Other acceptable options:

  1. One-contract PR first: choose invalid-key or port-conflict only, land a small direct Vitest replacement, then repeat for the next contract.
  2. Split durable fixture support: if custom-policy onboarding or registry-field validation is genuinely needed elsewhere, land a separate tiny fixture-support PR with explicit downstream users, then keep this PR focused on one contract.
  3. Pause migration: if equivalent simple Vitest coverage cannot be done without broad fixture work, leave the bash script in place for now rather than adding framework.

Suggested immediate direction:

  • Close or convert this PR to a small focused PR for one negative-path contract first.
  • Remove ledger edits.
  • Remove new expected-state/runtime-support/type expansion unless split and justified.
  • Add a Simplicity check section:
    • Test shape: focused direct Vitest or simple live Vitest.
    • New shared helpers: none, or split/justified tiny helper.
    • New framework/registry/ledger: none.
    • Workflow changes: none until full retirement.

@prekshivyas prekshivyas self-assigned this Jun 10, 2026
@copy-pr-bot

copy-pr-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

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

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown
Contributor

@prekshivyas prekshivyas 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.

Reviewed (code + 9-cat security). Bridges the legacy test-onboard-negative-paths.sh (#2573) into the registry-driven Vitest framework — flips 3 existing canonical scenario ids to supported, adds 3 onboarding-fixture dispatch paths + a local-registry-fields-match state probe. Test-only, no src//workflow changes.

Approve — coverage parity verified: the baseline scenario file is byte-identical main↔head (the ids already existed), the negative-path expected-states assert absence (gateway/sandbox absent) rather than probing a non-existent gateway, and the deferred legacy phases (policy-mode fallback, non-NVIDIA bypass) are genuinely covered in policy-tiers-onboard.test.ts / validation.test.ts — so keeping the legacy script covered (not deletionReady) is correct.

Security: all 9 pass — sandbox names still go through validateSandboxName, the port-conflict stub is loopback-only and closed in finally, and the real key is never injected into the invalid-key path. Nits: redactionValues:["not-a-nvidia-key"] redacts a non-secret (harmless); the invalid-key scenario declares requiredSecrets:[NVIDIA_API_KEY] but hardcodes the bad key.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

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

⚠️ Outside diff range comments (1)
.agents/skills/nemoclaw-user-configure-security/references/best-practices.md (1)

1-3: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

SPDX header compliance is missing across multiple changed files.

Please add SPDX copyright and Apache-2.0 license headers at the top of each file using the file-appropriate comment syntax (HTML comments for Markdown, # comments for YAML).

As per coding guidelines, all listed source file types in this repository must include SPDX headers.

🤖 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 @.agents/skills/nemoclaw-user-configure-security/references/best-practices.md
around lines 1 - 3, Add SPDX copyright and Apache-2.0 license headers to the top
of this Markdown file using HTML comments (e.g. <!-- SPDX-FileCopyrightText:
YEAR YourOrg --> and <!-- SPDX-License-Identifier: Apache-2.0 -->) so the file
containing the "# NemoClaw Security Best Practices" title and the import of
AgentOnly includes the required headers; apply the same pattern to all changed
files of their respective types (use HTML comments for .md and # comments for
YAML) and place them as the first lines before any content or imports.

Source: Coding guidelines

🧹 Nitpick comments (7)
Dockerfile (1)

424-431: ⚡ Quick win

Fail closed if the reviewed preflight object already has a mode.

This shape gate only distinguishes “already patched exact literal” vs. “not patched yet.” If a future OpenClaw bundle keeps the same auditContext but adds a different mode: at that callsite, this branch will still run and inject a second mode property instead of stopping on an unreviewed layout. Add an explicit pre-patch check for any non-trusted_env_proxy mode near cron-model-provider-preflight and patch_fail on it.

Suggested hardening
-            patched_count="$(grep -Fc 'mode: "trusted_env_proxy", auditContext: "cron-model-provider-preflight"' "$f" || true)"; \
+            if grep -Eq 'mode: "[^"]+", auditContext: "cron-model-provider-preflight"' "$f" \
+                && ! grep -Fq 'mode: "trusted_env_proxy", auditContext: "cron-model-provider-preflight"' "$f"; then \
+                patch_fail "Patch 6 shape gate: $f already specifies a different mode for cron-model-provider-preflight"; \
+            fi; \
+            patched_count="$(grep -Fc 'mode: "trusted_env_proxy", auditContext: "cron-model-provider-preflight"' "$f" || true)"; \
🤖 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 `@Dockerfile` around lines 424 - 431, The current patch logic only checks for
the exact literal 'mode: "trusted_env_proxy", auditContext:
"cron-model-provider-preflight"' and will blindly insert a second mode if a
different mode already exists; update the pre-patch checks in the block around
patched_count/new_patched_count to first grep for any occurrence of
'auditContext: "cron-model-provider-preflight"' combined with a 'mode:' nearby
(e.g., grep for 'mode:' within the same line or context) and if such a mode
exists and is not 'mode: "trusted_env_proxy"' call patch_fail with a clear
message, otherwise proceed with the existing exact-literal insertion and
verification logic; reference the functions/variables patched_count, sed
invocation that performs the replacement, new_patched_count, and patch_fail when
adding this protective branch.
docs/manage-sandboxes/messaging-channels.mdx (1)

87-87: ⚡ Quick win

Split semicolon-joined clauses to separate lines.

Line 87 contains two independent clauses joined by a semicolon. Per docs coding guidelines, use one sentence per line in source to make diffs readable.

📝 Suggested split
-To exercise Slack channel setup and the `slack` policy preset with placeholder tokens in a restricted network or hermetic test environment, set `NEMOCLAW_SKIP_SLACK_AUTH_VALIDATION=1` to skip the live credential probes; Slack token format checks still apply.
+To exercise Slack channel setup and the `slack` policy preset with placeholder tokens in a restricted network or hermetic test environment, set `NEMOCLAW_SKIP_SLACK_AUTH_VALIDATION=1` to skip the live credential probes.
+Slack token format checks still apply.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manage-sandboxes/messaging-channels.mdx` at line 87, The sentence
containing `SLACK_ALLOWED_USERS` currently joins two independent clauses with a
semicolon; split it into two separate sentences on separate lines in the docs
source so each clause stands alone: one line stating "Set `SLACK_ALLOWED_USERS`
to comma-separated Slack member IDs to authorize those users for DMs." and a
second line stating "Set `SLACK_ALLOWED_USERS` to authorize users for channel
`@mention` events in channels where the Slack app is present." Update the line
that mentions `SLACK_ALLOWED_USERS` accordingly so each sentence is on its own
line for clearer diffs.

Source: Coding guidelines

test/hermes-gateway-wrapper.test.ts (1)

78-78: 💤 Low value

Consider using literal : for PATH separator consistency.

The test is correctly gated to Linux-only (line 35), and path.delimiter will be : on Linux. However, based on learnings, the established pattern in this repo's test suite is to use the literal POSIX separator : when constructing PATH in tests that run on Linux runners.

♻️ Optional consistency improvement
-      pathPrefix = `${evilBin}${path.delimiter}`;
+      pathPrefix = `${evilBin}:`;
🤖 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/hermes-gateway-wrapper.test.ts` at line 78, The test sets pathPrefix
using path.delimiter but the repo tests use the POSIX literal ':' for Linux-only
tests; update the assignment that builds pathPrefix (where evilBin is
concatenated) to use the literal ':' instead of path.delimiter so the test uses
a consistent POSIX PATH separator (reference the pathPrefix variable and evilBin
concatenation).

Source: Learnings

test/e2e-scenario/docs/MIGRATION.md (1)

6-10: ⚡ Quick win

Format documentation with one sentence per line.

Multiple paragraphs in this file place several sentences on the same line, which makes diffs harder to review. As per coding guidelines for docs/**, "One sentence per line in source (makes diffs readable). Flag paragraphs where multiple sentences appear on the same line."

For example, lines 6-10 contain:

This file describes how to move coverage into the single Vitest E2E system
without confusing that work with the retired typed-shell scenario runner or a
second bash-driven harness. Vitest is the harness, GitHub Actions is the matrix,
and NemoClaw fixtures may invoke real subprocess and system boundaries when
those boundaries are the contract.

This should be formatted as:

This file describes how to move coverage into the single Vitest E2E system without confusing that work with the retired typed-shell scenario runner or a second bash-driven harness.
Vitest is the harness, GitHub Actions is the matrix, and NemoClaw fixtures may invoke real subprocess and system boundaries when those boundaries are the contract.

The same issue appears throughout the file in lines 19-29, 31-36, 38-55, 58-70, 74-87, and others.

Also applies to: 19-29, 31-36, 38-55, 58-70, 74-87

🤖 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/e2e-scenario/docs/MIGRATION.md` around lines 6 - 10, The paragraphs in
MIGRATION.md currently have multiple sentences on the same line (e.g., the
paragraph beginning "This file describes how to move coverage into the single
Vitest E2E system..." and the following sentence "Vitest is the harness, GitHub
Actions is the matrix..."); fix by reflowing those paragraphs so each sentence
is its own line throughout the document (apply to all similar paragraphs flagged
in the review), preserving existing sentence order and punctuation and avoiding
merging or splitting sentences—ensure every sentence ends with its punctuation
and starts on a new line.

Source: Coding guidelines

test/generate-openclaw-config-slack-allowlist.test.ts (1)

1-1: ⚡ Quick win

Consider removing @ts-nocheck and fixing underlying type issues.

The @ts-nocheck directive disables all TypeScript checking for this file. This test appears straightforward and similar test files in the repo don't use this directive. Removing it would surface any type errors that should be addressed.

🤖 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/generate-openclaw-config-slack-allowlist.test.ts` at line 1, Remove the
top-line "// `@ts-nocheck`" and re-enable TypeScript for this test, then fix any
surfaced type errors by adding explicit types or casts where needed (e.g., for
mocked inputs, expected config objects, and helper functions used in the test).
Locate and update the test declarations and any helper variables in this file
(the test case that builds the OpenClaw Slack allowlist config) to use correct
types or use "as" casts for third-party/mocked values, and add any missing
imports or type annotations so the file passes TypeScript checks without
disabling them.
tools/pr-review-advisor/analyze.mts (1)

1004-1021: 💤 Low value

Minor: inconsistent verb tense in finding description.

Line 1013 uses past tense "adds" for the added case but present tense "modifies" for the modified case. For consistency, consider using present tense for both: "adds""is adding" or "modifies""modified".

🤖 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 `@tools/pr-review-advisor/analyze.mts` around lines 1004 - 1021, In
addDeterministicFindings, make the description tense consistent by updating the
template that uses ledger.change (currently `This PR ${ledger.change === "added"
? "adds" : "modifies"} ${ledger.file}`) so both branches use the same tense
(e.g., change to `This PR ${ledger.change === "added" ? "is adding" : "is
modifying"} ${ledger.file}` or `This PR ${ledger.change === "added" ? "adds" :
"modifies"} ${ledger.file}` depending on preferred style) and update any related
strings (description, title, evidence if needed) to match.
tools/e2e-scenarios/workflow-boundary.mts (1)

213-301: ⚡ Quick win

Consider extracting shared workflow job validation logic.

validateOnboardNegativePathsVitestJob and validateOpenShellVersionPinVitestJob share ~85 lines of nearly identical validation logic (job existence, runs-on, env checks, secret exposure guards, pinned actions, artifact config). Extracting a parameterized helper (e.g., validateIndependentVitestJob(jobName, stepChecks)) would reduce duplication and make common contract changes easier to maintain.

🤖 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 `@tools/e2e-scenarios/workflow-boundary.mts` around lines 213 - 301, The two
functions validateOnboardNegativePathsVitestJob and
validateOpenShellVersionPinVitestJob duplicate large swaths of logic (job
existence, runs-on, env vars, requireEnvDoesNotExposeSecret checks, action SHA
enforcement via requireFullShaAction, and artifact upload validation); refactor
by extracting a parameterized helper (e.g., validateIndependentVitestJob or
validateVitestJobContract) that accepts the jobName and callbacks/flags for
job-specific assertions (like required steps names and specific run/run-contains
checks) and move common checks (runs-on, absence of needs/if,
NEMOCLAW_RUN_E2E_SCENARIOS, E2E_ARTIFACT_DIR, secret guards,
checkout/setup-node/upload validations) into that helper, then update both
validateOnboardNegativePathsVitestJob and validateOpenShellVersionPinVitestJob
to call the new helper with their specific step checks.
🤖 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 `@agents/hermes/Dockerfile`:
- Around line 105-109: Move the real hermes binary out of PATH and make the
wrapper exec it by absolute path: in the Dockerfile stop installing the real
binary as /usr/local/bin/hermes.real and instead place it at
/usr/local/lib/nemoclaw/hermes.real (ensure permissions), and update
agents/hermes/hermes-wrapper.sh to set
REAL_HERMES=/usr/local/lib/nemoclaw/hermes.real and exec "$REAL_HERMES" "$@"
(instead of relying on a PATH-resolvable hermes.real); this prevents bypassing
the wrapper (see cmdline_is_hermes_gateway) and ensures the wrapper always
invokes the non-PATH absolute binary.

In `@src/lib/actions/sandbox/policy-channel.ts`:
- Around line 511-514: The catch block that logs the Slack Socket Mode gateway
conflict failure should not "fail open" by returning true; instead preserve the
guard so adds don't proceed on transient verification failures unless the caller
explicitly passed the force override. Update the catch for the gateway
verification in policy-channel.ts (the try/catch that computes message from err
and logs with console.log(`  ${YW}⚠${R} Could not verify Slack Socket Mode
gateway conflicts: ${message}`)) to either rethrow the error or return false by
default, and only swallow and allow progress when the caller's force flag is
true (log that the check was bypassed when force is used). Ensure the function
that performs the add respects this boolean/exception behavior so --force still
controls bypassing the verification.

In `@src/lib/onboard.ts`:
- Around line 2924-2935: The disabledChannels state is read before stale sandbox
rows are pruned, so a stale registry entry can cause old disabled-channel lists
to be reused; move the call to resolveDisabledChannels (and the creation of
disabledChannelNames) to after pruneStaleSandboxEntry(sandboxName) (or re-run
resolveDisabledChannels immediately after prune) so the disabled list is loaded
from the up-to-date registry before it is used by the token-filtering logic and
when calling enforceMessagingChannelConflicts; update references to
disabledChannelNames accordingly (functions: resolveDisabledChannels,
pruneStaleSandboxEntry, enforceMessagingChannelConflicts).

In `@src/lib/onboard/bridge-dns-preflight.ts`:
- Around line 437-440: Replace the copy-paste verification that calls
require('node:dns').resolve(...) with a command that uses dns.lookup so the
check follows the OS resolver (e.g., swap the resolve call in the console.error
block that references hostname to use require('node:dns').lookup or node's
dns.lookup in the inline one-liner). Update the second console.error string that
currently contains `require('node:dns').resolve('${hostname}', ...)` to call
`dns.lookup('${hostname}', ...)` (keeping the same throw/log behavior) so the
remediation check uses the system resolution path.

In `@src/lib/onboard/messaging-conflict-guard.ts`:
- Around line 108-116: The Slack-axis false negatives happen because
backfillMessagingChannels() is only called inside the hasPlanCredentials branch,
so legacy rows without entry.messaging.plan never get messagingChannels
populated and Slack gateway conflicts can be missed; fix this by invoking
backfillMessagingChannels(registry, probe) earlier (or unconditionally) before
any Slack gateway checks (e.g., before calling
findSlackSocketModeGatewayConflicts() / resolveActiveChannelsFromEntry() or
before findChannelConflictsFromPlan()), or alternatively make the Slack helper
(resolveActiveChannelsFromEntry()/findSlackSocketModeGatewayConflicts()) fall
back to using the probe when messagingChannels is absent; reference
createMessagingConflictProbe, backfillMessagingChannels,
findChannelConflictsFromPlan, findSlackSocketModeGatewayConflicts, and
resolveActiveChannelsFromEntry to locate where to move/duplicate the call.

In `@test/onboard-selection.test.ts`:
- Around line 135-140: The synthetic 401 branch only changes the HTTP status but
leaves the successful fixture in the response body, which can mask regressions;
when the branch that sets status="401" (the code that checks has_config and url,
used by startOllamaAuthProxy readiness probing) is taken, also overwrite the
probe output file (the same -o target written in other branches) with an
authentication-error body (e.g., a JSON error/unauthorized payload) so the
response body matches the 401 status; update the branch that sets status to
"401" to write this auth error body to the output file instead of the
success/tool-call fixture.

---

Outside diff comments:
In
@.agents/skills/nemoclaw-user-configure-security/references/best-practices.md:
- Around line 1-3: Add SPDX copyright and Apache-2.0 license headers to the top
of this Markdown file using HTML comments (e.g. <!-- SPDX-FileCopyrightText:
YEAR YourOrg --> and <!-- SPDX-License-Identifier: Apache-2.0 -->) so the file
containing the "# NemoClaw Security Best Practices" title and the import of
AgentOnly includes the required headers; apply the same pattern to all changed
files of their respective types (use HTML comments for .md and # comments for
YAML) and place them as the first lines before any content or imports.

---

Nitpick comments:
In `@Dockerfile`:
- Around line 424-431: The current patch logic only checks for the exact literal
'mode: "trusted_env_proxy", auditContext: "cron-model-provider-preflight"' and
will blindly insert a second mode if a different mode already exists; update the
pre-patch checks in the block around patched_count/new_patched_count to first
grep for any occurrence of 'auditContext: "cron-model-provider-preflight"'
combined with a 'mode:' nearby (e.g., grep for 'mode:' within the same line or
context) and if such a mode exists and is not 'mode: "trusted_env_proxy"' call
patch_fail with a clear message, otherwise proceed with the existing
exact-literal insertion and verification logic; reference the
functions/variables patched_count, sed invocation that performs the replacement,
new_patched_count, and patch_fail when adding this protective branch.

In `@docs/manage-sandboxes/messaging-channels.mdx`:
- Line 87: The sentence containing `SLACK_ALLOWED_USERS` currently joins two
independent clauses with a semicolon; split it into two separate sentences on
separate lines in the docs source so each clause stands alone: one line stating
"Set `SLACK_ALLOWED_USERS` to comma-separated Slack member IDs to authorize
those users for DMs." and a second line stating "Set `SLACK_ALLOWED_USERS` to
authorize users for channel `@mention` events in channels where the Slack app is
present." Update the line that mentions `SLACK_ALLOWED_USERS` accordingly so
each sentence is on its own line for clearer diffs.

In `@test/e2e-scenario/docs/MIGRATION.md`:
- Around line 6-10: The paragraphs in MIGRATION.md currently have multiple
sentences on the same line (e.g., the paragraph beginning "This file describes
how to move coverage into the single Vitest E2E system..." and the following
sentence "Vitest is the harness, GitHub Actions is the matrix..."); fix by
reflowing those paragraphs so each sentence is its own line throughout the
document (apply to all similar paragraphs flagged in the review), preserving
existing sentence order and punctuation and avoiding merging or splitting
sentences—ensure every sentence ends with its punctuation and starts on a new
line.

In `@test/generate-openclaw-config-slack-allowlist.test.ts`:
- Line 1: Remove the top-line "// `@ts-nocheck`" and re-enable TypeScript for this
test, then fix any surfaced type errors by adding explicit types or casts where
needed (e.g., for mocked inputs, expected config objects, and helper functions
used in the test). Locate and update the test declarations and any helper
variables in this file (the test case that builds the OpenClaw Slack allowlist
config) to use correct types or use "as" casts for third-party/mocked values,
and add any missing imports or type annotations so the file passes TypeScript
checks without disabling them.

In `@test/hermes-gateway-wrapper.test.ts`:
- Line 78: The test sets pathPrefix using path.delimiter but the repo tests use
the POSIX literal ':' for Linux-only tests; update the assignment that builds
pathPrefix (where evilBin is concatenated) to use the literal ':' instead of
path.delimiter so the test uses a consistent POSIX PATH separator (reference the
pathPrefix variable and evilBin concatenation).

In `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 213-301: The two functions validateOnboardNegativePathsVitestJob
and validateOpenShellVersionPinVitestJob duplicate large swaths of logic (job
existence, runs-on, env vars, requireEnvDoesNotExposeSecret checks, action SHA
enforcement via requireFullShaAction, and artifact upload validation); refactor
by extracting a parameterized helper (e.g., validateIndependentVitestJob or
validateVitestJobContract) that accepts the jobName and callbacks/flags for
job-specific assertions (like required steps names and specific run/run-contains
checks) and move common checks (runs-on, absence of needs/if,
NEMOCLAW_RUN_E2E_SCENARIOS, E2E_ARTIFACT_DIR, secret guards,
checkout/setup-node/upload validations) into that helper, then update both
validateOnboardNegativePathsVitestJob and validateOpenShellVersionPinVitestJob
to call the new helper with their specific step checks.

In `@tools/pr-review-advisor/analyze.mts`:
- Around line 1004-1021: In addDeterministicFindings, make the description tense
consistent by updating the template that uses ledger.change (currently `This PR
${ledger.change === "added" ? "adds" : "modifies"} ${ledger.file}`) so both
branches use the same tense (e.g., change to `This PR ${ledger.change ===
"added" ? "is adding" : "is modifying"} ${ledger.file}` or `This PR
${ledger.change === "added" ? "adds" : "modifies"} ${ledger.file}` depending on
preferred style) and update any related strings (description, title, evidence if
needed) to match.
🪄 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: fd8f1dba-0c07-4e23-9a64-46ee23184119

📥 Commits

Reviewing files that changed from the base of the PR and between e30ec36 and 790f05e.

📒 Files selected for processing (143)
  • .agents/skills/nemoclaw-user-configure-inference/SKILL.md
  • .agents/skills/nemoclaw-user-configure-security/references/best-practices.md
  • .agents/skills/nemoclaw-user-manage-sandboxes/references/backup-restore.md
  • .agents/skills/nemoclaw-user-overview/references/release-notes.md
  • .agents/skills/nemoclaw-user-reference/references/commands.md
  • .agents/skills/nemoclaw-user-reference/references/network-policies.md
  • .coderabbit.yaml
  • .github/workflows/e2e-vitest-scenarios.yaml
  • .github/workflows/nightly-e2e.yaml
  • Dockerfile
  • agents/hermes/Dockerfile
  • agents/hermes/hermes-wrapper.sh
  • agents/hermes/start.sh
  • agents/openclaw/manifest.yaml
  • ci/test-file-size-budget.json
  • docs/about/release-notes.mdx
  • docs/inference/use-local-inference.mdx
  • docs/manage-sandboxes/messaging-channels.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • nemoclaw/src/commands/shields-status.test.ts
  • nemoclaw/src/commands/shields-status.ts
  • nemoclaw/src/commands/slash.test.ts
  • nemoclaw/src/commands/slash.ts
  • scripts/install.sh
  • scripts/ollama-auth-proxy.js
  • src/lib/actions/gateway-drift-preflight.test.ts
  • src/lib/actions/sandbox/policy-channel-conflict.test.ts
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/actions/upgrade-sandboxes.ts
  • src/lib/agent/defs.test.ts
  • src/lib/domain/maintenance/upgrade.test.ts
  • src/lib/domain/maintenance/upgrade.ts
  • src/lib/inference/model-prompts.test.ts
  • src/lib/inference/model-prompts.ts
  • src/lib/inference/ollama/proxy.ts
  • src/lib/inference/vllm-models.test.ts
  • src/lib/inference/vllm-models.ts
  • src/lib/inference/vllm-prompt.ts
  • src/lib/inference/vllm.test.ts
  • src/lib/inference/vllm.ts
  • src/lib/inventory/index.test.ts
  • src/lib/inventory/index.ts
  • src/lib/messaging/applier/conflict-detection-slack-gateway.test.ts
  • src/lib/messaging/applier/conflict-detection/index.ts
  • src/lib/messaging/applier/conflict-detection/slack-socket-mode.ts
  • src/lib/messaging/applier/conflict-detection/types.ts
  • src/lib/onboard.ts
  • src/lib/onboard/bridge-dns-preflight.ts
  • src/lib/onboard/host-dns-preflight.test.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/messaging-conflict-guard.test.ts
  • src/lib/onboard/messaging-conflict-guard.ts
  • src/lib/onboard/preflight.ts
  • src/lib/onboard/sandbox-agent.ts
  • src/lib/security/credential-filter.test.ts
  • src/lib/security/credential-filter.ts
  • src/lib/state/openclaw-config-merge.test.ts
  • src/lib/state/openclaw-config-merge.ts
  • src/lib/state/registry.ts
  • src/lib/state/sandbox.ts
  • src/lib/status-command-deps.ts
  • test/cli/list-share-live-inference.test.ts
  • test/control-ui-config-endpoint-docs.test.ts
  • test/e2e-scenario-advisor.test.ts
  • test/e2e-scenario/docs/MIGRATION.md
  • test/e2e-scenario/docs/README.md
  • test/e2e-scenario/docs/RETIREMENT.md
  • test/e2e-scenario/fixtures/artifacts.ts
  • test/e2e-scenario/fixtures/availability-env.ts
  • test/e2e-scenario/fixtures/cleanup.ts
  • test/e2e-scenario/fixtures/clients/command.ts
  • test/e2e-scenario/fixtures/clients/gateway.ts
  • test/e2e-scenario/fixtures/clients/host.ts
  • test/e2e-scenario/fixtures/clients/index.ts
  • test/e2e-scenario/fixtures/clients/provider.ts
  • test/e2e-scenario/fixtures/clients/sandbox.ts
  • test/e2e-scenario/fixtures/clients/state.ts
  • test/e2e-scenario/fixtures/e2e-test.ts
  • test/e2e-scenario/fixtures/live-project-gate.ts
  • test/e2e-scenario/fixtures/phases/environment.ts
  • test/e2e-scenario/fixtures/phases/index.ts
  • test/e2e-scenario/fixtures/phases/lifecycle.ts
  • test/e2e-scenario/fixtures/phases/onboarding.ts
  • test/e2e-scenario/fixtures/phases/runtime.ts
  • test/e2e-scenario/fixtures/phases/state-validation.ts
  • test/e2e-scenario/fixtures/redaction.ts
  • test/e2e-scenario/fixtures/secrets.ts
  • test/e2e-scenario/fixtures/shell-probe.ts
  • test/e2e-scenario/fixtures/shell/supervisor.ts
  • test/e2e-scenario/fixtures/shell/trusted-command.ts
  • test/e2e-scenario/framework-tests/e2e-migration-inventory.test.ts
  • test/e2e-scenario/live/onboard-negative-paths.test.ts
  • test/e2e-scenario/live/openshell-version-pin.test.ts
  • test/e2e-scenario/live/registry-scenarios.test.ts
  • test/e2e-scenario/live/ubuntu-repo-cli-smoke.test.ts
  • test/e2e-scenario/migration/legacy-inventory.json
  • test/e2e-scenario/scenarios/types.ts
  • test/e2e-scenario/support-tests/e2e-clients.test.ts
  • test/e2e-scenario/support-tests/e2e-expected-state.test.ts
  • test/e2e-scenario/support-tests/e2e-fixture-context.test.ts
  • test/e2e-scenario/support-tests/e2e-live-project-config.test.ts
  • test/e2e-scenario/support-tests/e2e-live-registry-discovery.test.ts
  • test/e2e-scenario/support-tests/e2e-live-skip-name-contract.test.ts
  • test/e2e-scenario/support-tests/e2e-manifests.test.ts
  • test/e2e-scenario/support-tests/e2e-migration-policy.test.ts
  • test/e2e-scenario/support-tests/e2e-migration-source-of-truth.test.ts
  • test/e2e-scenario/support-tests/e2e-phase-environment.test.ts
  • test/e2e-scenario/support-tests/e2e-phase-lifecycle.test.ts
  • test/e2e-scenario/support-tests/e2e-phase-onboarding.test.ts
  • test/e2e-scenario/support-tests/e2e-phase-runtime.test.ts
  • test/e2e-scenario/support-tests/e2e-phase-state-validation.test.ts
  • test/e2e-scenario/support-tests/e2e-redaction-entry.test.ts
  • test/e2e-scenario/support-tests/e2e-redaction-parity.test.ts
  • test/e2e-scenario/support-tests/e2e-scenario-matrix.test.ts
  • test/e2e-scenario/support-tests/e2e-scenario-registry.test.ts
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • test/e2e-scenario/support-tests/e2e-shell-supervisor.test.ts
  • test/e2e-script-workflow.test.ts
  • test/e2e/docs/parity-inventory.generated.json
  • test/e2e/test-cron-preflight-inference-local-e2e.sh
  • test/e2e/test-hermes-root-entrypoint-smoke.sh
  • test/fetch-guard-patch-regression.test.ts
  • test/generate-openclaw-config-slack-allowlist.test.ts
  • test/helpers/installer-sourced-env.ts
  • test/hermes-gateway-wrapper.test.ts
  • test/hermes-start.test.ts
  • test/install-preflight-docker-bootstrap.test.ts
  • test/install-preflight.test.ts
  • test/ollama-proxy-startup.test.ts
  • test/onboard-selection.test.ts
  • test/pr-review-advisor.test.ts
  • test/pr-workflow-contract.test.ts
  • test/release-latest-tag.test.ts
  • test/snapshot.test.ts
  • tools/e2e-advisor/scenario-comment.mts
  • tools/e2e-advisor/scenarios-schema.json
  • tools/e2e-advisor/scenarios.mts
  • tools/e2e-scenarios/workflow-boundary.mts
  • tools/pr-review-advisor/analyze.mts
  • vitest.config.ts
💤 Files with no reviewable changes (2)
  • test/e2e-scenario/framework-tests/e2e-migration-inventory.test.ts
  • test/e2e-scenario/migration/legacy-inventory.json
✅ Files skipped from review due to trivial changes (25)
  • test/e2e-scenario/live/registry-scenarios.test.ts
  • test/e2e-scenario/fixtures/shell/trusted-command.ts
  • src/lib/actions/gateway-drift-preflight.test.ts
  • test/e2e-scenario/fixtures/secrets.ts
  • test/e2e-scenario/fixtures/shell-probe.ts
  • test/e2e-scenario/fixtures/phases/lifecycle.ts
  • .agents/skills/nemoclaw-user-manage-sandboxes/references/backup-restore.md
  • .agents/skills/nemoclaw-user-reference/references/network-policies.md
  • test/e2e-scenario/live/ubuntu-repo-cli-smoke.test.ts
  • test/e2e-scenario/fixtures/clients/provider.ts
  • test/e2e-scenario/support-tests/e2e-fixture-context.test.ts
  • test/e2e-scenario/fixtures/shell/supervisor.ts
  • .agents/skills/nemoclaw-user-configure-inference/SKILL.md
  • test/e2e-scenario/support-tests/e2e-phase-lifecycle.test.ts
  • docs/inference/use-local-inference.mdx
  • test/e2e-scenario/fixtures/availability-env.ts
  • test/e2e-scenario/live/openshell-version-pin.test.ts
  • .agents/skills/nemoclaw-user-overview/references/release-notes.md
  • tools/e2e-advisor/scenarios-schema.json
  • docs/reference/commands-nemohermes.mdx
  • test/e2e-scenario/fixtures/phases/state-validation.ts
  • test/e2e-scenario/docs/RETIREMENT.md
  • test/e2e-scenario/docs/README.md
  • test/e2e-scenario/scenarios/types.ts
  • docs/about/release-notes.mdx

Comment thread agents/hermes/Dockerfile
Comment thread src/lib/actions/sandbox/policy-channel.ts
Comment thread src/lib/onboard.ts
Comment thread src/lib/onboard/bridge-dns-preflight.ts
Comment thread src/lib/onboard/messaging-conflict-guard.ts
Comment thread test/onboard-selection.test.ts
@jyaunches jyaunches enabled auto-merge (squash) June 10, 2026 23:15
@jyaunches jyaunches merged commit 153a13b into main Jun 10, 2026
38 checks passed
@jyaunches jyaunches deleted the e2e-migrate/test-onboard-negative-paths branch June 10, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: e2e End-to-end tests, nightly failures, or validation infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants