Skip to content

ci(e2e): stop waiting for managed image completion - #9556

Merged
prekshivyas merged 3 commits into
mainfrom
codex/issue-9549-base-publication-gate
Aug 19, 2026
Merged

ci(e2e): stop waiting for managed image completion#9556
prekshivyas merged 3 commits into
mainfrom
codex/issue-9549-base-publication-gate

Conversation

@rsliter

@rsliter rsliter commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

The base image publication gate previously waited for overall workflow completion even though it consumed only base publisher evidence. It now verifies the three current-attempt publishers as soon as they finish, removing a measured median 26m 35s downstream wait while preserving exact SHA, attempt, and artifact checks.

Related Issue

Fixes #9549

Changes

  • Select the trusted base image workflow run without using whole-workflow completion as publication evidence.
  • Classify the three required publisher jobs in the selected attempt as pending, successful, or failed.
  • Recheck the selected run identity before exporting its artifact coordinates.
  • Accept valid base evidence when unrelated managed-image or Pi work remains active, fails, or is cancelled.
  • Add deterministic tests for pending publishers, attempt mixing, required publisher failures, and unrelated downstream states.

Type of Change

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

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior
  • Tests not applicable
  • Docs updated for user-facing behavior changes
  • Docs not applicable: this changes an internal GitHub Actions qualification gate, not a public CLI, configuration, or supported user workflow.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed: the implementation review preserved repository, SHA, first-parent, run, attempt, job, and artifact trust boundaries. Current-attempt negative tests cover stale evidence and required publisher failures. No credential scope or workflow permission changed.
  • Non-success, skipped, or missing CI check accepted by maintainer

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: The change affects internal E2E qualification behavior only. It does not change a public user surface.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed
  • Targeted behavior tests pass: npx vitest run --project e2e-support test/e2e/support/base-image-publication.test.ts test/e2e/support/base-image-publication-workflow-boundary.test.ts passed 87 tests.
  • Applicable broad gate passed: not required for this focused verifier change. The complete local E2E-support project passed 2,998 tests; four host-specific fixture tests require Linux systemctl or GNU find and could not pass on macOS.
  • Quality Gates section completed with required justifications
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Rebecca Sliter 571084+rsliter@users.noreply.github.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved base-image publication validation for in-progress and completed workflow runs.
    • Publisher checks now correctly track the selected workflow attempt and prevent successful results from previous attempts being reused.
    • Failed or skipped required publishers are rejected, while incomplete publishers remain pending until the selected run finishes.
    • Improved polling behavior and timeout handling when unrelated image jobs are active or unsuccessful.

@rsliter rsliter self-assigned this Aug 19, 2026
@github-code-quality

github-code-quality Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit f73419f in the codex/issue-9549-bas... branch remains at 96%, unchanged from commit 7afe395 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit f73419f in the codex/issue-9549-bas... branch remains at 82%, unchanged from commit 7afe395 in the main branch.

Show a code coverage summary of the most impacted files.
File main 7afe395 codex/issue-9549-bas... f73419f +/-
src/lib/actions...e-classifier.ts 63% 58% -5%
src/lib/onboard...ce-lifecycle.ts 93% 89% -4%
src/lib/onboard...uild-context.ts 86% 86% 0%
src/lib/onboard...x-containers.ts 82% 82% 0%
src/lib/onboard...-transaction.ts 94% 94% 0%
src/lib/sandbox...rce-identity.ts 81% 81% 0%
src/lib/state/r...ime-snapshot.ts 100% 100% 0%
src/lib/shields...nsition-lock.ts 84% 85% +1%
src/lib/actions...aged-profile.ts 84% 88% +4%
src/lib/actions...er-lifecycle.ts 85% 94% +9%

Updated August 19, 2026 04:20 UTC

@coderabbitai

coderabbitai Bot commented Aug 19, 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: 72bc4222-a707-4a45-8875-b4dd0f4ac4ff

📥 Commits

Reviewing files that changed from the base of the PR and between d7f8623 and 1b9748b.

📒 Files selected for processing (2)
  • test/e2e/support/base-image-publication.test.ts
  • tools/e2e/base-image-publication.mts

Included review availability: Your plan provides up to 12 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The publication gate now selects matching workflow runs without waiting for overall completion. It validates required publisher jobs from the selected run attempt, polls until they are ready, and ignores unrelated downstream job completion.

Changes

Base publication gate

Layer / File(s) Summary
Selected run state
tools/e2e/base-image-publication.mts, test/e2e/support/base-image-publication.test.ts
Publication selection now returns selected for matching runs, including in-progress, failed, cancelled, or missing-conclusion cases.
Attempt-scoped publisher validation
tools/e2e/base-image-publication.mts, test/e2e/support/base-image-publication.test.ts
Publisher validation checks required jobs from the selected run attempt. Incomplete jobs remain pending for active runs. Failed, cancelled, skipped, missing, or prior-attempt jobs do not satisfy validation.
Readiness polling and coverage
tools/e2e/base-image-publication.mts, test/e2e/support/base-image-publication.test.ts
The wait loop polls the selected run’s attempt-specific job history and verifies the bound run only after publisher readiness. Tests cover unrelated downstream jobs remaining active or ending unsuccessfully.

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

Merge Risk: ⚪ Minimal · up to 1b974

The change shortens the base-image publication wait while retaining SHA, attempt, publisher, and artifact validation. No actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant E2EGate
  participant WorkflowRun
  participant PublisherJobs
  E2EGate->>WorkflowRun: select matching publication run
  E2EGate->>PublisherJobs: retrieve jobs for selected attempt
  PublisherJobs-->>E2EGate: return required publisher statuses
  E2EGate->>WorkflowRun: verify bound run after publishers are ready
  E2EGate-->>E2EGate: release E2E fanout
Loading

Possibly related PRs

  • NVIDIA/NemoClaw#9484: Updates E2E base-image workflow-run and attempt-scoped publisher validation.

Suggested labels: bug-fix

Suggested reviewers: cv, brandonpelfrey, dnandakumar-nv

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: the E2E gate no longer waits for managed-image workflow completion.
Linked Issues check ✅ Passed The implementation meets issue #9549 by using current-attempt publisher evidence, preserving contract checks, and allowing unrelated downstream work to continue.
Out of Scope Changes check ✅ Passed The changes are limited to the publication gate and its deterministic tests, with no unrelated scope expansion.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-9549-base-publication-gate

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

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

LOC Reduction / Codebase Simplicity Review

Why this blocks

The implementation loads every job from every run attempt and then creates a second attempt-selection authority inside validatePublisherJobs. At tools/e2e/base-image-publication.mts:450, it stores arrays of occurrences per publisher, carries each occurrence’s attempt, detects duplicates per attempt, and later searches those arrays for the selected attempt. This machinery exists only because waitForBaseImagePublication requests /actions/runs/{id}/jobs?filter=all at line 640.

GitHub already provides an attempt-scoped jobs endpoint, and this repository already uses it in tools/e2e/native-runtime-qualification-collector.mts and tools/e2e/hosted-runner-loss-github.mts. Asking for the selected attempt directly preserves the required trust boundary without maintaining a parallel in-memory history registry. It also prevents irrelevant prior-attempt job records from participating in this gate.

Refactor direction

Request /actions/runs/${run.id}/attempts/${run.attempt}/jobs?per_page=100, following the existing qualification pattern.

Then simplify validatePublisherJobs to retain at most one current-attempt record per required publisher name. Require each retained job’s run_id, run_attempt, and head_sha to match the selected run, reject duplicate required names, and classify only those three jobs as pending, successful, or failed. Keep the final bound-run recheck and exact artifact validation unchanged.

Expected result

The #9549 readiness behavior and fail-closed attempt binding remain intact, while the all-attempt registry, occurrence arrays, attempt searches, and associated fixtures disappear. The verifier has one attempt authority—the selected GitHub run attempt—and the production change becomes smaller.

@senthilr-nv senthilr-nv added chore Build, CI, dependency, or tooling maintenance area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure v0.0.111 labels Aug 19, 2026
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas

Copy link
Copy Markdown
Collaborator

Pushed signed follow-up 1b9748bfcbbe3494d687107b4b552aa17e27f458 after exact PR-head and branch-ref guards on d7f8623be673ea56f48d6538a2020927edf1d580.

The verifier now requests GitHub's attempt-scoped jobs endpoint for the selected run attempt. validatePublisherJobs retains one current-attempt record per required publisher and still fails closed on mismatched run ID, run attempt, head SHA, duplicate required names, invalid terminal/pending states, missing terminal publishers, or failed/skipped publishers. The final bound-run recheck and exact artifact validation remain unchanged.

The follow-up removes the all-attempt occurrence registry (20 additions / 45 deletions).

Validation:

  • focused publication + workflow-boundary suites: 86/86 passed
  • growth guardrails: 32/32 passed
  • npm run checks:repository
  • npm run typecheck:cli
  • npm run validate:pr

Fresh CI/advisor checks are now running on the exact new head.

@jyaunches
jyaunches dismissed their stale review August 19, 2026 03:11

Resolved by 1b9748b: the verifier now uses the attempt-scoped jobs endpoint and removes the all-attempt occurrence registry.

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

LOC Reduction / Codebase Simplicity Review

Resolved

The attempt-selection blocker is resolved at 1b9748bfcbbe3494d687107b4b552aa17e27f458.

The verifier now requests the selected run's attempt-scoped jobs endpoint. validatePublisherJobs retains only one current-attempt record per required publisher and preserves the exact run ID, run attempt, head SHA, duplicate-name, pending, and failure checks. The all-attempt occurrence registry and its search machinery are gone.

The follow-up adds 20 lines and removes 45, for a net reduction of 25 lines. The final bound-run recheck and exact artifact validation remain unchanged, and I found no replacement LOC or codebase-simplicity blocker.

This resolves only the prior LOC reduction and codebase-simplicity finding. It is not an approval or a judgment on other review dimensions.

@udsy19

udsy19 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Outside contributor here, not a maintainer — no decision implied. The only human review on this thread was scoped to LOC reduction and explicitly did not judge other dimensions, so I spent an hour on the one property that seemed worth an independent pair of eyes: whether dropping whole-run completion as evidence leaves the gate fail-closed. As far as I can tell it does. Details below in case they save someone else the trace.

Fail-closed matrix

I transcribed validatePublisherJobs from head 1b9748b (tools/e2e/base-image-publication.mts:440-512) and drove it over the terminal and in-flight combinations rather than reading it:

selected run required publishers result
completed / success all three success ready
completed / failure all three success ready
completed / cancelled all three success ready
in progress all three success ready
in progress one still running pending
in progress one absent from the listing pending
in progress one concluded failure throws
in progress one concluded skipped throws
completed / cancelled one absent from the listing throws
completed / cancelled one still running throws
completed / cancelled one concluded cancelled throws
any job carries a different run_attempt throws
any a required name appears twice throws
completed / failure all three success, unrelated job failed ready

Every accept path requires all three required jobs completed + success in the selected attempt on the selected run and SHA. The three intended acceptances — a terminal run that concluded non-success, an in-flight run, and unrelated managed-image work in any state — are the only ways evidence is admitted without whole-run success, and each still carries the full per-job provenance check at :455.

The skipped case is the one I most expected to leak, since skipped is a member of COMPLETED_CONCLUSIONS. It does not: :505 compares against success specifically, outside the run.status guard.

The question the refactor raises, and why I think it is fine

run.status is now load-bearing — it decides whether an absent or incomplete publisher is a hard failure or just pending (:488, :497). But that value comes from the workflow-runs listing fetched at the top of the poll iteration, while the jobs listing is a later request. So a run can terminate between the two, leaving a stale in_progress alongside final job data.

Tracing it through, that race only ever costs a poll interval, never correctness:

  • a required job that concluded non-success throws at :505 regardless of run.status, because that branch is not inside the terminal guard;
  • an absent or still-running job with a stale in_progress returns pending, and the next iteration re-reads the runs listing, sees completed, and throws.

So the worst case is one extra 30s poll before the accurate error, not an acceptance. Worth stating somewhere, because "why is it safe to judge terminality from an earlier response?" is the first thing a later reader will ask.

Small note

Three of the throw sites this change introduces have no assertion behind them: publisher job … status is invalid (:463-465), … conclusion is invalid (:469-471), and … pending state is invalid (:473-475). The table test at test/e2e/support/base-image-publication.test.ts:642-665 covers missing, duplicated, failed, and wrong-run, and the two new focused cases cover pending-vs-terminal, so the behavioural surface is well covered — these three are malformed-payload guards rather than behaviour, and given how hard this repo pushes on test size I would not add cases for them without a maintainer asking. Flagging only so the omission is a choice rather than an oversight.

What I did not check

I did not run the test suite, type-check, build, or trigger any workflow, and I have no way to exercise the real GitHub endpoints. The matrix above comes from a hand-transcribed copy of the function executed under plain node, not from importing the module, so treat it as a reading aid rather than a test result. I also did not evaluate the pagination or retry layers, which this change leaves alone.

Nice result on the 26-minute saving — the attempt-scoped endpoint reads much more clearly than the all-attempts registry it replaces.

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections match; severity counts match.
7 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • terminal attempt at tools/e2e/base-image-publication.mts:499: primary classified it as replace; the second opinion classified it as define.
  • selected attempt at test/e2e/support/base-image-publication.test.ts:563: primary classified it as justified; the second opinion classified it as define.
  • required publisher at test/e2e/support/base-image-publication.test.ts:579: selected only by the second-opinion lane as established.
  • selected run at test/e2e/support/base-image-publication.test.ts:579: selected only by the second-opinion lane as established.
  • publisher validation at test/e2e/support/base-image-publication.test.ts:525: selected only by the second-opinion lane as define.
  • unrelated downstream at test/e2e/support/base-image-publication.test.ts:742: selected only by the second-opinion lane as define.
  • pending at tools/e2e/base-image-publication.mts:440: selected only by the second-opinion lane as replace.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • justified — selected attempt at test/e2e/support/base-image-publication.test.ts:563: Keep “selected attempt” where attempt provenance distinguishes it from earlier workflow attempts.
  • replace — terminal attempt at tools/e2e/base-image-publication.mts:499: Replace “terminal attempt” with “completed workflow run” or state that the selected run is completed.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

Manual-only E2E: cloud-onboard, security-posture, cloud-inference
The manual PR workflow does not run these selectors for the commit under review. Run them from reviewed code on main.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

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

Approved exact head f73419f9ef08ea8f10d1660702ecf15c201f320a. The gate now selects the matching base-image publication run without waiting for unrelated downstream completion, while validating required publisher jobs against the selected run attempt. The attempt-scoped jobs endpoint and current-attempt registry close the prior-attempt ambiguity. All commits are GitHub Verified, all review threads are resolved, CodeRabbit and both advisor lanes are clean, and the complete current check suite is green after the unrelated installer test rerun passed.

@prekshivyas
prekshivyas merged commit db93b2e into main Aug 19, 2026
70 of 72 checks passed
@prekshivyas
prekshivyas deleted the codex/issue-9549-base-publication-gate branch August 19, 2026 04:42
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci(e2e): stop waiting for unrelated managed-image completion

5 participants