Skip to content

feat(ci): automate exact-head live E2E gating - #6589

Closed
prekshivyas wants to merge 3 commits into
NVIDIA:mainfrom
prekshivyas:ci/required-live-e2e-coordinator
Closed

feat(ci): automate exact-head live E2E gating#6589
prekshivyas wants to merge 3 commits into
NVIDIA:mainfrom
prekshivyas:ci/required-live-e2e-coordinator

Conversation

@prekshivyas

@prekshivyas prekshivyas commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a trusted PR coordinator that lets normal CI and E2E Advisor run in parallel, then dispatches the bounded union of deterministic and Advisor-required live jobs only after exact-head CI succeeds. It reports one stable E2E / Required Live check and cancels superseded PR-correlated runs on every new commit.

Related Issue

Part of #6145. Depends on #6583 for automatic fork Advisor output; first-party coordination is otherwise independent.

Changes

  • Resolve PR identity from the completed CI / Pull Request run by exact head SHA, repository, branch, and canonical PR files API.
  • Create the stable required-live check before fallible PR resolution or Advisor lookup.
  • Validate the Advisor artifact against the same head SHA and changed-file set, then union supported recommendations with a deterministic coverage floor.
  • Dispatch at most three selected E2E jobs concurrently; unsupported selectors, manual expansion, stale state, missing evidence, and controller errors are blocking failures.
  • Bind every child checkout and risk signal to the validated SHA, plan digest, correlation ID, job, and shard, with a second PR identity check immediately before dispatch.
  • Publish one exact-head E2E / Required Live result, cancel superseded coordinator/child runs immediately, and close the check on every controller failure path without overwriting evidence-specific failures.
  • Never dispatch secret-bearing live E2E for fork code. Fork planning remains automatic; a maintainer must review and promote a revision to a trusted upstream branch before live execution.
  • Use least-privilege job permissions, safe-integer API identifiers, private controller state, and typed, symlink-safe GitHub output handling.
  • Reclaim hosted-runner disk before dual-version gateway builds and preserve the Docker authentication boundary; increase only the subprocess-heavy MCP status test's timeout to its measured CI-safe value.

Type of Change

  • Code change with doc updates

Quality Gates

  • Tests added or updated for changed behavior
  • Docs updated for user-facing behavior changes
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed — trusted controller code is loaded from the default branch; exact PR identity, CI SHA, Advisor artifact, dispatch identity, private state digest, checkout SHA, and child evidence are independently validated. Fork code cannot reach repository live-E2E credentials.
  • Non-success, skipped, or missing CI check accepted by maintainer — not applicable; all required PR checks are green.

Verification

  • Commit is GitHub Verified and includes the DCO sign-off
  • npm run check:diff
  • npm run typecheck:cli
  • 42/42 coordinator, dispatch, evidence, and workflow tests
  • 23/23 focused unified E2E workflow-boundary tests
  • 11/11 MCP bridge status-resolution tests
  • YAML validation, lint/format, source-shape and size budgets, secret scan, and pre-commit/pre-push hooks
  • Applicable broad gate passed — CI / Pull Request and all required PR checks are green
  • Both PR Review Advisors passed on exact head — GPT-5.5 and Nemotron 3 Ultra, zero findings
  • E2E Advisor passed on exact head — Advisor run
  • Advisor-required full E2E passed — full fan-out produced 78 green executable lanes; the sole hosted runner disappeared mid-rebuild-hermes without logs/cleanup, and the exact-SHA isolated retry passed
  • Both legacy gateway-upgrade lanes passed, including v0.0.36 beyond the former disk-exhaustion point
  • No secrets, API keys, or credentials committed

Rollout

  1. Merge feat(ci): automate E2E advisor and mock parity #6583 before this PR so fork Advisor artifacts exist automatically.
  2. Observe E2E / Required Live in advisory mode on representative first-party PRs.
  3. Add that exact check name to the main ruleset and enable strict up-to-date required checks.
  4. Keep fork live execution disabled; promote reviewed fork revisions to an upstream branch when live coverage is required.
  5. Keep the post-merge shadow gate enabled and inspect failures before cutting a release tag.

The PR-specific controller remains separate only for PR lifecycle concerns—workflow_run identity resolution, fork rejection, and superseded-run cancellation. Planning, dispatch identity, state validation, evidence classification, and check completion reuse the existing post-merge risk-gate primitives.


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

Summary by CodeRabbit

  • New Features

    • Added automated required-live E2E checks for pull requests.
    • E2E runs now validate the exact PR commit, generate risk-based job plans, and report a single status check.
    • New commits automatically cancel superseded E2E activity and prevent stale results.
    • Fork-based changes are blocked from secret-bearing live execution.
    • Added safeguards and cleanup to improve reliability of live E2E runs.
  • Documentation

    • Documented required-live PR checks, risk planning, fork handling, and rollout behavior.

@prekshivyas prekshivyas self-assigned this Jul 9, 2026
@prekshivyas prekshivyas added area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure labels Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 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

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: 3ef65870-99f4-467f-9210-76d0a5bb0a4e

📥 Commits

Reviewing files that changed from the base of the PR and between 47bb7b1 and 8e7b07f.

📒 Files selected for processing (12)
  • .github/workflows/e2e.yaml
  • .github/workflows/pr-e2e-risk-gate.yaml
  • src/lib/actions/sandbox/mcp-bridge-status-resolution.test.ts
  • test/e2e/README.md
  • test/e2e/support/e2e-workflow-contract.test.ts
  • test/e2e/support/openshell-gateway-upgrade-workflow-boundary.test.ts
  • test/post-merge-e2e-risk-gate.test.ts
  • test/pr-e2e-risk-gate-workflow.test.ts
  • test/pr-e2e-risk-gate.test.ts
  • tools/e2e-advisor/README.md
  • tools/e2e-advisor/post-merge-risk-gate.mts
  • tools/e2e-advisor/pr-risk-gate.mts
✅ Files skipped from review due to trivial changes (2)
  • src/lib/actions/sandbox/mcp-bridge-status-resolution.test.ts
  • tools/e2e-advisor/README.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/e2e/support/openshell-gateway-upgrade-workflow-boundary.test.ts
  • test/e2e/support/e2e-workflow-contract.test.ts
  • .github/workflows/e2e.yaml
  • tools/e2e-advisor/pr-risk-gate.mts

📝 Walkthrough

Walkthrough

Adds PR-scoped exact-commit validation and risk dispatch to e2e.yaml, a required-live coordinator workflow, a pr-risk-gate.mts CLI, shared PR-context check helpers, and supporting tests and documentation.

Changes

PR-scoped required-live E2E risk gate

Layer / File(s) Summary
e2e.yaml risk dispatch and validation
.github/workflows/e2e.yaml
Adds PR-scoped inputs, concurrency, exact-head validation, pull-request permissions, and runner disk cleanup.
Required-live coordinator workflow
.github/workflows/pr-e2e-risk-gate.yaml
Coordinates check creation, exact PR and CI resolution, Advisor artifact polling, bounded E2E dispatch, evidence completion, cancellation, and abandonment.
Risk-gate CLI orchestration
tools/e2e-advisor/pr-risk-gate.mts
Implements trusted-context validation, exact PR lookup, Advisor plan validation, dispatch, cancellation, abandonment, and CLI mode routing.
Shared check and dispatch helpers
tools/e2e-advisor/post-merge-risk-gate.mts
Adds PR context, configurable check helpers, checked-out-commit validation, PR dispatch inputs, controller-error conclusions, and required-success completion.
Workflow contracts, behavior tests, and documentation
test/pr-e2e-risk-gate.test.ts, test/pr-e2e-risk-gate-workflow.test.ts, test/e2e/support/*, test/post-merge-e2e-risk-gate.test.ts, test/e2e/README.md, tools/e2e-advisor/README.md, src/lib/actions/sandbox/mcp-bridge-status-resolution.test.ts
Adds coverage for workflow wiring, exact-head and fork gating, CLI lifecycle behavior, helper completion outcomes, runner cleanup, documentation, and an explicit sandbox test timeout.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI Pull Request
  participant Coordinator as pr-e2e-risk-gate.yaml
  participant CLI as pr-risk-gate.mts
  participant GitHub as GitHub API
  participant E2E as e2e.yaml

  CI->>Coordinator: workflow_run completed
  Coordinator->>CLI: initialize and resolve exact PR
  CLI->>GitHub: create check and fetch PR state
  Coordinator->>Coordinator: poll for matching Advisor artifact
  Coordinator->>CLI: start required-live plan
  CLI->>E2E: dispatch risk_pr workflow
  Coordinator->>CLI: finish or abandon
  CLI->>GitHub: complete required-live check
Loading

Suggested labels: feature

Suggested reviewers: cv, jyaunches

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% 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 clearly summarizes the main change: automating exact-head live E2E gating in CI.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch from 4ab13e9 to 9f627e8 Compare July 9, 2026 17: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.

🧹 Nitpick comments (3)
.github/workflows/pr-e2e-risk-gate.yaml (2)

13-17: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Scope actions: write / checks: write to the jobs that need them.

Workflow-level actions: write and checks: write grant both jobs more than they need. cancel-superseded only needs actions: write + contents: read; checks/pull-requests are only used by coordinate. Moving to per-job permissions: reduces blast radius on these trusted triggers.

🔒 Suggested per-job least-privilege split
-permissions:
-  actions: write
-  checks: write
-  contents: read
-  pull-requests: read
+permissions: {}
   cancel-superseded:
     if: ${{ github.repository == 'NVIDIA/NemoClaw' && github.event_name == 'pull_request_target' }}
     runs-on: ubuntu-latest
+    permissions:
+      actions: write
+      contents: read
     timeout-minutes: 5
   coordinate:
     if: ${{ github.repository == 'NVIDIA/NemoClaw' && github.event_name == 'workflow_run' && github.event.workflow_run.event == 'pull_request' }}
     runs-on: ubuntu-latest
+    permissions:
+      actions: write
+      checks: write
+      contents: read
+      pull-requests: read
     timeout-minutes: 130

As per path instructions: "Keep permissions least-privileged and pass untrusted values as data rather than interpolating them into shell programs."

🤖 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/pr-e2e-risk-gate.yaml around lines 13 - 17, The
workflow-level permissions are too broad for both jobs in pr-e2e-risk-gate.yaml;
scope them per job instead. Update the workflow so cancel-superseded keeps only
the permissions it needs (actions and contents), and move checks and
pull-requests permissions to the coordinate job where they are actually used.
Use the job names cancel-superseded and coordinate to place the permissions
blocks correctly.

Sources: Path instructions, Linters/SAST tools


113-121: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pass resolved outputs as env data instead of ${{ }} template expansion into run:.

Lines 116–121 interpolate steps.resolve.outputs.* / steps.advisor.outputs.artifact_dir directly into the shell command (same pattern at Lines 144–147 and 156). Although these outputs are name-allowlisted and newline-rejected upstream, the path instruction requires passing PR-derived values as environment data rather than expanding them into the program text.

🛡️ Example for the start step (apply the same to finish/abandon)
       - id: start
         name: Build exact-head plan and dispatch required live E2E
         if: ${{ always() }}
         env:
           GITHUB_TOKEN: ${{ github.token }}
+          PR_NUMBER: ${{ steps.resolve.outputs.pr_number }}
+          BASE_SHA: ${{ steps.resolve.outputs.base_sha }}
+          HEAD_SHA: ${{ steps.resolve.outputs.head_sha }}
+          HEAD_REPO: ${{ steps.resolve.outputs.head_repo }}
+          CI_GREEN: ${{ steps.resolve.outputs.ci_green }}
+          ADVISOR_DIR: ${{ steps.advisor.outputs.artifact_dir }}
         run: >-
           node --experimental-strip-types tools/e2e-advisor/pr-risk-gate.mts
           --mode start
-          --pr "${{ steps.resolve.outputs.pr_number }}"
-          --base "${{ steps.resolve.outputs.base_sha }}"
-          --head "${{ steps.resolve.outputs.head_sha }}"
-          --head-repo "${{ steps.resolve.outputs.head_repo }}"
-          --ci-green "${{ steps.resolve.outputs.ci_green }}"
-          --advisor-dir "${{ steps.advisor.outputs.artifact_dir }}"
+          --pr "$PR_NUMBER"
+          --base "$BASE_SHA"
+          --head "$HEAD_SHA"
+          --head-repo "$HEAD_REPO"
+          --ci-green "$CI_GREEN"
+          --advisor-dir "$ADVISOR_DIR"

As per path instructions: "pass untrusted values as data rather than interpolating them into shell programs."

🤖 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/pr-e2e-risk-gate.yaml around lines 113 - 121, The
PR-risk-gate workflow is interpolating resolved step outputs directly into the
shell command instead of passing them as environment data. Update the start,
finish, and abandon invocations in the workflow to put the resolved
PR/base/head/repo/CI-green/advisor directory values into env on the step, and
have the pr-risk-gate.mts command read them from environment variables rather
than `${{ }}` expansion in run.

Sources: Path instructions, Linters/SAST tools

tools/e2e-advisor/pr-risk-gate.mts (1)

267-283: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

cancel() should use args.head or stop passing it.
It currently cancels every queued/in_progress E2E PR #<n> risk run for the PR, so the current revision can’t be spared. If this is meant to keep only the latest head, filter by run.head_sha; otherwise drop --head from the caller.

🤖 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-advisor/pr-risk-gate.mts` around lines 267 - 283, The cancel()
logic currently cancels every queued/in_progress E2E PR run matching the PR
prefix, so it cannot preserve the current revision. Update cancel() in
pr-risk-gate.mts to honor args.head by filtering the WorkflowRun results on
run.head_sha before calling githubApi, or remove the --head path from the caller
if that behavior is not intended; use the existing cancel() and
githubRestPaginated()/githubApi flow as the place to apply the fix.
🤖 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.

Nitpick comments:
In @.github/workflows/pr-e2e-risk-gate.yaml:
- Around line 13-17: The workflow-level permissions are too broad for both jobs
in pr-e2e-risk-gate.yaml; scope them per job instead. Update the workflow so
cancel-superseded keeps only the permissions it needs (actions and contents),
and move checks and pull-requests permissions to the coordinate job where they
are actually used. Use the job names cancel-superseded and coordinate to place
the permissions blocks correctly.
- Around line 113-121: The PR-risk-gate workflow is interpolating resolved step
outputs directly into the shell command instead of passing them as environment
data. Update the start, finish, and abandon invocations in the workflow to put
the resolved PR/base/head/repo/CI-green/advisor directory values into env on the
step, and have the pr-risk-gate.mts command read them from environment variables
rather than `${{ }}` expansion in run.

In `@tools/e2e-advisor/pr-risk-gate.mts`:
- Around line 267-283: The cancel() logic currently cancels every
queued/in_progress E2E PR run matching the PR prefix, so it cannot preserve the
current revision. Update cancel() in pr-risk-gate.mts to honor args.head by
filtering the WorkflowRun results on run.head_sha before calling githubApi, or
remove the --head path from the caller if that behavior is not intended; use the
existing cancel() and githubRestPaginated()/githubApi flow as the place to apply
the fix.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 65ea3c76-535b-4662-bcf4-40fccabec849

📥 Commits

Reviewing files that changed from the base of the PR and between e2777f8 and 4ab13e9.

📒 Files selected for processing (7)
  • .github/workflows/e2e.yaml
  • .github/workflows/pr-e2e-risk-gate.yaml
  • test/e2e/README.md
  • test/pr-e2e-risk-gate-workflow.test.ts
  • test/pr-e2e-risk-gate.test.ts
  • tools/e2e-advisor/post-merge-risk-gate.mts
  • tools/e2e-advisor/pr-risk-gate.mts

Comment thread tools/e2e-advisor/pr-risk-gate.mts Fixed

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

🧹 Nitpick comments (1)
test/pr-e2e-risk-gate.test.ts (1)

58-68: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Test title doesn't match what's actually being tested.

The title claims to test rejection of an artifact "from another revision," but both the artifact's risk-plan.json and the call use the same headSha ("a".repeat(40)); the mismatch actually exercised is changedFiles. There's no dedicated coverage for an actual headSha mismatch case in advisorJobs, per the upstream contract that checks both artifactPlan.headSha !== headSha and the changedFiles equality.

Consider renaming this test to reflect the changed-files mismatch, and adding a separate case for a genuine headSha mismatch to cover both branches of the exact-head validation.

🤖 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/pr-e2e-risk-gate.test.ts` around lines 58 - 68, Rename the advisorJobs
test to reflect that it is exercising a changedFiles mismatch rather than a
different revision, since the artifact() setup and advisorJobs() call both use
the same headSha. Then add a separate test in pr-e2e-risk-gate.test.ts that
passes a different headSha into advisorJobs to cover the artifactPlan.headSha
!== headSha branch, keeping the existing exact-head validation coverage split
between changed-files and head-sha mismatches.

Source: Path instructions

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

Inline comments:
In @.github/workflows/pr-e2e-risk-gate.yaml:
- Around line 46-48: The coordinate job in pr-e2e-risk-gate.yaml has too little
timeout headroom relative to its internal waits, risking forced termination
before the always() cleanup in the finish/abandon steps can run. Increase the
job-level timeout on the coordinate job (or reduce the gh run watch budget
inside the same job) so the workflow_run handling, artifact polling, and cleanup
logic in coordinate, finish, and abandon all reliably complete within the job
limit.
- Around line 108-121: The `start` step in `pr-e2e-risk-gate.yaml` is
interpolating `steps.resolve.outputs.*` directly into the `run` script; move
those values into `env:` and reference them as shell variables in the command
instead. Apply the same pattern to the related `finish` and `abandon` steps,
using the existing `resolve` and `cancel` steps as the safe reference pattern,
so the workflow passes data to `pr-risk-gate.mts` without embedding untrusted
values in the shell program.
- Around line 13-17: Move the broad workflow-level permissions in this GitHub
Actions workflow into the specific jobs that need them so the token is
least-privileged. Keep `actions: write` only on the `cancel-superseded` job and
`checks: write` only on the `coordinate` job, while leaving the shared workflow
permissions minimal; use the job names `coordinate` and `cancel-superseded` to
place the scoped permissions correctly.
- Around line 19-21: The concurrency settings for the coordinator workflow use
different group keys for `pull_request_target` and `workflow_run`, which
prevents a newer run from cancelling an older superseded `coordinate` run.
Update the `concurrency.group` in `pr-e2e-risk-gate.yaml` to use one shared
identifier for both triggers, using the existing workflow context from the
coordinator job so `cancel-in-progress` can stop stale runs consistently.

---

Nitpick comments:
In `@test/pr-e2e-risk-gate.test.ts`:
- Around line 58-68: Rename the advisorJobs test to reflect that it is
exercising a changedFiles mismatch rather than a different revision, since the
artifact() setup and advisorJobs() call both use the same headSha. Then add a
separate test in pr-e2e-risk-gate.test.ts that passes a different headSha into
advisorJobs to cover the artifactPlan.headSha !== headSha branch, keeping the
existing exact-head validation coverage split between changed-files and head-sha
mismatches.
🪄 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: c7315ca0-29e6-45f0-ac51-746a2f5e037c

📥 Commits

Reviewing files that changed from the base of the PR and between 4ab13e9 and 9f627e8.

📒 Files selected for processing (7)
  • .github/workflows/e2e.yaml
  • .github/workflows/pr-e2e-risk-gate.yaml
  • test/e2e/README.md
  • test/pr-e2e-risk-gate-workflow.test.ts
  • test/pr-e2e-risk-gate.test.ts
  • tools/e2e-advisor/post-merge-risk-gate.mts
  • tools/e2e-advisor/pr-risk-gate.mts
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/pr-e2e-risk-gate-workflow.test.ts
  • tools/e2e-advisor/pr-risk-gate.mts
  • tools/e2e-advisor/post-merge-risk-gate.mts
  • .github/workflows/e2e.yaml

Comment thread .github/workflows/pr-e2e-risk-gate.yaml Outdated
Comment thread .github/workflows/pr-e2e-risk-gate.yaml
Comment thread .github/workflows/pr-e2e-risk-gate.yaml Outdated
Comment thread .github/workflows/pr-e2e-risk-gate.yaml Outdated
@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch 2 times, most recently from 997be37 to 853e308 Compare July 9, 2026 18:20
Comment thread tools/e2e-advisor/pr-risk-gate.mts Fixed
@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch 2 times, most recently from f7d04ab to 47bb7b1 Compare July 9, 2026 18:46
@cv cv added the v0.0.80 label Jul 9, 2026
@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch 6 times, most recently from f2a20cf to ab1ae30 Compare July 9, 2026 20:57
@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch from ab1ae30 to ea581d2 Compare July 9, 2026 21:10
@cv cv added the needs: unblock Blocked item needs dependency or decision resolved label Jul 9, 2026
@cv

cv commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Hold exact head ea581d21a9a311bec8c150e94cedb2d3f71e5d6f behind #6583: it is six main commits stale, its manual PR Advisor was cancelled by the shared dispatch concurrency, and the promoted full run both has an OpenClaw inference-switch failure and does not exercise the new correlated risk_pr protocol. After #6583 lands, refresh from current main, re-promote that exact SHA, and rerun ordinary CI, manual review, and the full E2E-advisor matrix before approval.

@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch from ea581d2 to eb15562 Compare July 9, 2026 21:24
@prekshivyas
prekshivyas requested a review from jyaunches July 9, 2026 21:28
@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch from eb15562 to b0bd5eb Compare July 9, 2026 21:34
@cv

cv commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Exact head b0bd5eb remains six commits behind current main (merge base 521bb13), so the post-#6583 refresh is still outstanding. It also fails codebase-growth-guardrails because test/post-merge-e2e-risk-gate.test.ts raises the test-file if count from 0 to 1; please linearize that branch when rebasing after #6583 lands. The existing hold and sequencing remain unchanged, so no live run is useful yet.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas
prekshivyas force-pushed the ci/required-live-e2e-coordinator branch from b0bd5eb to b273dde Compare July 9, 2026 22:44
# Conflicts:
#	tools/e2e-advisor/post-merge-risk-gate.mts
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: cloud-onboard, openshell-gateway-upgrade
Optional E2E: None

Dispatch hint: cloud-onboard,openshell-gateway-upgrade

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: target/main
Head: HEAD
Confidence: high

Required E2E

  • cloud-onboard (high): Required by the deterministic risk plan floor for .github/workflows/e2e.yaml. This validates that the changed unified E2E workflow still installs the intended pinned dependencies and reaches a usable hosted onboarding path on a clean runner.
  • openshell-gateway-upgrade (high): The PR directly changes the live OpenShell gateway upgrade job setup by adding runner disk reclamation before building both upgrade images. Run the existing upgrade E2E to verify the real dual-version gateway upgrade lifecycle still executes successfully.

Optional E2E

  • None.

New E2E recommendations

  • required-live-pr-coordinator (high): The new PR required-live coordinator and risk_pr exact-head dispatch path rely on GitHub workflow_run, pull_request_target, Checks, Actions dispatch, cancellation, and artifact correlation behavior that existing live product jobs do not exercise end-to-end.
    • Suggested test: Add a non-secret workflow-dispatched integration E2E for the required-live PR coordinator that uses a controlled first-party test PR or dry-run GitHub API fixture to verify exact-head selection, stale SHA rejection, fork blocking, correlated child run identity, and required-live check completion.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: cloud-onboard,openshell-gateway-upgrade

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: cloud-onboard, e2e-all
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard
  • gh workflow run e2e.yaml --ref <pr-head-ref>

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: target/main
Head: HEAD
Confidence: high

Required E2E targets

  • cloud-onboard: Installer and platform changes must work on a clean supported host with the pinned runtime dependencies.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard
  • e2e-all: The PR changes shared e2e.yaml workflow machinery, exact-commit dispatch validation, checkout binding, and workflow-boundary tests; policy requires the full E2E fan-out. This also covers the deterministic risk-plan floor for cloud-onboard and the changed OpenShell gateway upgrade workflow path.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref>

Optional E2E targets

  • None.

Relevant changed files

  • .github/workflows/e2e.yaml
  • test/e2e/README.md
  • test/e2e/support/e2e-workflow-contract.test.ts
  • test/e2e/support/openshell-gateway-upgrade-workflow-boundary.test.ts

@prekshivyas prekshivyas removed the needs: unblock Blocked item needs dependency or decision resolved label Jul 10, 2026
@cjagwani

Copy link
Copy Markdown
Collaborator

Exact-head security/gate follow-up for 815158ca451208401d42fa41b38e9d6c623ce59f:

  • I do not confirm the suspected same-PR cross-generation overlap of GitHub secret-bearing jobs. The coordinator uses a stable PR branch group with cancel-in-progress, every child uses stable PR-number concurrency, and the no-secret validation job rechecks open PR, first-party repo, and exact SHA before secret jobs. Forced cancellation still cannot prove external teardown, so a non-secret two-generation/coordinator smoke remains important before making Required Live mandatory.
  • This fork PR itself fails closed because its head repo is prekshivyas/NemoClaw. For future upstream-head PRs, however, repo identity plus exact green CI is the authorization boundary; there is no protected Environment, human approval, trusted label, or permission recheck. That is acceptable only if project policy intentionally treats every upstream branch writer/bot as a live-E2E secret principal. An admin should explicitly accept that model or add an independently controlled Environment/reviewer gate.

The PR is still not merge-ready: it is stale against current main, has no human approval, its current-head automatic PR Advisor was skipped, and there is no exact-head e2e-all/cloud-onboard live evidence. The old full run and retry analyzed the pre-merge parent b273ddea, not 815158ca.

Required sequence: sync current main; rerun ordinary gates and both trusted advisors on the resulting exact head; run exact-head e2e-all (covering cloud-onboard); obtain human approval; record the upstream-writer trust decision. Keep Required Live advisory until the coordinator path has a non-secret end-to-end generation/concurrency smoke.

@prekshivyas

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Security/correctness review of exact head 8e7b07f9b916ae9f973b014de32d832dc0d09e2f: FAIL / changes required.

  1. Every successful PR child is rejected by the evidence verifier. .github/workflows/e2e.yaml:5 names the child E2E PR #<pr> risk <correlation>, and pr-risk-gate.mts:348-357 persists prNumber. But post-merge-risk-gate.mts:627-645 still requires E2E risk <correlation>, and finishRiskGate() never supplies the PR number (:894-898). A direct exact-head probe reproduces the identity mismatch. The 39 focused tests pass because no test finishes a PR-named child. Thread prNumber into the correlated identity contract and add a full PR finish regression.

  2. The secret-bearing child has no unforgeable coordinator authorization. e2e.yaml:10-61 exposes all risk inputs to ordinary workflow_dispatch; :111-127 proves only a main-ref dispatch, an open same-repo PR at that SHA, and syntactically valid caller-provided jobs/hash/UUID. It does not prove a green canonical CI run, Advisor result, deterministic plan, three-job cap, approved human, or coordinator caller. A write collaborator/app can directly dispatch e2e.yaml on main with an unmerged first-party PR SHA and arbitrary allowed jobs; downstream jobs checkout that PR code while DockerHub/provider/messaging secrets are available (:339-351, :447-453, :3593-3618, :3802-3835). The same GitHub Actions app can also emit the same check name, so the proposed name-only required status is not a distinct trust principal. Require an independently controlled authorization bound to {pr, headSha, jobs, planHash} and revalidate it in the child before any credential-bearing job—prefer a protected Environment with required maintainer reviewers and a Ruleset Required Workflow/dedicated App identity. Reject bots/apps and non-default-base PRs unless policy explicitly authorizes them.

  3. A stale workflow completion can cancel the current generation. Coordinator concurrency at .github/workflows/pr-e2e-risk-gate.yaml:15-17 is keyed only by head repo+branch. A late completion/rerun for old SHA A can start after SHA B's coordinator and cancel B before its own exact-head check fails. Nothing retriggers B, leaving the current required check failed or stuck. Key coordinate runs by exact SHA (and keep explicit superseded-child cancellation generation-aware), or otherwise reject stale generations before they can cancel current work.

  4. Large PRs can plan from a silently truncated file set. pullChangedFiles() asks for 5001 and rejects only >5000 (pr-risk-gate.mts:138-143), but GitHub's PR-files endpoint returns at most 3000 files. The guard is unreachable; a larger PR can omit risk-relevant paths and even reach “No live E2E required.” Fail closed at the API cap or derive and cross-check the complete exact base/head diff.

After fixing these, require an exact-head non-secret coordinator lifecycle smoke (including two out-of-order generations), focused tests, current-main sync, trusted advisors, and the Advisor-required full live matrix. Do not enable this as a required check until the authorization principal and end-to-end protocol are proven.

@cjagwani

Copy link
Copy Markdown
Collaborator

Concrete repository evidence for authorization finding 2: this is not hypothetical. Open Dependabot PR #5755 has author=dependabot[bot], author_association=CONTRIBUTOR, and head.repo.full_name=NVIDIA/NemoClaw; automation PR #4344 likewise used github-actions[bot] with a same-repo head. Both satisfy the current sole first_party predicate.

The live rulesets also do not make all upstream topic branches a human-trusted namespace: the only non-main branch rule is no-force-push, while CI/signature rules apply to main. Therefore repo location cannot stand in for an exact-head human authorization. Please enforce the trusted principal/approval independently in both coordinator and child before any PR checkout receives live credentials.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29123661854
Workflow ref: tmp/e2e/pr-6589-required-live-8e7b07f9
Requested targets: (default — all supported)
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 66 passed, 5 failed, 0 cancelled, 5 skipped

Job Result
agent-turn-latency ✅ success
bedrock-runtime-compatible-anthropic ✅ success
brave-search ✅ success
channels-add-remove ✅ success
channels-stop-start ✅ success
cloud-inference ✅ success
cloud-onboard ✅ success
common-egress-agent ✅ success
concurrent-gateway-ports ✅ success
credential-migration ✅ success
credential-sanitization ✅ success
cron-preflight-inference-local ✅ success
device-auth-health ✅ success
diagnostics ✅ success
docs-validation ✅ success
double-onboard ✅ success
full-e2e ❌ failure
gateway-drift-preflight ✅ success
gateway-guard-recovery ✅ success
gateway-health-honest ✅ success
generate-matrix ✅ success
gpu-double-onboard ✅ success
gpu-e2e ✅ success
hermes-dashboard ✅ success
hermes-discord ✅ success
hermes-e2e ✅ success
hermes-gpu-startup ⏭️ skipped
hermes-inference-switch ✅ success
hermes-shields-config ✅ success
hermes-slack ✅ success
inference-routing ✅ success
issue-2478-crash-loop-recovery ✅ success
issue-4434-tui-unreachable-inference ✅ success
issue-4462-scope-upgrade-approval ✅ success
jetson-nvmap-gpu ⏭️ skipped
kimi-inference-compat ✅ success
launchable-smoke ✅ success
live ✅ success
mcp-bridge ❌ failure
mcp-bridge-dev ⏭️ skipped
messaging-compatible-endpoint ✅ success
messaging-providers ✅ success
model-router-provider-routed-inference ✅ success
network-policy ✅ success
ollama-auth-proxy ✅ success
onboard-negative-paths ✅ success
onboard-repair ✅ success
onboard-resume ✅ success
openclaw-discord-pairing ✅ success
openclaw-inference-switch ✅ success
openclaw-plugin-runtime-exdev ✅ success
openclaw-skill-cli ✅ success
openclaw-slack-pairing ✅ success
openclaw-tui-chat-correlation ✅ success
openshell-gateway-auth-contract ⏭️ skipped
openshell-gateway-upgrade ✅ success
openshell-version-pin ✅ success
overlayfs-autofix ✅ success
rebuild-hermes ❌ failure
rebuild-hermes-stale-base ❌ failure
rebuild-openclaw ✅ success
sandbox-operations ❌ failure
sandbox-rebuild ✅ success
sandbox-rlimits-connect ⏭️ skipped
sandbox-survival ✅ success
security-posture ✅ success
sessions-agents-cli ✅ success
shields-config ✅ success
skill-agent ✅ success
snapshot-commands ✅ success
spark-install ✅ success
state-backup-restore ✅ success
telegram-injection ✅ success
token-rotation ✅ success
tunnel-lifecycle ✅ success
upgrade-stale-sandbox ✅ success

Explicit-only jobs skipped: openshell-gateway-auth-contract (default dispatch excludes the resource-heavy OpenShell auth-contract probe unless selected; validate with jobs=openshell-gateway-auth-contract or targets=openshell-gateway-auth-contract), mcp-bridge-dev (default dispatch excludes moving OpenShell dev artifacts unless explicitly selected; validate with jobs=mcp-bridge-dev or targets=mcp-bridge-dev), hermes-gpu-startup (default dispatch excludes this explicit-only job unless selected; validate with jobs=hermes-gpu-startup or targets=hermes-gpu-startup), sandbox-rlimits-connect (default dispatch excludes the destructive rlimit fork/connect probe unless selected; validate with jobs=sandbox-rlimits-connect or targets=sandbox-rlimits-connect), jetson-nvmap-gpu (default dispatch excludes Jetson; explicit dispatch requires allow_jetson_runner_queue=true after confirming an online Jetson runner because queued jobs do not honor timeout-minutes before assignment; validate with jobs=jetson-nvmap-gpu or targets=jetson-nvmap-gpu).

Failed jobs: full-e2e, mcp-bridge, rebuild-hermes, rebuild-hermes-stale-base, sandbox-operations. Check run artifacts for logs.

@cv

cv commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Superseded by #6662

@cv cv closed this Jul 10, 2026
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants