Skip to content

feat(e2e): classify hosted-runner resource pressure and infrastructure loss - #7168

Merged
cv merged 11 commits into
NVIDIA:mainfrom
souvikDevloper:feat/7146-runner-pressure-classification
Jul 19, 2026
Merged

feat(e2e): classify hosted-runner resource pressure and infrastructure loss#7168
cv merged 11 commits into
NVIDIA:mainfrom
souvikDevloper:feat/7146-runner-pressure-classification

Conversation

@souvikDevloper

@souvikDevloper souvikDevloper commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Maintainers need to distinguish deterministic E2E failures from process/container OOM kills, disk exhaustion, and hosted-runner loss without exposing workload-controlled data. This PR implements the #7146 runner-pressure evidence and retry contract on the existing #7101 Hermes phase-heartbeat path.

Fixes #7146

Changes

  • Collect bounded memory, cgroup, PSI, Docker, workspace, and inode evidence while emitting only numeric values and fixed ranks; process/container names and command payloads are excluded.
  • Validate canonical timestamps and strict baseline/classification record shapes.
  • Keep an immutable workflow baseline plus an append-only phase ledger, so cleanup sampled after an OOM cannot erase attribution to the failing phase.
  • Emit periodic resource snapshots from the canonical rebuild-Hermes progress reporter and wire both rebuild-hermes and rebuild-hermes-stale-base to produce, consume, validate, and upload terminal evidence.
  • Fail closed when terminal classification contradicts runner-loss evidence.
  • Permit only one confirmed runner-loss retry in the PR gate and link the original and retry run URLs for diagnosis.
  • Sort Docker consumers before limiting output and add mutation-based workflow-boundary coverage.

Verification

  • Runner-pressure, Hermes progress/timing, and workflow contracts: 97 tests passed.
  • PR E2E gate and watch-trigger contracts: 144 tests passed.
  • Full PR gate controller family: 139 tests passed before the current-main merge; conflict-focused rerun passed afterward.
  • CLI build and typecheck passed.
  • Source-shape, test-title, project-membership, Biome, YAML, secret scan, commit hooks, and pre-push hooks passed.
  • Both maintainer commits are signed and reported Verified by GitHub.

No user-facing command or configuration behavior changes; contributor documentation is not affected.

Signed-off-by: Souvik Ghosh 138186578+souvikDevloper@users.noreply.github.com

Summary by CodeRabbit

  • New Features

    • Added hosted-runner “resource pressure” evidence snapshots with bounded, secret-safe terminal failure classification.
    • Introduced pre-phase baselines to improve OOM attribution and phase-based evidence capture.
    • Implemented runner-loss detection with a single permissible retry and PR gate retry lineage linking.
    • Added a “live test outcome” artifact (none/assertion/timeout) integrated into classification and risk-signal reporting.
    • Extended the runner-pressure CLI and workflow boundary validation with fail-closed behavior.
  • Tests

    • Expanded end-to-end and contract coverage for snapshot/baseline/classification, CLI/subcommand fail-closed rules, retry policy, and workflow/PR gate lifecycle validation.

Host-memory snapshots that only read raw MemFree make healthy Linux page
cache look like exhaustion, and a hosted VM can disappear before logs
identify the cause, encouraging broad retries that hide deterministic
regressions. Add the trusted evidence contract that issue NVIDIA#7146 owns:

- tools/e2e/runner-pressure-core.mts: pure parsers for /proc/meminfo,
  loadavg, cgroup v2 scalars and memory.events, PSI, ps (comm and RSS
  only — never argv), docker stats, and docker system df; a bounded
  secret-safe E2E_RESOURCE_SNAPSHOT line built by an explicit
  field-by-field allowlist serializer that drops lists before scalars
  when over budget; a machine-readable terminal classification
  (assertion, timeout, process-oom, container-oom, disk-pressure,
  unknown) driven by positive evidence only, so low raw MemFree alone is
  never OOM; a hosted-runner-loss signature that requires the attempt to
  have produced no terminal classification; and a retry policy allowing
  at most one retry, only for confirmed runner loss.
- tools/e2e/runner-pressure.mts: fail-closed CLI (snapshot, classify,
  decide-retry) with validated env inputs and best-effort collectors, so
  the snapshot line still emits on hosts without cgroup v2 or Docker.
- test/e2e/support/runner-pressure.test.ts: covers each parser, the
  allowlist and length bound under adversarial input, every terminal
  classification including the acceptance criteria (assertion gets zero
  retries; runner loss retries exactly once and links attempts;
  ambiguous stays unknown), and the CLI through real subprocesses
  including the unsupported-subcommand guard.

The snapshot and classification lines are single prefixed records a
phase-heartbeat stream (NVIDIA#7101) can carry verbatim; this change defines
no second progress framework and no workflow wiring yet.

Refs NVIDIA#7146

Signed-off-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

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

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

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

Adds hosted-runner resource telemetry, bounded evidence artifacts, terminal failure classification, runner-loss retry decisions, trusted live-test outcomes, workflow validation, and PR gate retry lineage reporting.

Changes

Runner pressure handling

Layer / File(s) Summary
Evidence parsing and snapshot rendering
tools/e2e/runner-pressure-core.mts, tools/e2e/runner-pressure.mts, test/e2e/support/runner-pressure.test.ts
Parses host and container telemetry, collects resource snapshots, and renders bounded allowlisted evidence lines.
Failure classification and retry policy
tools/e2e/runner-pressure-core.mts, tools/e2e/runner-pressure.mts, test/e2e/support/runner-pressure.test.ts
Records OOM baselines, classifies terminal outcomes, validates CLI artifacts, detects runner loss, and permits at most one runner-loss retry.
Trusted live-test outcomes
tools/e2e/live-test-outcome.mts, test/e2e/risk-signal-reporter.ts, test/e2e/support/live-test-outcome-invocation.test.ts, test/e2e-risk-signal-reporter.test.ts
Writes strict live-test outcome artifacts and classifies trusted assertion and timeout results for terminal reporting.
Progress and workflow instrumentation
test/e2e/live/rebuild-hermes-progress.ts, .github/workflows/e2e.yaml, tools/e2e/runner-pressure-workflow-boundary.mts, tools/e2e/workflow-boundary.mts, test/e2e/support/*, test/helpers/vitest-watch-triggers.ts, test/vitest-watch-triggers.test.ts
Emits phase snapshots, records baselines, wraps rebuild tests with classification commands, and validates required workflow wiring.
PR gate retry lineage
tools/e2e/pr-e2e-gate.mts, test/pr-e2e-gate-lifecycle.test.ts
Integrates runner-loss retry decisions with check history and links original and retry attempts in gate summaries.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant E2EWorkflow
  participant RebuildHermesProgress
  participant RunnerPressureCLI
  participant RunnerPressureCore
  participant PRGate
  E2EWorkflow->>RunnerPressureCLI: capture snapshot and baseline
  RebuildHermesProgress->>RunnerPressureCLI: record phase baseline
  E2EWorkflow->>RunnerPressureCLI: classify failed test
  RunnerPressureCLI->>RunnerPressureCore: classify evidence and decide retry
  RunnerPressureCore-->>PRGate: retry decision
  PRGate->>PRGate: link prior runner-loss attempts
Loading

Possibly related issues

Possibly related PRs

Suggested labels: feature, area: e2e, area: observability, integration: hermes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.58% 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 matches the PR’s main change: hosted-runner resource-pressure classification and loss handling.
Linked Issues check ✅ Passed The changes cover bounded evidence capture, terminal classification, runner-loss retry policy, and related tests required by #7146.
Out of Scope Changes check ✅ Passed No unrelated scope creep stands out; the added modules and tests all support the runner-pressure and retry workflow.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / high confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: No actionable findings remain in the canonical review ledger.

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 E2E selections differ; severity counts match.

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-onboard, credential-sanitization, security-posture

2 optional E2E recommendations
  • rebuild-hermes
  • rebuild-hermes-stale-base

Workflow run details

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

@souvikDevloper

Copy link
Copy Markdown
Contributor Author

@cv can i get the ci now

@apurvvkumaria apurvvkumaria self-assigned this Jul 19, 2026
@souvikDevloper

Copy link
Copy Markdown
Contributor Author

@apurvvkumaria hey can u take a look over the fix

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

Reviewed exact head 7f1d8fff04943f1beffa07b340e33b01af9b33e8. The focused suite passes 36/36, but the current change does not yet satisfy #7146's functional and secret-safety boundaries:

  1. The implementation is inert. No canonical workflow, heartbeat, reporter, or gate invokes runner-pressure.mts, consumes either evidence prefix, rejects missing/malformed terminal evidence, or links a single runner-loss retry. #7146 explicitly requires representative heavy lanes to emit this evidence and the retry to preserve/link both attempts. Please wire the smallest canonical path and add a workflow-boundary test.

  2. The claimed secret-safe serializer emits workload-controlled topProcesses[].comm and containers[].name verbatim. Both can contain credential material. snapshot.at is also copied without shape/length validation, so renderSnapshotLine() can leak arbitrary input and exceed its stated bound. Remove workload-controlled identifiers from logged evidence (numeric PID/container rank or another non-secret identity is safer), validate the timestamp as canonical bounded data, and add adversarial token-shaped tests.

  3. decideRetry({ runnerLoss: true, classification: "assertion", attempt: 1 }) currently returns retry: true, contradicting the invariant that classified assertions/OOM/disk/timeouts are never retried. Fail closed whenever a terminal classification is present, even if the runner-loss flag is also true, and cover contradictory inputs.

  4. OOM counters and kernel-log matches are treated as absolute booleans/counters rather than deltas from a pre-phase baseline, so an earlier OOM can misclassify an unrelated later failure. Also, parseDockerStats stops at the first five rows instead of selecting the largest consumers. Capture/compare baselines and sort before limiting so the attribution is actually phase-specific and reports the largest consumers required by #7146.

Please keep the integration on the existing #7101 heartbeat/control-plane path rather than creating a parallel retry loop.

apurvvkumaria and others added 2 commits July 19, 2026 00:03
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

@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

🤖 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 `@test/e2e/support/runner-pressure.test.ts`:
- Around line 599-609: Update the runHelper invocation in the strict pre-phase
baseline test to explicitly unset or override DOCKER_OOM_CONTAINER in the
spawned environment, while preserving the existing E2E_PHASE value and
deterministic containerOomKilled: false assertion.
🪄 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: a1e0e6da-cb98-47ac-9bb9-88ccf2566129

📥 Commits

Reviewing files that changed from the base of the PR and between 7f1d8ff and 5509f52.

📒 Files selected for processing (13)
  • .github/workflows/e2e.yaml
  • test/e2e/live/rebuild-hermes-progress.ts
  • test/e2e/support/rebuild-hermes-progress.test.ts
  • test/e2e/support/runner-pressure-workflow-boundary.test.ts
  • test/e2e/support/runner-pressure.test.ts
  • test/helpers/vitest-watch-triggers.ts
  • test/pr-e2e-gate-lifecycle.test.ts
  • test/vitest-watch-triggers.test.ts
  • tools/e2e/pr-e2e-gate.mts
  • tools/e2e/runner-pressure-core.mts
  • tools/e2e/runner-pressure-workflow-boundary.mts
  • tools/e2e/runner-pressure.mts
  • tools/e2e/workflow-boundary.mts

Comment thread test/e2e/support/runner-pressure.test.ts
apurvvkumaria and others added 3 commits July 19, 2026 00:54
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

@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

🤖 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 `@test/e2e/support/live-test-outcome-invocation.test.ts`:
- Around line 46-84: Add a per-call timeout below the 30-second Vitest limit to
both the `spawnSync` invocation running Vitest and the one running `CLASSIFIER`,
preserving their existing options and ensuring hung child processes fail fast.
🪄 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: c47195da-3635-4727-973e-7010b4a4bad0

📥 Commits

Reviewing files that changed from the base of the PR and between afda9f1 and ebeaa84.

📒 Files selected for processing (10)
  • .github/workflows/e2e.yaml
  • test/e2e-risk-signal-reporter.test.ts
  • test/e2e/risk-signal-reporter.ts
  • test/e2e/support/fixtures/live-test-outcome.fixture.test.ts
  • test/e2e/support/live-test-outcome-invocation.test.ts
  • test/e2e/support/runner-pressure-workflow-boundary.test.ts
  • test/e2e/support/runner-pressure.test.ts
  • tools/e2e/live-test-outcome.mts
  • tools/e2e/runner-pressure-workflow-boundary.mts
  • tools/e2e/runner-pressure.mts
🚧 Files skipped from review as they are similar to previous changes (4)
  • .github/workflows/e2e.yaml
  • test/e2e/support/runner-pressure.test.ts
  • tools/e2e/runner-pressure-workflow-boundary.mts
  • tools/e2e/runner-pressure.mts

Comment thread test/e2e/support/live-test-outcome-invocation.test.ts
apurvvkumaria and others added 3 commits July 19, 2026 01:33
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Addressed exact-head advisor blocker PRA-1 in f1b11101b. finishPrGate now derives verified runner-loss evidence from trusted GitHub Jobs API metadata: the workflow job is terminal and failed on a GitHub-hosted runner while exactly one step remains stranded in_progress, with no failed/cancelled terminal step. Ordinary failed jobs suppress the infrastructure retry, cancellation alone remains non-retryable, and the existing history guard still limits the positive case to one retry. Validation: all 10 PR-gate test files pass (142/142), focused lifecycle coverage passes (26/26), CLI typecheck and commit/push hooks pass; the commit is signed and GitHub-Verified.

Create and consume runner evidence through no-follow, single-link descriptors.

Reject symlink and hardlink redirection during PR-controlled live tests.

Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria
apurvvkumaria dismissed their stale review July 19, 2026 10:46

Superseded by exact head a5209a3. The current revision wires the canonical heartbeat/gate path, removes workload-controlled identifiers, validates timestamps, fails closed on contradictory retry evidence, uses phase-local OOM deltas and sorted consumers, and now protects evidence files against link substitution. Focused tests and CLI type-checking pass.

Select link creators from a fixed map so the security fixture adds no test conditional.

Co-authored-by: Souvik Ghosh <138186578+souvikDevloper@users.noreply.github.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

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

Reviewed exact head 04e7e87 against current base 78e0e4e. The prior integration, secret-safety, fail-closed retry, phase-baseline, and evidence-file blockers are addressed: snapshots expose only bounded numeric/rank data, terminal classifications override runner-loss claims, OOM attribution uses monotonic phase deltas, runner loss requires a trusted hosted-runner marker and receives at most one linked retry, and evidence files reject symlink/hardlink substitution. Current-head CI, security scans, advisors, protected E2E, and all review threads are green. I also re-audited the workflow wiring and controller retry history at this revision; no blocking issue found.

@cv
cv merged commit 73fc914 into NVIDIA:main Jul 19, 2026
42 checks passed
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure feature PR adds or expands user-visible functionality labels Jul 29, 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 feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci(e2e): classify hosted-runner resource pressure and infrastructure loss

4 participants