Skip to content

ci: simplify Vitest E2E selectors#5330

Merged
jyaunches merged 2 commits into
NVIDIA:mainfrom
jyaunches:chore/e2e-live-job-inventory
Jun 12, 2026
Merged

ci: simplify Vitest E2E selectors#5330
jyaunches merged 2 commits into
NVIDIA:mainfrom
jyaunches:chore/e2e-live-job-inventory

Conversation

@jyaunches

@jyaunches jyaunches commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • remove the separate validate-jobs workflow job and let generate-matrix remain the single selector gate
  • move free-standing Vitest job/scenario inventory into one shared env file
  • simplify workflow-boundary assertions so the diff removes selector duplication

Diff budget

  • 68 insertions, 321 deletions (-253 net)

Validation

  • npx vitest run --project cli test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts --reporter=default ✅
  • npm run typecheck ⚠️ fails before reaching these files because dist artifacts are not built in this fresh worktree
  • pre-commit full CLI test ⚠️ unrelated local failures/timeouts in broader suite; targeted workflow boundary test passes

Refs #5098

Summary by CodeRabbit

  • Chores

    • Moved end-to-end job selection/validation into matrix-generation and removed the separate validation job.
    • Centralized allowed free-standing Vitest jobs into a single configuration inventory.
    • PR reporting now bases selector handling on matrix-generation results and waits for the appropriate generation step.
  • Tests

    • Updated E2E workflow tests to reflect the new validation flow, dependency changes, strengthened selector/env/artefact checks, and dynamic free-standing job mappings.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Removes the standalone validate-jobs job, moves selector validation into generate-matrix, and externalizes allowed free-standing Vitest job IDs and scenario→job mappings to tools/e2e-scenarios/free-standing-jobs.env. Workflow validators, free-standing job needs, report-to-pr gating, and tests updated to use the dynamic inventory.

Changes

Selector Validation Refactoring

Layer / File(s) Summary
Configuration file and loading mechanism
tools/e2e-scenarios/free-standing-jobs.env, tools/e2e-scenarios/workflow-boundary.mts
New free-standing-jobs.env defines allowed_jobs and scenario-to-job CSV mappings; workflow-boundary.mts loads and parses the file at module init to derive allowedJobs and a scenario→job Map.
Selector evaluation using loaded configuration
tools/e2e-scenarios/workflow-boundary.mts
evaluateE2eVitestWorkflowDispatchSelectors now validates inputs.jobs, computes no-input defaults from the loaded allowed job IDs, and resolves inputs.scenarios via the loaded scenario→job Map.
Validator dependency and per-job checks
tools/e2e-scenarios/workflow-boundary.mts
Validator enforces needs === "generate-matrix" for free-standing jobs, adds validateFreeStandingInventoryCoverage, and updates multiple per-job checks to use the new inventory-driven expectations.
Matrix generation and workflow wiring
.github/workflows/e2e-vitest-scenarios.yaml, tools/e2e-scenarios/workflow-boundary.mts
Deletes the standalone validate-jobs job; generate-matrix sources allowed free-standing jobs from free-standing-jobs.env and performs selector validation; free-standing Vitest jobs now need only generate-matrix; generate-matrix assertions updated.
report-to-pr and tests
.github/workflows/e2e-vitest-scenarios.yaml, tools/e2e-scenarios/workflow-boundary.mts, test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
report-to-pr removes validate-jobs from needs, its script checks needs['generate-matrix']?.result === 'success' for selector validation, rejection messaging updated, and tests added/adjusted to validate the free-standing inventory and the new selector/coverage behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5243: Related changes to e2e Vitest free-standing selector plumbing; this PR replaces a validate-jobs-based flow with generate-matrix driven validation.
  • NVIDIA/NemoClaw#5233: Overlaps in updates to e2e-vitest-scenarios.yaml and workflow-boundary.mts for selector validation and report-to-pr gating.
  • NVIDIA/NemoClaw#5228: Touches free-standing job wiring and validator expectations that are impacted by the allowlist/inventory refactor.

Suggested reviewers

  • cv

Poem

A rabbit nudged the CI stone,
Moved validation into the matrix zone,
Env-file maps now lead the way,
Jobs wait on one bright ray. 🐇✨

🚥 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 'ci: simplify Vitest E2E selectors' directly summarizes the main change: consolidating job/scenario inventory and removing the separate validate-jobs job to simplify the selector workflow.
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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (4)
.github/workflows/e2e-vitest-scenarios.yaml (1)

1290-1294: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid labeling every generate-matrix failure as a selector rejection.

Line 1290 treats any non-success result from generate-matrix as "selector rejected", but that job now also does checkout, npm ci, and matrix generation. If any of those fail, the PR comment on Lines 1333 and 1338 will falsely blame the user’s selectors and suppress otherwise valid inputs. Use neutral wording here, or emit a dedicated output for actual selector-validation success before the expensive matrix work begins.

Suggested minimal wording fix
-            const selectorValidationPassed = needs['generate-matrix']?.result === 'success';
+            const selectorValidationPassed = needs['generate-matrix']?.result === 'success';
             const requestedScenarios = selectorValidationPassed ? rawRequestedScenarios : '';
             const requestedJobs = selectorValidationPassed ? rawRequestedJobs : '';
             const scenariosRejected = rawRequestedScenarios && !selectorValidationPassed;
             const jobsRejected = rawRequestedJobs && !selectorValidationPassed;
@@
-                ? '**Requested scenarios:** _(selector rejected by generate-matrix)_'
+                ? '**Requested scenarios:** _(unavailable because generate-matrix did not complete successfully)_'
@@
-                ? '**Requested jobs:** _(selector rejected by generate-matrix)_'
+                ? '**Requested jobs:** _(unavailable because generate-matrix did not complete successfully)_'

Also applies to: 1332-1339

🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml around lines 1290 - 1294, The
current logic uses needs['generate-matrix']?.result to set
selectorValidationPassed and then marks scenariosRejected/jobsRejected, which
incorrectly blames selectors when generate-matrix fails for unrelated reasons;
instead either (A) have the job that only validates selectors emit a dedicated
output (e.g., selector_validation_passed) before checkout/npm and change
selectorValidationPassed to read
needs['selector-validation']?.outputs.selector_validation_passed (or read
generate-matrix.outputs.selector_validation_passed if you choose to add the
output there), or (B) if you can't add a dedicated validation step, change the
rejection logic to use neutral wording by only treating selectors as rejected
when a specific validation output exists and is false, otherwise fall back to a
neutral failure path; update the variables selectorValidationPassed,
scenariosRejected, and jobsRejected and the PR comment generation logic to rely
on that new output or neutral condition rather than
needs['generate-matrix']?.result.
test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts (2)

496-497: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid the cascading runtime-overrides rewrite.

Lines 496-497 rewrite the same token twice: runtime-overrides-vitest becomes runtime-overrides-missing-missing after the second .replace(). That makes the fixture less controlled than intended and weakens the diagnostic. Swap the replacement order or use bounded patterns so each literal changes once.

Suggested fix
-        .replace(/runtime-overrides-vitest/g, "runtime-overrides-missing")
-        .replace(/runtime-overrides/g, "runtime-overrides-missing"),
+        .replace(/\bruntime-overrides\b/g, "runtime-overrides-missing")
+        .replace(/\bruntime-overrides-vitest\b/g, "runtime-overrides-missing"),
🤖 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/support-tests/e2e-scenarios-workflow.test.ts` around lines
496 - 497, The chained .replace calls on the string (the calls that use
.replace(/runtime-overrides-vitest/g, "runtime-overrides-missing") and
.replace(/runtime-overrides/g, "runtime-overrides-missing")) cause a double
rewrite so the token becomes "runtime-overrides-missing-missing"; update the
replacement to avoid cascading by either swapping the two replaces (replace
"runtime-overrides" first then "runtime-overrides-vitest") or use
bounded/anchored patterns (e.g. match exact literals or word boundaries for
"runtime-overrides-vitest" and "runtime-overrides") so each literal is replaced
exactly once in the code path that performs these .replace(...) calls.

486-503: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Target the externalized selector config in this test.

After this refactor, the runtime-overrides allowlist lives in the shared env file, but this fixture only rewrites the workflow YAML. That means the test can still pass while tools/e2e-scenarios/free-standing-jobs.env drifts, so it no longer verifies the contract named in the test. Mutate the loaded selector config (or mock that loader) instead of only renaming workflow literals here.

🤖 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/support-tests/e2e-scenarios-workflow.test.ts` around lines
486 - 503, The test currently only mutates workflow YAML so it misses the
externalized selector allowlist; update the test to either (a) mutate the
in-memory selector config that validateE2eVitestScenariosWorkflowBoundary reads
(so change the loaded allowlist entries to remove "runtime-overrides-vitest") or
(b) mock/stub the module/function that loads the shared selector allowlist (the
code that reads tools/e2e-scenarios/free-standing-jobs.env) so the validator
sees the missing literal; keep the rest of the fixture and assertions the same
but ensure validateE2eVitestScenariosWorkflowBoundary is invoked against the
modified/mocked selector config rather than only a renamed workflow file.
tools/e2e-scenarios/workflow-boundary.mts (1)

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

Contract mismatch: double-onboard-vitest has a scenario mapping in the env file but validator omits it.

The new free-standing-jobs.env defines double-onboard:double-onboard-vitest in free_standing_scenario_jobs_csv, indicating that scenarios=double-onboard should select this job. However, line 802 calls validateFreeStandingJobSelector without the scenario name, causing the validator to expect an if condition without the scenario selector.

If the workflow includes the scenario selector (to match the env file contract), validation will fail.

🐛 Proposed fix
-  validateFreeStandingJobSelector(errors, jobs, jobName);
+  validateFreeStandingJobSelector(errors, jobs, jobName, "double-onboard");
🤖 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` at line 802, The validator call at
validateFreeStandingJobSelector(errors, jobs, jobName) omits the scenario
selector so it doesn't match entries like "double-onboard:double-onboard-vitest"
from free_standing_scenario_jobs_csv; update the call to pass the scenario name
(e.g., validateFreeStandingJobSelector(errors, jobs, jobName, scenarioName)) and
adjust the validateFreeStandingJobSelector signature/logic to accept that
scenario string and require the "if" selector to include that scenario when
matching jobs (use the scenario token parsed from the env mapping such as
"double-onboard" when validating).
🤖 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 `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 1463-1465: The loop over FREE_STANDING_VITEST_JOB_IDS only asserts
presence of each job but doesn't enforce the shared selector/dependency rules
for "launchable-smoke-vitest"; call validateFreeStandingJobSelector(errors,
jobs, "launchable-smoke-vitest", ...) (same signature used for other allowed
jobs) where other free-standing Vitest jobs are validated, or add a dedicated
validator that checks the job's needs: generate-matrix and the common if
selector against the jobs map and pushes descriptive errors into errors to
mirror the existing validations.

---

Outside diff comments:
In @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 1290-1294: The current logic uses needs['generate-matrix']?.result
to set selectorValidationPassed and then marks scenariosRejected/jobsRejected,
which incorrectly blames selectors when generate-matrix fails for unrelated
reasons; instead either (A) have the job that only validates selectors emit a
dedicated output (e.g., selector_validation_passed) before checkout/npm and
change selectorValidationPassed to read
needs['selector-validation']?.outputs.selector_validation_passed (or read
generate-matrix.outputs.selector_validation_passed if you choose to add the
output there), or (B) if you can't add a dedicated validation step, change the
rejection logic to use neutral wording by only treating selectors as rejected
when a specific validation output exists and is false, otherwise fall back to a
neutral failure path; update the variables selectorValidationPassed,
scenariosRejected, and jobsRejected and the PR comment generation logic to rely
on that new output or neutral condition rather than
needs['generate-matrix']?.result.

In `@test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts`:
- Around line 496-497: The chained .replace calls on the string (the calls that
use .replace(/runtime-overrides-vitest/g, "runtime-overrides-missing") and
.replace(/runtime-overrides/g, "runtime-overrides-missing")) cause a double
rewrite so the token becomes "runtime-overrides-missing-missing"; update the
replacement to avoid cascading by either swapping the two replaces (replace
"runtime-overrides" first then "runtime-overrides-vitest") or use
bounded/anchored patterns (e.g. match exact literals or word boundaries for
"runtime-overrides-vitest" and "runtime-overrides") so each literal is replaced
exactly once in the code path that performs these .replace(...) calls.
- Around line 486-503: The test currently only mutates workflow YAML so it
misses the externalized selector allowlist; update the test to either (a) mutate
the in-memory selector config that validateE2eVitestScenariosWorkflowBoundary
reads (so change the loaded allowlist entries to remove
"runtime-overrides-vitest") or (b) mock/stub the module/function that loads the
shared selector allowlist (the code that reads
tools/e2e-scenarios/free-standing-jobs.env) so the validator sees the missing
literal; keep the rest of the fixture and assertions the same but ensure
validateE2eVitestScenariosWorkflowBoundary is invoked against the
modified/mocked selector config rather than only a renamed workflow file.

In `@tools/e2e-scenarios/workflow-boundary.mts`:
- Line 802: The validator call at validateFreeStandingJobSelector(errors, jobs,
jobName) omits the scenario selector so it doesn't match entries like
"double-onboard:double-onboard-vitest" from free_standing_scenario_jobs_csv;
update the call to pass the scenario name (e.g.,
validateFreeStandingJobSelector(errors, jobs, jobName, scenarioName)) and adjust
the validateFreeStandingJobSelector signature/logic to accept that scenario
string and require the "if" selector to include that scenario when matching jobs
(use the scenario token parsed from the env mapping such as "double-onboard"
when validating).
🪄 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: 2c1088f0-2513-431a-9aea-056c0b681e62

📥 Commits

Reviewing files that changed from the base of the PR and between 561bd2f and d2355e5.

📒 Files selected for processing (4)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env
  • tools/e2e-scenarios/workflow-boundary.mts

Comment thread tools/e2e-scenarios/workflow-boundary.mts Outdated
@jyaunches

Copy link
Copy Markdown
Contributor Author

This is a useful cleanup direction, especially because #5098 needs one deterministic way to answer “which live E2E Vitest jobs exist?”, but I’m requesting changes before this becomes the workflow cleanup base.

Required before merge:

  1. Rebase on current main and carry forward model-router-provider-routed-inference-vitest from test(e2e): migrate test-model-router-provider-routed-inference.sh to vitest [IND-2] #5221. The new inventory currently misses that just-merged migrated Vitest lane.
  2. Decide/source-of-truth explicitly. tools/e2e-scenarios/free-standing-jobs.env is helpful, but it must not become an unvalidated second registry. Either generate/derive it from the workflow, or add strict tests that fail when workflow jobs and the env inventory diverge.
  3. Update the advisor/operator path. tools/e2e-advisor/scenarios.mts and any dispatch examples still describe scenarios= semantics; the future Epic: Migrate legacy bash E2E into the Vitest E2E system #5098 Pi advisor needs to consume the same job inventory/selector contract this PR introduces.
  4. Make “full E2E Vitest suite” explicit and dispatchable: empty selector should run all registry scenarios plus all free-standing live Vitest jobs; selective jobs= should run exactly the requested subset.
  5. Include the current workflow parse/dispatch blocker in the cleanup if this PR touches that area: the current main e2e-vitest-scenarios.yaml cannot be manually dispatched because the model-router job uses ${{ runner.temp }} in a place GitHub rejects at dispatch parse time.

Net: this moves the needle, but it needs to be rebased and tied into the advisor/dispatch contract so it actually simplifies #5098 execution rather than adding another place to keep in sync.

@jyaunches jyaunches force-pushed the chore/e2e-live-job-inventory branch from d2355e5 to 6ee68c5 Compare June 12, 2026 14:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
.github/workflows/e2e-vitest-scenarios.yaml (1)

1423-1429: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale reference to validate-jobs in PR comment text.

The rejection messages still reference validate-jobs, but validation is now performed by generate-matrix. Update the user-facing text for consistency.

📝 Proposed fix
             scenariosRejected
-              ? '**Requested scenarios:** _(selector rejected by validate-jobs)_'
+              ? '**Requested scenarios:** _(selector rejected by generate-matrix)_'
               : requestedScenarios
                 ? `**Requested scenarios:** \`${requestedScenarios}\``
                 : '**Requested scenarios:** _(default — all supported)_',
             jobsRejected
-              ? '**Requested jobs:** _(selector rejected by validate-jobs)_'
+              ? '**Requested jobs:** _(selector rejected by generate-matrix)_'
               : requestedJobs
🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml around lines 1423 - 1429, Update
the user-facing rejection strings that currently mention "validate-jobs" to
instead reference "generate-matrix": locate the template branches using the
symbols scenariosRejected and jobsRejected and replace the text '**Requested
scenarios:** _(selector rejected by validate-jobs)_' and any similar
'**Requested jobs:** _(selector rejected by validate-jobs)_' occurrences with
'**Requested scenarios:** _(selector rejected by generate-matrix)_' and
'**Requested jobs:** _(selector rejected by generate-matrix)_' respectively so
the PR comment accurately reflects the new validator.
🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 1083-1088: The job-level env uses runner.temp (DOCKER_CONFIG)
which is invalid at job scope; update the workflow by removing DOCKER_CONFIG
from the job-level env and either (a) replace it with a job-safe value like
using github.workspace for the path (e.g., set DOCKER_CONFIG based on
github.workspace) or (b) move DOCKER_CONFIG into the env: of the specific steps
that need it (steps that use NEMOCLAW_CLI_BIN / E2E_ARTIFACT_DIR /
NEMOCLAW_RUN_E2E_SCENARIOS / OPENSHELL_GATEWAY), or compute DOCKER_CONFIG in a
prior step and export it for later steps.

---

Outside diff comments:
In @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 1423-1429: Update the user-facing rejection strings that currently
mention "validate-jobs" to instead reference "generate-matrix": locate the
template branches using the symbols scenariosRejected and jobsRejected and
replace the text '**Requested scenarios:** _(selector rejected by
validate-jobs)_' and any similar '**Requested jobs:** _(selector rejected by
validate-jobs)_' occurrences with '**Requested scenarios:** _(selector rejected
by generate-matrix)_' and '**Requested jobs:** _(selector rejected by
generate-matrix)_' respectively so the PR comment accurately reflects the new
validator.
🪄 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: 1c93eb51-c041-4d27-bd47-b327dde8920e

📥 Commits

Reviewing files that changed from the base of the PR and between d2355e5 and 6ee68c5.

📒 Files selected for processing (4)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env
  • tools/e2e-scenarios/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (3)
  • tools/e2e-scenarios/free-standing-jobs.env
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/workflow-boundary.mts

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
.github/workflows/e2e-vitest-scenarios.yaml (1)

1423-1429: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale reference to validate-jobs in PR comment text.

The rejection messages still reference validate-jobs, but validation is now performed by generate-matrix. Update the user-facing text for consistency.

📝 Proposed fix
             scenariosRejected
-              ? '**Requested scenarios:** _(selector rejected by validate-jobs)_'
+              ? '**Requested scenarios:** _(selector rejected by generate-matrix)_'
               : requestedScenarios
                 ? `**Requested scenarios:** \`${requestedScenarios}\``
                 : '**Requested scenarios:** _(default — all supported)_',
             jobsRejected
-              ? '**Requested jobs:** _(selector rejected by validate-jobs)_'
+              ? '**Requested jobs:** _(selector rejected by generate-matrix)_'
               : requestedJobs
🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml around lines 1423 - 1429, Update
the user-facing rejection strings that currently mention "validate-jobs" to
instead reference "generate-matrix": locate the template branches using the
symbols scenariosRejected and jobsRejected and replace the text '**Requested
scenarios:** _(selector rejected by validate-jobs)_' and any similar
'**Requested jobs:** _(selector rejected by validate-jobs)_' occurrences with
'**Requested scenarios:** _(selector rejected by generate-matrix)_' and
'**Requested jobs:** _(selector rejected by generate-matrix)_' respectively so
the PR comment accurately reflects the new validator.
🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 1083-1088: The job-level env uses runner.temp (DOCKER_CONFIG)
which is invalid at job scope; update the workflow by removing DOCKER_CONFIG
from the job-level env and either (a) replace it with a job-safe value like
using github.workspace for the path (e.g., set DOCKER_CONFIG based on
github.workspace) or (b) move DOCKER_CONFIG into the env: of the specific steps
that need it (steps that use NEMOCLAW_CLI_BIN / E2E_ARTIFACT_DIR /
NEMOCLAW_RUN_E2E_SCENARIOS / OPENSHELL_GATEWAY), or compute DOCKER_CONFIG in a
prior step and export it for later steps.

---

Outside diff comments:
In @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 1423-1429: Update the user-facing rejection strings that currently
mention "validate-jobs" to instead reference "generate-matrix": locate the
template branches using the symbols scenariosRejected and jobsRejected and
replace the text '**Requested scenarios:** _(selector rejected by
validate-jobs)_' and any similar '**Requested jobs:** _(selector rejected by
validate-jobs)_' occurrences with '**Requested scenarios:** _(selector rejected
by generate-matrix)_' and '**Requested jobs:** _(selector rejected by
generate-matrix)_' respectively so the PR comment accurately reflects the new
validator.
🪄 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: 1c93eb51-c041-4d27-bd47-b327dde8920e

📥 Commits

Reviewing files that changed from the base of the PR and between d2355e5 and 6ee68c5.

📒 Files selected for processing (4)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env
  • tools/e2e-scenarios/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (3)
  • tools/e2e-scenarios/free-standing-jobs.env
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/workflow-boundary.mts
🛑 Comments failed to post (1)
.github/workflows/e2e-vitest-scenarios.yaml (1)

1083-1088: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

runner context is not available at job-level env: — workflow dispatch will fail.

The runner context (including runner.temp) is only available within steps, not at the job level. GitHub will reject this workflow at parse time when manually dispatched. The PR objectives explicitly flag this as a blocker to address.

Move DOCKER_CONFIG into step-level env: blocks for steps that need it, or compute it within a step.

🔧 Proposed fix

Option 1 — Use github.workspace which is available at job level:

     env:
-      DOCKER_CONFIG: ${{ runner.temp }}/docker-config-model-router-provider-routed-inference
+      DOCKER_CONFIG: ${{ github.workspace }}/.docker-config-model-router-provider-routed-inference

Option 2 — Move to step-level for steps that need it:

     env:
-      DOCKER_CONFIG: ${{ runner.temp }}/docker-config-model-router-provider-routed-inference
       E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/vitest/model-router-provider-routed-inference
       ...
     steps:
       ...
       - name: Authenticate to Docker Hub
         env:
           DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
           DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
+          DOCKER_CONFIG: ${{ runner.temp }}/docker-config-model-router-provider-routed-inference
         shell: bash
         run: |
           ...
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    env:
      DOCKER_CONFIG: ${{ github.workspace }}/.docker-config-model-router-provider-routed-inference
      E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/vitest/model-router-provider-routed-inference
      NEMOCLAW_CLI_BIN: ${{ github.workspace }}/bin/nemoclaw.js
      NEMOCLAW_RUN_E2E_SCENARIOS: "1"
      OPENSHELL_GATEWAY: "nemoclaw"
🧰 Tools
🪛 actionlint (1.7.12)

[error] 1084-1084: context "runner" is not allowed here. available contexts are "github", "inputs", "matrix", "needs", "secrets", "strategy", "vars". see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability for more details

(expression)

🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml around lines 1083 - 1088, The
job-level env uses runner.temp (DOCKER_CONFIG) which is invalid at job scope;
update the workflow by removing DOCKER_CONFIG from the job-level env and either
(a) replace it with a job-safe value like using github.workspace for the path
(e.g., set DOCKER_CONFIG based on github.workspace) or (b) move DOCKER_CONFIG
into the env: of the specific steps that need it (steps that use
NEMOCLAW_CLI_BIN / E2E_ARTIFACT_DIR / NEMOCLAW_RUN_E2E_SCENARIOS /
OPENSHELL_GATEWAY), or compute DOCKER_CONFIG in a prior step and export it for
later steps.

Source: Linters/SAST tools

@jyaunches jyaunches force-pushed the chore/e2e-live-job-inventory branch from 6ee68c5 to 6c37476 Compare June 12, 2026 14:41
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure chore Build, CI, dependency, or tooling maintenance labels Jun 12, 2026
@wscurran

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
tools/e2e-scenarios/workflow-boundary.mts (1)

1732-1758: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

The new selector registry is still only half-dynamic.

evaluateE2eVitestWorkflowDispatchSelectors() now accepts every job id from FREE_STANDING_VITEST_JOB_IDS, but boundary enforcement and report-to-pr coverage are still maintained as separate hardcoded lists here. That means adding a new id to free-standing-jobs.env can make the selector valid and part of the default run set without also requiring a workflow validator, existence check, shared gating check, or report-to-pr dependency for that job.

Please derive these checks from the same registry (for example, a single validator table keyed by job id, with report-to-pr needs derived from the same keys) so the env file cannot become an unvalidated secondary inventory.

Also applies to: 1764-1783

🤖 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 1732 - 1758, The
various hardcoded validator lists (calls like validateFreeStandingJobSelector,
validateRuntimeOverridesVitestJob, validateTokenRotationVitestJob, and
validateRebuildOpenClawVitestJob) must be derived from the same registry used by
evaluateE2eVitestWorkflowDispatchSelectors / FREE_STANDING_VITEST_JOB_IDS so the
env file cannot introduce unvalidated jobs; refactor by creating a single
registry/table keyed by job id that includes metadata flags (needsValidation,
requiresReportToPr, sharedGating, etc.), update
evaluateE2eVitestWorkflowDispatchSelectors to consume that registry, and replace
the separate hardcoded validator calls in workflow-boundary.mts with a loop that
iterates the registry and invokes the appropriate validation logic based on each
job's metadata (use the existing validator functions like
validateFreeStandingJobSelector and validate*VitestJob by referencing their
names when dispatching).
🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 59-65: The free-standing selector contract is split between
generate-matrix and the workflow guards (is_free_standing_scenario(), each job's
if: and report-to-pr.needs), causing drift; fix by centralizing the inventory:
have the workflow source and parse free_standing_jobs from
free-standing-jobs.env into a single canonical variable (e.g.
free_standing_scenarios_csv) and change every per-job guard (the
is_free_standing_scenario() function and all job if: expressions) and
report-to-pr.needs aggregation to reference that same canonical variable, or
alternatively add a strict boundary test that enumerates every free-standing job
mapping and fails if any job guard or report-to-pr.needs entry does not match
generate-matrix output (use generate-matrix output as the single source of
truth).

In `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 23-39: The module assumes keys exist and dereferences
FREE_STANDING_JOBS_ENV.allowed_jobs and
FREE_STANDING_JOBS_ENV.free_standing_scenario_jobs_csv during import, causing
crashes on malformed free-standing-jobs.env; update readFreeStandingJobsEnv and
the initialization of FREE_STANDING_VITEST_JOB_IDS and
FREE_STANDING_VITEST_SCENARIO_TO_JOB to validate the parsed env contract: after
building FREE_STANDING_JOBS_ENV (in readFreeStandingJobsEnv or immediately
after) assert the required keys exist and are non-empty, throw a clear,
actionable error if missing, and default to safe empty values (e.g., [] or empty
Map) when appropriate so consumers of FREE_STANDING_JOBS_ENV don't crash on
import; reference the functions/consts readFreeStandingJobsEnv,
FREE_STANDING_JOBS_ENV, FREE_STANDING_VITEST_JOB_IDS,
FREE_STANDING_VITEST_SCENARIO_TO_JOB and the keys allowed_jobs and
free_standing_scenario_jobs_csv when making the checks.

---

Outside diff comments:
In `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 1732-1758: The various hardcoded validator lists (calls like
validateFreeStandingJobSelector, validateRuntimeOverridesVitestJob,
validateTokenRotationVitestJob, and validateRebuildOpenClawVitestJob) must be
derived from the same registry used by
evaluateE2eVitestWorkflowDispatchSelectors / FREE_STANDING_VITEST_JOB_IDS so the
env file cannot introduce unvalidated jobs; refactor by creating a single
registry/table keyed by job id that includes metadata flags (needsValidation,
requiresReportToPr, sharedGating, etc.), update
evaluateE2eVitestWorkflowDispatchSelectors to consume that registry, and replace
the separate hardcoded validator calls in workflow-boundary.mts with a loop that
iterates the registry and invokes the appropriate validation logic based on each
job's metadata (use the existing validator functions like
validateFreeStandingJobSelector and validate*VitestJob by referencing their
names when dispatching).
🪄 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: deac211c-89ee-47a0-b1ad-6a27cde97747

📥 Commits

Reviewing files that changed from the base of the PR and between 6ee68c5 and 6c37476.

📒 Files selected for processing (4)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env
  • tools/e2e-scenarios/workflow-boundary.mts
✅ Files skipped from review due to trivial changes (1)
  • tools/e2e-scenarios/free-standing-jobs.env

Comment thread .github/workflows/e2e-vitest-scenarios.yaml Outdated
Comment thread tools/e2e-scenarios/workflow-boundary.mts Outdated
@jyaunches jyaunches force-pushed the chore/e2e-live-job-inventory branch from 18156ec to 00adf10 Compare June 12, 2026 15:31

@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/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts (1)

269-289: ⚡ Quick win

Add a regression test for the empty-selector default path.

This new coverage exercises explicit jobs= and scenarios= inputs, but it never pins the no-input behavior that now derives “all registry scenarios + all free-standing jobs” from the inventory. That default is one of the main contract changes in this PR, so a regression there would still pass this suite.

Please add one assertion for evaluateE2eVitestWorkflowDispatchSelectors({}) and one generateMatrixForDispatch({ JOBS: "", SCENARIOS: "" }) check to lock down the empty-selector behavior. Based on PR objectives, an empty selector must dispatch the full E2E Vitest suite.

🤖 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/support-tests/e2e-scenarios-workflow.test.ts` around lines
269 - 289, Add assertions to lock the empty-selector default behavior: call
evaluateE2eVitestWorkflowDispatchSelectors({}) and assert it returns valid:
true, liveScenariosRuns: false, selectedFreeStandingJobs equals the inventory's
allowedJobs, and registryScenarios equals the inventory's registry scenarios;
and call generateMatrixForDispatch({ JOBS: "", SCENARIOS: "" }) and assert it
dispatches the full E2E Vitest suite (i.e., hermes_selected true for
hermes-e2e-vitest and matrix contains all registry scenarios and free-standing
jobs per readFreeStandingJobsInventory()). Use the existing helpers
evaluateE2eVitestWorkflowDispatchSelectors, generateMatrixForDispatch, and
readFreeStandingJobsInventory to construct the expected values.
🤖 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 `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 368-395: The validator validateFreeStandingInventoryCoverage
currently only checks the hardcoded FREE_STANDING_VITEST_JOB_IDS and
FREE_STANDING_VITEST_SCENARIO_TO_JOB; update it to iterate the canonical
FREE_STANDING_JOBS_INVENTORY (or its equivalent registry) and run the
selector/needs checks for each inventory entry (or call the existing
validateFreeStandingJobSelector per job) instead of only the subset, so every
inventory-defined job (e.g., sandbox-survival-vitest) is validated for presence,
report-to-pr coverage, and correct needs/shared-if selectors; ensure you
reference FREE_STANDING_JOBS_INVENTORY, validateFreeStandingJobSelector (or the
selector-validation logic), and the job keys used in asRecord/jobIf when
implementing this change.

---

Nitpick comments:
In `@test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts`:
- Around line 269-289: Add assertions to lock the empty-selector default
behavior: call evaluateE2eVitestWorkflowDispatchSelectors({}) and assert it
returns valid: true, liveScenariosRuns: false, selectedFreeStandingJobs equals
the inventory's allowedJobs, and registryScenarios equals the inventory's
registry scenarios; and call generateMatrixForDispatch({ JOBS: "", SCENARIOS: ""
}) and assert it dispatches the full E2E Vitest suite (i.e., hermes_selected
true for hermes-e2e-vitest and matrix contains all registry scenarios and
free-standing jobs per readFreeStandingJobsInventory()). Use the existing
helpers evaluateE2eVitestWorkflowDispatchSelectors, generateMatrixForDispatch,
and readFreeStandingJobsInventory to construct the expected values.
🪄 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: a7a24c14-9c68-49b6-a296-fbd66c5863ab

📥 Commits

Reviewing files that changed from the base of the PR and between 157d676 and 00adf10.

📒 Files selected for processing (4)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env
  • tools/e2e-scenarios/workflow-boundary.mts
✅ Files skipped from review due to trivial changes (1)
  • tools/e2e-scenarios/free-standing-jobs.env
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/e2e-vitest-scenarios.yaml

Comment thread tools/e2e-scenarios/workflow-boundary.mts
@jyaunches jyaunches force-pushed the chore/e2e-live-job-inventory branch 2 times, most recently from cc64cc9 to 4862adb Compare June 12, 2026 16:01
@jyaunches jyaunches force-pushed the chore/e2e-live-job-inventory branch from 4862adb to 783312b Compare June 12, 2026 16:08
@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All jobs passed

Run: 27428412159
Workflow ref: ci/pr-5330-e2e-vitest
Requested scenarios: openshell-version-pin
Requested jobs: (default — all free-standing when no scenarios are requested)
Summary: 2 passed, 0 failed, 20 skipped

Job Result
credential-migration-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ✅ success
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 27428410843
Workflow ref: ci/pr-5330-e2e-vitest
Requested scenarios: (default — all supported)
Requested jobs: (default — all free-standing when no scenarios are requested)
Summary: 19 passed, 3 failed, 0 skipped

Job Result
credential-migration-vitest ✅ success
double-onboard-vitest ✅ success
gateway-guard-recovery ❌ failure
generate-matrix ✅ success
hermes-e2e-vitest ✅ success
hermes-root-entrypoint-smoke-vitest ✅ success
inference-routing-vitest ✅ success
issue-4434-tui-unreachable-inference-vitest ✅ success
launchable-smoke-vitest ❌ failure
live-scenarios ✅ success
model-router-provider-routed-inference-vitest ✅ success
network-policy-vitest ❌ failure
onboard-negative-paths-vitest ✅ success
openclaw-tui-chat-correlation-vitest ✅ success
openshell-version-pin-vitest ✅ success
rebuild-openclaw-vitest ✅ success
runtime-overrides-vitest ✅ success
sandbox-rebuild-vitest ✅ success
sandbox-survival-vitest ✅ success
shields-config-vitest ✅ success
skill-agent-vitest ✅ success
token-rotation-vitest ✅ success

Failed jobs: gateway-guard-recovery, launchable-smoke-vitest, network-policy-vitest. Check run artifacts for logs.

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

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure chore Build, CI, dependency, or tooling maintenance v0.0.65 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants