Skip to content

Improvements to payload agent - #511

Merged
openshift-merge-bot[bot] merged 27 commits into
openshift-eng:mainfrom
not-stbenjam:snapshot-payload
Jun 3, 2026
Merged

openshift-merge-bot[bot] merged 27 commits into
openshift-eng:mainfrom
not-stbenjam:snapshot-payload

Conversation

@stbenjam

@stbenjam stbenjam commented Jun 1, 2026

Copy link
Copy Markdown
Member

Introduces agent-eval-harness for systematic evaluation of the Payload Agent with reproducible test cases and multi-judge scoring. Restructures the analyze-payload skill to separate deterministic data collection (snapshot creation) from AI-driven analysis.

I will remove the "payload-anaylze" command once this merges and I validate the openshift/release side.

Key changes:

  • Add snapshot-based approach: pre-collect all payload data (metadata,
    JUnit, logs, PRs, Sippy regressions) into hermetic archives before
    analysis, eliminating non-deterministic data fetching during agent runs (primary driver of cost reduction)
  • Build 12+ test cases covering single/multi-component reverts, mixed
    regressions, false positives, and rejection streaks with annotated
    expected outcomes
  • Implement multi-judge evaluation: deterministic judges (YAML/JSON schema,
    required file generation) + LLM judges (analysis quality, revert scoring)

Results from 117 evaluation runs:

  • Cost: 64% reduction per payload (avg $6.68 → $2.41 on Opus 4.6)
  • Quality: analysis improved 4.21 → 4.46/5, HTML structure 57% → 83%
  • Reliability: enforced skill invocation compliance (98%+ vs previous
    ad-hoc hallucination of output formats)

Summary by CodeRabbit

  • New Features

    • Added ci:payload-analysis command for comprehensive payload failure analysis
    • Introduced payload-snapshot skill for downloading and analyzing OpenShift payload data offline
  • Documentation

    • Added complete documentation for payload analysis and snapshot workflows
    • Updated command references across documentation to reflect new command structure
  • Chores

    • Bumped CI plugin version to 0.0.46
    • Added 13 new evaluation test cases for payload analysis validation
    • Introduced payload results JSON and YAML validators

stbenjam and others added 9 commits May 31, 2026 10:20
Adds a script that downloads all data needed to analyze an OpenShift
payload into a local directory tree: release controller data, PR diffs,
comments, CI jobs, JUnit test results, and regression tracking.

Features:
- Chains backwards through payloads to find last all-green baseline
- Splits jobs into blocking/informing directories with metadata
- Downloads and parses JUnit XML for failed blocking jobs
- Tracks test failure regressions across the payload chain
- Generates summary.json and summary.md roll-up at stream level
- Falls back to git clone for large PR diffs that exceed GitHub API limits
- Idempotent: re-running skips existing files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…AGENTS.md

Add comprehensive data extraction so summary.json can answer 90% of
payload agent questions without live API calls:

- GCS browser URLs in job.json and summary for direct artifact access
- BuildLogCollector: download build-log.txt from GCS (handles gzip),
  extract error/warning lines and last 20% of log
- JobStreakTracker: per-job consecutive failure count, originating
  payload, and failure pattern (e.g. "F F F F F S") across the chain
- Expanded summary.json: architecture, stream, version, release_url,
  hours_since_baseline, failed_jobs as detailed objects with streaks,
  build-log error counts, test failure counts, and file paths
- Remove failure_text truncation in regressions (was [:500])
- Generate dynamic AGENTS.md + CLAUDE.md in snapshot output directory
  so any agent opening the directory gets instant orientation
- Drop summary.md (JSON is more useful to LLMs than markdown tables)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update documentation to reflect new capabilities: GCS browser URLs,
build-log extraction, per-job failure streaks, comprehensive
summary.json schema, and dynamic AGENTS.md/CLAUDE.md generation.
Remove references to dropped summary.md. Bump version to 0.0.45.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename skill directory and script to payload-snapshot for consistency.
Move script into scripts/ subdirectory per convention. Update all
path references in SKILL.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the analyze-payload skill and command with payload-analysis,
which reads from a local payload-snapshot instead of making live API
calls. This enables:

- Time-travel replay: re-analyze historical payloads against frozen data
- Model accessibility: less capable models skip multi-skill data gathering
- Reproducibility: same snapshot always produces consistent analysis

The new skill adds an adversarial review step (Step 9) that launches a
dedicated subagent to check conclusions for weak correlations,
infrastructure misattribution, and score inflation before finalizing
the report.

Update all cross-references in payload-revert, payload-experiment,
payload-results-yaml, payload-autodl-json, stage-payload-reverts,
and payload-snapshot. Delete old analyze-payload skill and command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…orrection

Add evaluation infrastructure for the payload-analysis skill with 6 judges
(4 deterministic schema checks, 2 LLM quality judges) and 1 test case based
on the 5.0.0-0.nightly-2026-05-30-072431 payload.

Fix Step 9 adversarial review to act as a methodology reviewer rather than
a score overrider — it now validates investigation depth and skill usage
without lowering rubric-based confidence scores backed by concrete evidence.
This fixes a false negative where the reviewer incorrectly lowered
origin#31006 from 100→70, dropping it below the 85 revert threshold.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add SippyClient and SippyPayloadChain to payload_snapshot.py for
creating snapshots of historical payloads pruned from the release
controller. Sippy provides job runs, changelog diffs, and tag metadata.

Extend JUnit and build-log collection to include failed informing jobs
(target payload only) so install-analysis-all failures can be traced
through their underlying informing jobs.

Add 13 prioritized eval cases covering revert detection, false positive
rejection, CI config issues, streak detection, and infrastructure
classification. Cases are numbered by value — case-001 tests the most
complex scenario (CI config change from openshift/release + product
regression). Add runner.system_prompt for date-pinning external queries.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add required_skill_invocations judge that parses JSONL transcripts to
verify ci:payload-results-yaml and ci:payload-autodl-json are invoked
via the Skill tool. Align runner.system_prompt with CI production prompt
to enforce skill loading before analysis and mandate use of output
formatting skills.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…path

Remove <details> check from html_report_structure judge — not useful
enough to enforce. Change snapshot extraction from /tmp to .work/ to
avoid filling tmpfs during parallel eval runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci
openshift-ci Bot requested review from cblecker and jogeo June 1, 2026 13:49
@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 1, 2026
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

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

This PR introduces a complete OpenShift CI payload-analysis feature, including a new CLI command, skill implementation for downloading and analyzing payload data offline, a comprehensive evaluation framework with 13 test cases, and validators for structured output formats (YAML/JSON).

Changes

Payload Analysis Feature Implementation

Layer / File(s) Summary
Plugin version and manifest updates
.claude-plugin/marketplace.json, plugins/ci/.claude-plugin/plugin.json
Version bumped from 0.0.42 to 0.0.46 across CI plugin manifests.
Payload-analysis command and skill documentation
plugins/ci/commands/payload-analysis.md, plugins/ci/skills/payload-analysis/SKILL.md
New CLI command definition with workflow steps and usage examples; comprehensive skill documentation covering prerequisites, argument parsing, snapshot handling, parallel job investigation, revert/force-accept decision logic, report generation, error handling, and structured return formats.
Payload-snapshot skill and Python implementation
plugins/ci/skills/payload-snapshot/SKILL.md, plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py
Skill documentation and 2,154-line Python module implementing payload chain building (walking backward to all-green baseline), data collection (payloads, PRs, jobs, JUnit tests, build logs) via ReleaseController/Sippy APIs, regression tracking, job streak analysis, and summary generation for offline analysis.
Evaluation framework with 13 test cases
plugins/ci/evals/eval-payload-analysis.yaml, plugins/ci/evals/cases/payload-analysis/*
Evaluation config defining test case execution, dataset schema, expected outputs (HTML/YAML/JSON), and LLM judges validating file existence, YAML/JSON structure, HTML report quality, skill invocations, and analysis/scoring accuracy. Thirteen annotated cases cover nightly/CI payloads, rejection streaks, false positives, and multi-revert scenarios with expected outcomes and confidence thresholds.
Snapshot extraction utility
plugins/ci/evals/scripts/extract-payload-analysis-snapshots.sh
Bash script for extracting and caching tar.gz archives during eval runs, with idempotent re-run support and tag-based filtering.
Output validators and test data
plugins/ci/skills/payload-*-json/scripts/validate.py, plugins/ci/skills/payload-results-yaml/scripts/validate.py, plugins/ci/skills/payload-*/scripts/test_validate.py, plugins/ci/skills/payload-*/scripts/testdata/*
Python validators enforcing required fields and structure for payload-results-*.yaml (metadata, failing_jobs, candidates) and *-autodl.json (table_name, schema, rows with string values). Includes test runners and comprehensive fixtures (valid cases, missing fields, empty rows, type errors, malformed syntax).
Related skill and command documentation updates
plugins/ci/commands/payload-experiment.md, plugins/ci/commands/payload-revert.md, plugins/ci/skills/payload-autodl-json/SKILL.md, plugins/ci/skills/payload-results-yaml/SKILL.md, plugins/ci/skills/stage-payload-reverts/SKILL.md
Consistent renaming from /ci:analyze-payload to /ci:payload-analysis across dependent command/skill docs; addition of force_accept_recommended field documentation.
Plugin registry updates
docs/index.html
Version update to 0.0.46, new ci:payload-analysis command registration, new payload-analysis and payload-snapshot skill definitions, and population of standalone skills list (dotenv, dotenvx, playwright-cli, playwright-trace).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • openshift-eng/ai-helpers#464: Introduces the behavioral eval framework (Makefile and .github/workflows/eval-plugins.yml) that runs the new payload-analysis eval config and cases added in this PR.
  • openshift-eng/ai-helpers#356: Updates existing payload-analysis workflow documentation and introduces failure_pattern field; directly related to the payload-analysis feature being formalized and renamed in this PR.
  • openshift-eng/ai-helpers#384: Restructures stage-payload-reverts skill with Jira MCP preflight; overlaps on stage-payload-reverts skill documentation updates and payload-analysis integration.

Suggested labels

lgtm

Suggested reviewers

  • cblecker
  • rvanderp3

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
No Assumed Git Remote Names ❌ Error Found hardcoded git remote name 'origin' in payload_snapshot.py line 594 within _git_diff_fallback() method used for PR diff cloning, without first discovering available remotes via 'git remote -v'. Replace git fetch "origin" with discovered remote name or use 'git fetch' without specifying remote (uses upstream by default for cloned repos).
Docstring Coverage ⚠️ Warning Docstring coverage is 58.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title "Improvements to payload agent" refers to real changes (new payload-analysis skill, snapshot-based approach, evaluation harness) but is vague and overly broad, not clearly summarizing the main technical change. Consider a more specific title like "Add payload-analysis skill with snapshot-based evaluation" or "Restructure payload analysis with deterministic snapshots and eval harness" to better convey the primary architectural change.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
No Real People Names In Style References ✅ Passed No real people names found as style references. Only "GitHub-inspired" (a company, not a person) appears in the PR documentation.
Git Push Safety Rules ✅ Passed No git push operations found in CI plugin code. All git operations are read-only (clone, fetch, diff, merge-base). No force push or push to main/master found.
No Untrusted Mcp Servers ✅ Passed PR introduces no MCP server installations from untrusted sources. New code (payload_snapshot.py, validators) uses only Python standard library; no external package dependencies added.
Ai-Helpers Overlap Detection ✅ Passed PR intentionally refactors analyze-payload into payload-snapshot + payload-analysis to separate data collection from analysis. High similarity is expected, not problematic overlap.
✨ 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: 6

🧹 Nitpick comments (3)
plugins/ci/commands/payload-revert.md (1)

39-42: 💤 Low value

Consider adding a language specifier to the fenced code block.

The error message block could specify a language (e.g., text) to satisfy the markdownlint rule and improve consistency.

📝 Proposed fix
-   ```
+   ```text
    Error: Payload results YAML not found for {payload_tag}.
    Run `/ci:payload-analysis {payload_tag}` first to generate it.
    ```
🤖 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 `@plugins/ci/commands/payload-revert.md` around lines 39 - 42, Add a language
specifier to the fenced code block containing the error message "Error: Payload
results YAML not found for {payload_tag}." so it becomes a code fence like
```text; update the opening backticks for the block that includes the "Error:
Payload results YAML not found for {payload_tag}." and the "Run
`/ci:payload-analysis {payload_tag}` first to generate it." line to satisfy
markdownlint and improve consistency.
plugins/ci/evals/cases/payload-analysis/case-013-4.20-accepted-with-failures/annotations.yaml (1)

1-11: 💤 Low value

Consider adding expected_candidates field for consistency.

This annotations file omits the expected_candidates field, while case-011 includes it explicitly as an empty array. Since has_revert_candidates: false, the expected behavior is the same, but explicit presence improves consistency across test cases and may prevent evaluation framework issues if this field is expected.

📝 Suggested addition for consistency
 has_revert_candidates: false
 force_accept_expected: false
+expected_candidates: []
+
 notes: >
🤖 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
`@plugins/ci/evals/cases/payload-analysis/case-013-4.20-accepted-with-failures/annotations.yaml`
around lines 1 - 11, Add an explicit expected_candidates field to the
annotations YAML (e.g., expected_candidates: []) to mirror case-011 and ensure
consistency with has_revert_candidates: false; update the top-level fields in
the same document where expected_phase, expected_failed_job_count, and
has_revert_candidates are declared so the evaluation framework sees an empty
array for expected_candidates rather than omitting the key.
plugins/ci/evals/cases/payload-analysis/case-012-4.20-rejected-streak/annotations.yaml (1)

1-12: 💤 Low value

Consider adding expected_candidates field for consistency.

This annotations file omits the expected_candidates field, while case-011 includes it explicitly as an empty array. Since has_revert_candidates: false, the expected behavior is the same, but explicit presence improves consistency across test cases and may prevent evaluation framework issues if this field is expected.

📝 Suggested addition for consistency
 has_revert_candidates: false
 force_accept_expected: false
+expected_candidates: []
+
 notes: >
🤖 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
`@plugins/ci/evals/cases/payload-analysis/case-012-4.20-rejected-streak/annotations.yaml`
around lines 1 - 12, Add an explicit expected_candidates field to the
annotations so the file consistently declares expected revert candidates; since
has_revert_candidates is false, set expected_candidates to an empty array
(expected_candidates: []). Update the top-level keys (e.g., alongside
expected_phase, expected_failed_job_count, has_revert_candidates) so consumers
that expect the expected_candidates key won't break and test case formatting
matches case-011.
🤖 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 `@plugins/ci/commands/payload-analysis.md`:
- Around line 12-14: The Markdown file plugins/ci/commands/payload-analysis.md
has fenced code blocks missing language identifiers (tripping MD040); update the
fences so the usage block uses a neutral language like "text" (for the usage
line `/ci:payload-analysis <payload-tag> [--snapshot-dir DIR]`) and the example
invocation blocks use "bash" (for the example commands such as
`/ci:payload-analysis 4.22.0-0.nightly-2026-02-25-152806`, `/ci:payload-analysis
... --snapshot-dir payload/4.22/nightly`, and the arm64 example); apply the same
change to the other affected fences around lines 76-88 so all triple-backtick
fences include the appropriate language identifiers.

In `@plugins/ci/evals/scripts/extract-payload-analysis-snapshots.sh`:
- Line 33: The tar extraction command tar xzf "$archive" -C "$dest" is
vulnerable to path traversal and link attacks; before extracting, enumerate
members (tar -tzf "$archive") and validate each entry: reject any member with an
absolute path (starts with '/'), any path containing '..' segments, and any
member that is a symlink or hardlink (detect via tar -tzvf or --list with type
flag and reject type 'l'/'L'/'H' entries); only if all members pass, proceed to
extract to "$dest" (tar xzf "$archive" -C "$dest"), otherwise abort with a clear
error.

In `@plugins/ci/skills/payload-analysis/SKILL.md`:
- Around line 137-147: The fenced code blocks in SKILL.md (notably the block
labeled "ANALYSIS_RESULT" and the other plain-output blocks referenced around
the sections showing job summaries) are missing language identifiers which trips
markdown lint; update each ``` fence to include a language token (use ```text
for plain output) so all fenced blocks like the ANALYSIS_RESULT block and the
other plain-output blocks are written as ```text ... ``` to satisfy the linter.
- Around line 1-4: The SKILL.md for payload-analysis is missing the required
4-phase ai-helpers overlap analysis; update the payload-analysis SKILL.md to
include a 4-phase overlap report (Phase 1–4) that classifies similarity as
HIGH/MODERATE/LOW against existing plugins/ci/* payload components and any
overlapping open PRs, include explicit lists of overlapping component names and
PR identifiers/links, state the methodology and metrics used for similarity
scoring, and summarize actionable conclusions (e.g., merge/reuse/avoid,
potential conflicts) so reviewers can see which components/PRs overlap and why.

In `@plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py`:
- Line 22: The JUnit XML parsing in _parse_junit_xml currently uses
xml.etree.ElementTree (imported as ET) which is vulnerable to XML bomb/entity
expansion; replace it by adding defusedxml as a dependency, change the import at
the top to use defusedxml's ElementTree (e.g., import defusedxml.ElementTree as
ET or from defusedxml import ElementTree as ET), keep using ET.parse(source)
inside _parse_junit_xml, and update the exception handling around the parse to
also catch defusedxml's security exception
(defusedxml.common.DefusedXmlException) in addition to ET.ParseError and OSError
so malicious payloads are rejected safely and logged.

In `@plugins/ci/skills/payload-snapshot/SKILL.md`:
- Around line 120-123: The jq example incorrectly reads component from each
commit's .name; update the query to take the component name from the parent
updatedImages[] object by binding the parent (e.g., using updatedImages[] as
$img) and then iterating $img.commits[] and using $img.name for the component
while keeping .pullURL and .subject for pr and subject; change the expression
that currently uses .changeLogJson.updatedImages[].commits[] and .name to
reference the parent’s name (e.g., $img.name) instead.

---

Nitpick comments:
In `@plugins/ci/commands/payload-revert.md`:
- Around line 39-42: Add a language specifier to the fenced code block
containing the error message "Error: Payload results YAML not found for
{payload_tag}." so it becomes a code fence like ```text; update the opening
backticks for the block that includes the "Error: Payload results YAML not found
for {payload_tag}." and the "Run `/ci:payload-analysis {payload_tag}` first to
generate it." line to satisfy markdownlint and improve consistency.

In
`@plugins/ci/evals/cases/payload-analysis/case-012-4.20-rejected-streak/annotations.yaml`:
- Around line 1-12: Add an explicit expected_candidates field to the annotations
so the file consistently declares expected revert candidates; since
has_revert_candidates is false, set expected_candidates to an empty array
(expected_candidates: []). Update the top-level keys (e.g., alongside
expected_phase, expected_failed_job_count, has_revert_candidates) so consumers
that expect the expected_candidates key won't break and test case formatting
matches case-011.

In
`@plugins/ci/evals/cases/payload-analysis/case-013-4.20-accepted-with-failures/annotations.yaml`:
- Around line 1-11: Add an explicit expected_candidates field to the annotations
YAML (e.g., expected_candidates: []) to mirror case-011 and ensure consistency
with has_revert_candidates: false; update the top-level fields in the same
document where expected_phase, expected_failed_job_count, and
has_revert_candidates are declared so the evaluation framework sees an empty
array for expected_candidates rather than omitting the key.
🪄 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: c23ac0a3-7ee0-4c21-8243-1a4e05eb45d3

📥 Commits

Reviewing files that changed from the base of the PR and between 744b3d5 and d1b60be.

⛔ Files ignored due to path filters (14)
  • plugins/ci/evals/snapshots/payload-analysis/4.18.0-0.nightly-2026-05-14-085133.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.20.0-0.nightly-2026-05-12-225204.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.20.0-0.nightly-2026-05-13-064706.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.20.0-0.nightly-2026-05-14-114051.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.22.0-0.ci-2026-03-31-050515.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.22.0-0.ci-2026-03-31-170515.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.22.0-0.nightly-2026-03-18-161724.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.22.0-0.nightly-2026-03-20-053450.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/4.22.0-0.nightly-2026-03-26-231124.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/5.0.0-0.ci-2026-04-14-085906.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/5.0.0-0.ci-2026-05-07-142711.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/5.0.0-0.ci-2026-05-14-181709.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/5.0.0-0.nightly-2026-04-27-183150.tar.gz is excluded by !**/*.gz
  • plugins/ci/evals/snapshots/payload-analysis/5.0.0-0.nightly-2026-05-30-072431.tar.gz is excluded by !**/*.gz
📒 Files selected for processing (42)
  • .claude-plugin/marketplace.json
  • docs/index.html
  • plugins/ci/.claude-plugin/plugin.json
  • plugins/ci/commands/analyze-payload.md
  • plugins/ci/commands/payload-analysis.md
  • plugins/ci/commands/payload-experiment.md
  • plugins/ci/commands/payload-revert.md
  • plugins/ci/evals/cases/payload-analysis/case-001-4.22-nightly-ci-config-and-product-regression/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-001-4.22-nightly-ci-config-and-product-regression/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-002-5.0-nightly-all-new-failures/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-002-5.0-nightly-all-new-failures/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-003-5.0-ci-cno-networkpolicy-revert/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-003-5.0-ci-cno-networkpolicy-revert/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-004-4.22-two-reverts/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-004-4.22-two-reverts/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-005-4.22-ci-cco-revert/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-005-4.22-ci-cco-revert/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-006-4.22-ci-hypershift-revert/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-006-4.22-ci-hypershift-revert/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-007-4.22-cvo-revert/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-007-4.22-cvo-revert/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-008-5.0-nightly-cmo-monitoring-revert/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-008-5.0-nightly-cmo-monitoring-revert/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-009-5.0-ci-hypershift-builder-fp/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-009-5.0-ci-hypershift-builder-fp/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-010-4.18-rejected-multiple-failures/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-010-4.18-rejected-multiple-failures/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-011-5.0-ci-infra-only-no-candidates/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-011-5.0-ci-infra-only-no-candidates/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-012-4.20-rejected-streak/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-012-4.20-rejected-streak/input.yaml
  • plugins/ci/evals/cases/payload-analysis/case-013-4.20-accepted-with-failures/annotations.yaml
  • plugins/ci/evals/cases/payload-analysis/case-013-4.20-accepted-with-failures/input.yaml
  • plugins/ci/evals/eval-payload-analysis.yaml
  • plugins/ci/evals/scripts/extract-payload-analysis-snapshots.sh
  • plugins/ci/skills/analyze-payload/SKILL.md
  • plugins/ci/skills/payload-analysis/SKILL.md
  • plugins/ci/skills/payload-autodl-json/SKILL.md
  • plugins/ci/skills/payload-results-yaml/SKILL.md
  • plugins/ci/skills/payload-snapshot/SKILL.md
  • plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py
  • plugins/ci/skills/stage-payload-reverts/SKILL.md
💤 Files with no reviewable changes (2)
  • plugins/ci/commands/analyze-payload.md
  • plugins/ci/skills/analyze-payload/SKILL.md

Comment thread plugins/ci/commands/payload-analysis.md
Comment thread plugins/ci/evals/scripts/extract-payload-analysis-snapshots.sh Outdated
Comment thread plugins/ci/skills/payload-analysis/SKILL.md
Comment on lines +137 to +147
```
ANALYSIS_RESULT:
- failure_type: install|test|upgrade|infra
- root_cause_summary: <one-line summary>
- affected_components: <comma-separated list of affected operators/components>
- key_error_patterns: <comma-separated key error strings for matching>
- known_symptoms: <comma-separated symptom summaries from job_labels, or "none">
- underlying_job_name: <for aggregated jobs only, extracted from junit artifacts>
- retries_consistent: yes|no|no_retries|only_final_examined
- retry_summary: <brief comparison of failure modes across attempts, e.g. "all 3 attempts failed with same KAS crashloop" or "attempt 1 infra timeout, attempts 2-3 test failure", or "no retries" when there was only a single attempt>
```

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Specify languages for fenced blocks to satisfy markdown lint.

Several fences are missing language identifiers (text is fine for plain output blocks).

Also applies to: 164-166, 471-488

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 137-137: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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 `@plugins/ci/skills/payload-analysis/SKILL.md` around lines 137 - 147, The
fenced code blocks in SKILL.md (notably the block labeled "ANALYSIS_RESULT" and
the other plain-output blocks referenced around the sections showing job
summaries) are missing language identifiers which trips markdown lint; update
each ``` fence to include a language token (use ```text for plain output) so all
fenced blocks like the ANALYSIS_RESULT block and the other plain-output blocks
are written as ```text ... ``` to satisfy the linter.

Comment thread plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py
Comment on lines +120 to +123
**List PRs in a payload:**
```bash
jq '.changeLogJson.updatedImages[].commits[] | {component: .name, pr: .pullURL, subject: .subject}' payload/<version>/<stream>/<tag>/changelog.json
```

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the jq example: component is read from the wrong level.

The current query reads .name from each commit object, but component name is on the parent updatedImages[] object.

💡 Suggested patch
-jq '.changeLogJson.updatedImages[].commits[] | {component: .name, pr: .pullURL, subject: .subject}' payload/<version>/<stream>/<tag>/changelog.json
+jq '.changeLogJson.updatedImages[] | .name as $component | .commits[] | {component: $component, pr: .pullURL, subject: .subject}' payload/<version>/<stream>/<tag>/changelog.json
📝 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.

Suggested change
**List PRs in a payload:**
```bash
jq '.changeLogJson.updatedImages[].commits[] | {component: .name, pr: .pullURL, subject: .subject}' payload/<version>/<stream>/<tag>/changelog.json
```
**List PRs in a payload:**
🤖 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 `@plugins/ci/skills/payload-snapshot/SKILL.md` around lines 120 - 123, The jq
example incorrectly reads component from each commit's .name; update the query
to take the component name from the parent updatedImages[] object by binding the
parent (e.g., using updatedImages[] as $img) and then iterating $img.commits[]
and using $img.name for the component while keeping .pullURL and .subject for pr
and subject; change the expression that currently uses
.changeLogJson.updatedImages[].commits[] and .name to reference the parent’s
name (e.g., $img.name) instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.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: 3

🤖 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 `@plugins/ci/skills/payload-autodl-json/scripts/validate.py`:
- Around line 42-50: The loop over rows is both prematurely breaking (the "if i
> 0: break" stops after the first row) and assumes each row is a dict (using
row.items()), which can crash on malformed input; remove the premature break so
all rows are validated, and before accessing row.items() or checking fields
against REQUIRED_ROW_FIELDS ensure row is a dict (or mapping) — if not, append
an error like "rows[i] is not an object" and continue; only then check missing
fields and non-string values (use the existing REQUIRED_ROW_FIELDS, rows
variable and the enumerate loop) so every row is safely validated without
exceptions.

In `@plugins/ci/skills/payload-results-yaml/scripts/validate.py`:
- Around line 39-43: The loops over data["failing_jobs"] and data["candidates"]
assume each item is a mapping and will crash on non-dict entries; update the
checks in the failing_jobs loop (iterate variable job in validate.py) and the
candidates loop to first verify isinstance(item, dict) and if not append a clear
error like "failing_jobs[i] is not an object" or "candidates[j] is not an
object" then continue, otherwise perform the existing REQUIRED_JOB_FIELDS /
REQUIRED_CANDIDATE_FIELDS membership checks as before.
- Around line 29-33: The validation currently assumes metadata is a dict by
doing meta = data.get("metadata", {}) and then iterating REQUIRED_METADATA,
which allows non-object metadata (e.g., string or list) to pass or produce
confusing messages; update the logic where meta is read (the variable meta
derived from data.get("metadata", {})) to first check that metadata exists and
is a mapping/dict type and, if not, append a clear error like "metadata must be
an object" to errors and skip the REQUIRED_METADATA loop; keep using the same
symbols (data, meta, REQUIRED_METADATA, errors) so callers and tests still find
the check location.
🪄 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: 3d22d286-5c01-48fc-80ac-2112256ece19

📥 Commits

Reviewing files that changed from the base of the PR and between d1b60be and a004ffa.

📒 Files selected for processing (2)
  • plugins/ci/skills/payload-autodl-json/scripts/validate.py
  • plugins/ci/skills/payload-results-yaml/scripts/validate.py

Comment thread plugins/ci/skills/payload-autodl-json/scripts/validate.py Outdated
Comment thread plugins/ci/skills/payload-results-yaml/scripts/validate.py Outdated
Comment thread plugins/ci/skills/payload-results-yaml/scripts/validate.py
Address CodeRabbit feedback: validate metadata type before checking
keys, guard list entries against non-dict values, validate all rows
instead of breaking after the first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

These are mostly small files, but some are a few megabytes. I am not sure if it makes sense to keep them there, or publish them somewhere else. I was thinking FROM scratch OCI containers. Pre-hooks would help a lot here opendatahub-io/agent-eval-harness#88

13 tests covering valid schemas, missing fields, wrong types, flat
schemas (the hallucinated format), non-string JSON values, empty
rows, bad syntax, and missing files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.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: 2

🤖 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 `@plugins/ci/skills/payload-autodl-json/scripts/test_validate.py`:
- Around line 36-38: The temporary file created with
tempfile.NamedTemporaryFile(..., delete=False) in test_validate.py is never
removed; update the test to ensure the file is cleaned up after use by removing
the file (os.unlink or pathlib.Path.unlink) once the test case is registered or
in test teardown, or change to delete=True and capture the name before closing
if necessary; locate the NamedTemporaryFile usage and add explicit cleanup
(e.g., try/finally or fixture teardown) to avoid leaving orphaned files.

In `@plugins/ci/skills/payload-results-yaml/scripts/test_validate.py`:
- Around line 38-40: The temp file created with tempfile.NamedTemporaryFile(...,
delete=False) in the test is never removed; update the test in test_validate.py
so the temporary YAML is deleted after use (either use delete=True or explicitly
unlink the file), e.g. create the temp file, append the case to cases, then
ensure os.unlink(f.name) in a finally block or use pytest's tmp_path fixture to
manage cleanup; refer to the NamedTemporaryFile call and the variable f and the
cases list when making the change.
🪄 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: d4b914a7-1661-443f-b653-954dc7c7ad98

📥 Commits

Reviewing files that changed from the base of the PR and between bc28091 and fe2917c.

📒 Files selected for processing (11)
  • plugins/ci/skills/payload-autodl-json/scripts/test_validate.py
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/invalid_empty_rows.json
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/invalid_no_table_name.json
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/invalid_non_string_values.json
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/valid.json
  • plugins/ci/skills/payload-results-yaml/scripts/test_validate.py
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/invalid_flat_schema.yaml
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/invalid_metadata_string.yaml
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/invalid_missing_job_fields.yaml
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/valid.yaml
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/valid_no_candidates.yaml
✅ Files skipped from review due to trivial changes (8)
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/invalid_empty_rows.json
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/invalid_metadata_string.yaml
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/valid.json
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/valid.yaml
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/invalid_non_string_values.json
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/invalid_flat_schema.yaml
  • plugins/ci/skills/payload-autodl-json/scripts/testdata/invalid_no_table_name.json
  • plugins/ci/skills/payload-results-yaml/scripts/testdata/invalid_missing_job_fields.yaml

Comment thread plugins/ci/skills/payload-autodl-json/scripts/test_validate.py Outdated
Comment thread plugins/ci/skills/payload-results-yaml/scripts/test_validate.py Outdated
not-stbenjam and others added 9 commits June 1, 2026 11:21
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix markdown fence languages, jq component query, and XML parser
trust annotation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep analyze-payload in place alongside payload-analysis until the
release repo migration is validated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous docs were generated with node_modules present, which
included dotenv, dotenvx, and playwright skills as standalone_skills.
CI runs on a clean checkout without node_modules and sees the mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Packages like dotenv and playwright-core ship SKILL.md files that
skillsaw picks up as standalone skills, causing docs drift between
local (with node_modules) and CI (clean checkout).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 32MB of tarballs with a shallow clone from
stbenjam/historical-payload-data. The extraction script now
fetches snapshot data on demand instead of bundling it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stbenjam stbenjam closed this Jun 2, 2026
@stbenjam stbenjam reopened this Jun 2, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis

2 similar comments
@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis

@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis

@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

build13 taken out of rotation finally openshift/release#79962

/test eval-payload-analysis

not-stbenjam and others added 3 commits June 2, 2026 08:35
# Conflicts:
#	.claude-plugin/marketplace.json
#	docs/index.html
#	plugins/ci/.claude-plugin/plugin.json
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis-minimal

2 similar comments
@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis-minimal

@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis-minimal

@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis

The adversarial review was causing the agent to second-guess correct
rubric scores — talking itself down from 92 to 60 with speculative
counter-arguments like "if this were the sole cause, ALL jobs would
fail." Three fixes:

- Step 6.1: enforce mechanical rubric application, no speculative
  score adjustments
- Step 9: rename to completeness review, refocus on catching lazy
  agents (missing skills, shallow analysis) not challenging correct
  conclusions
- Step 4: require affirmative evidence for infrastructure
  classification, default to product regression

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/test eval-payload-analysis

@stbenjam

stbenjam commented Jun 2, 2026

Copy link
Copy Markdown
Member Author

/hold cancel

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 2, 2026

set -euo pipefail

REPO_URL="https://github.com/stbenjam/historical-payload-data.git"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Presuming this is intentional / temporary but double checking the use of personal repo. No objections just confirming.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, transitional. I'll request a repo from cyborg

@neisw

neisw commented Jun 2, 2026

Copy link
Copy Markdown

/lgtm
/hold
for comment review, unhold if all good

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 2, 2026
@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 2, 2026
@openshift-ci

openshift-ci Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: neisw, stbenjam

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@stbenjam

stbenjam commented Jun 3, 2026

Copy link
Copy Markdown
Member Author

/hold cancel

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 3, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 4fd0460 into openshift-eng:main Jun 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants