From ae2fbd501616d4dcb6f1140674d3497d315d0c1e Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Mon, 1 Jun 2026 06:03:11 -0400 Subject: [PATCH 01/13] Switch payload agent to snapshot-based payload-analysis skill - Run payload_snapshot.py deterministically before invoking Claude, shifting data gathering from token-burning agent orchestration to a zero-cost Python script - Replace /ci:analyze-payload with /ci:payload-analysis --snapshot-dir - Add schema validation retry loop for YAML/JSON outputs (up to 3 attempts) - Remove Jira integration and revert staging (now handled by Chai Bot) - Add snapshot phase to JUnit tracking Co-Authored-By: Claude Opus 4.6 --- ...openshift-claude-payload-agent-commands.sh | 134 ++++++++---------- .../openshift-claude-payload-agent-ref.yaml | 21 +-- 2 files changed, 60 insertions(+), 95 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index f6694a58d9b01..75b186d2a7f03 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -28,22 +28,6 @@ else echo "Warning: Slack webhook not found at ${SLACK_WEBHOOK_URL}. Notifications will be skipped." fi -JIRA_API_TOKEN="" -if [ -f "${JIRA_API_TOKEN_PATH}" ]; then - JIRA_API_TOKEN=$(cat "${JIRA_API_TOKEN_PATH}") - echo "Jira API token loaded." -else - echo "Warning: Jira API token not found at ${JIRA_API_TOKEN_PATH}. Jira operations will not be available." -fi - -JIRA_USERNAME="" -if [ -f "${JIRA_USERNAME_PATH}" ]; then - JIRA_USERNAME=$(cat "${JIRA_USERNAME_PATH}") - echo "Jira username loaded." -else - echo "Warning: Jira username not found at ${JIRA_USERNAME_PATH}. Jira operations will not be available." -fi - # Install gcloud CLI for GCS artifact access (no root required) echo "Installing gcloud CLI..." curl -sSL https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-linux-x86_64.tar.gz | tar -xz -C /tmp @@ -63,7 +47,6 @@ PAYLOAD_URL="${RELEASE_CONTROLLER_URL}/releasestream/${STREAM_NAME}/release/${PA echo "Version: ${VERSION}, Stream: ${STREAM}" echo "Release API: ${API_URL}" -echo "Automatic reverts enabled: ${ENABLE_PAYLOAD_REVERT}" # Poll until blocking jobs finish OR the payload reaches a terminal state. # The release controller can report jobs as Pending even after they complete @@ -180,6 +163,20 @@ echo "Invoking Claude to analyze payload ${PAYLOAD_TAG}..." WORKDIR=$(mktemp -d /tmp/claude-analysis-XXXXXX) cd "${WORKDIR}" +# Create payload snapshot deterministically (no tokens spent) +echo "" +echo "=== Creating payload snapshot ===" +SNAPSHOT_SCRIPT=$(find /home/claude/.claude -name "payload_snapshot.py" -path "*/payload-snapshot/*" 2>/dev/null | head -1) +if [[ -z "${SNAPSHOT_SCRIPT}" ]]; then + echo "ERROR: payload_snapshot.py not found. Is the ai-helpers plugin installed?" + exit 1 +fi +SNAPSHOT_DIR="${WORKDIR}/snapshot" +PHASE_SNAPSHOT_START=$(date +%s) +python3 "${SNAPSHOT_SCRIPT}" "${PAYLOAD_TAG}" --output-dir "${SNAPSHOT_DIR}" +PHASE_SNAPSHOT_DURATION=$(( $(date +%s) - PHASE_SNAPSHOT_START )) +echo "Snapshot created in ${PHASE_SNAPSHOT_DURATION}s at ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" + # Ensure reports and session logs are copied to artifacts even if the script exits early copy_reports() { if [[ -d "${WORKDIR:-}" ]]; then @@ -209,7 +206,9 @@ ALLOWED_TOOLS="Bash Read Write Edit Grep Glob WebFetch WebSearch Task Skill" SYSTEM_PROMPT="You are a diligent senior OpenShift release engineer triaging failures. -**CRITICAL**: You have many ci, must-gather, and jira skills at your disposal. You MUST load the relevant skills using the Skill tool BEFORE you begin any work. Do NOT improvise or guess. This applies equally to subagents: instruct every subagent to review its available skills and load the appropriate ones before beginning its investigation. A subagent that does not load a skill will produce shallow, unreliable analysis." +**CRITICAL**: You have many ci and must-gather skills at your disposal. You MUST load the relevant skills using the Skill tool BEFORE you begin any work. Do NOT improvise or guess. This applies equally to subagents: instruct every subagent to review its available skills and load the appropriate ones before beginning its investigation. A subagent that does not load a skill will produce shallow, unreliable analysis. + +After completing your analysis, you MUST use the Skill tool to invoke ci:payload-results-yaml and ci:payload-autodl-json to generate the structured output files. NEVER write these files directly — the skills enforce the canonical schema." PHASE_ANALYSIS_START=$(date +%s) CLAUDE_EXIT=0 @@ -219,7 +218,7 @@ timeout 3600 claude \ --output-format stream-json \ --max-turns 100 \ --append-system-prompt "${SYSTEM_PROMPT}" \ - -p "/ci:analyze-payload ${PAYLOAD_TAG}" \ + -p "/ci:payload-analysis ${PAYLOAD_TAG} --snapshot-dir ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" \ --verbose 2>&1 | tee "${ARTIFACT_DIR}/claude-output.log" || CLAUDE_EXIT=$? PHASE_ANALYSIS_DURATION=$(( $(date +%s) - PHASE_ANALYSIS_START )) @@ -241,74 +240,56 @@ if [[ "${CLAUDE_EXIT}" -eq 124 ]]; then fi PHASE_NUDGE_DURATION=$(( $(date +%s) - PHASE_NUDGE_START )) -# Optionally stage reverts for high-confidence candidates -PHASE_REVERT_START=$(date +%s) -REVERT_EXIT=0 -if [[ "${ENABLE_PAYLOAD_REVERT}" == "true" ]]; then - if [[ -z "${GITHUB_TOKEN:-}" ]]; then - echo "Warning: Automatic reverts enabled but no GitHub token is available. Skipping reverts." - elif ls "${WORKDIR}"/payload-results-*.yaml 1>/dev/null 2>&1; then - echo "" - echo "=== Staging reverts for high-confidence candidates ===" - - # Configure Jira MCP server for creating TRT issues - REVERT_ALLOWED_TOOLS="${ALLOWED_TOOLS}" - if [[ -n "${JIRA_API_TOKEN}" ]] && [[ -n "${JIRA_USERNAME}" ]]; then - echo "Configuring Jira MCP server..." - set +x - claude mcp add \ - -e JIRA_URL="${JIRA_URL}" \ - -e JIRA_API_TOKEN="${JIRA_API_TOKEN}" \ - -e JIRA_USERNAME="${JIRA_USERNAME}" \ - --transport stdio \ - jira -- uvx mcp-atlassian@0.21.0 - echo "Jira MCP server configured." - REVERT_ALLOWED_TOOLS="${REVERT_ALLOWED_TOOLS} mcp__jira__*" - else - echo "Warning: Jira API token or username not available. TRT issues will not be created." - fi +# Validate structured output files, retry up to 3 times if missing/invalid +SANITIZED_TAG=$(echo "${PAYLOAD_TAG}" | tr '.' '-') +for attempt in 1 2 3; do + YAML_OK=false + JSON_OK=false - timeout 3600 claude \ - --model "${CLAUDE_MODEL}" \ - --continue \ - --allowedTools "${REVERT_ALLOWED_TOOLS}" \ - --output-format stream-json \ - --max-turns 50 \ - -p "/ci:payload-revert ${PAYLOAD_TAG}" \ - --verbose 2>&1 | tee "${ARTIFACT_DIR}/claude-revert.log" || REVERT_EXIT=$? + if python3 -c "import yaml; yaml.safe_load(open('payload-results-${SANITIZED_TAG}.yaml'))" 2>/dev/null; then + YAML_OK=true + fi + if python3 -c "import json; json.load(open('payload-analysis-${SANITIZED_TAG}-autodl.json'))" 2>/dev/null; then + JSON_OK=true + fi - else - echo "Warning: No payload results YAML found. Skipping reverts." + if $YAML_OK && $JSON_OK; then + echo "Structured outputs validated (attempt ${attempt})." + break fi -else - echo "Automatic reverts not enabled. Skipping revert stage." -fi -PHASE_REVERT_DURATION=$(( $(date +%s) - PHASE_REVERT_START )) + + if [[ "${attempt}" -eq 3 ]]; then + echo "Warning: Structured outputs still invalid after 3 attempts." + break + fi + + MISSING="" + if ! $YAML_OK; then MISSING="ci:payload-results-yaml"; fi + if ! $JSON_OK; then MISSING="${MISSING:+${MISSING} and }ci:payload-autodl-json"; fi + echo "Attempt ${attempt}: Missing/invalid outputs (${MISSING}). Re-invoking Claude..." + + timeout 600 claude \ + --model "${CLAUDE_MODEL}" \ + --continue \ + --allowedTools "${ALLOWED_TOOLS}" \ + --output-format stream-json \ + --max-turns 10 \ + -p "Your structured output files are missing or invalid. Use the Skill tool to invoke ${MISSING} to regenerate them now." \ + --verbose 2>&1 | tee -a "${ARTIFACT_DIR}/claude-output.log" || true +done # Generate JUnit XML for timeout and phase duration tracking JUNIT_FILE="${ARTIFACT_DIR}/junit_claude-ci.xml" PHASE_PREFIX="[sig-claude]" TIMEOUT_TESTCASE="${PHASE_PREFIX} Claude should complete in a reasonable time" -TOTAL_DURATION=$(( PHASE_WAIT_DURATION + PHASE_ANALYSIS_DURATION + PHASE_NUDGE_DURATION + PHASE_REVERT_DURATION )) +TOTAL_DURATION=$(( PHASE_WAIT_DURATION + PHASE_SNAPSHOT_DURATION + PHASE_ANALYSIS_DURATION + PHASE_NUDGE_DURATION )) PHASE_CASES=" + " TIMEOUT_CASES="" FAILURE_COUNT=0 - -if [[ "${ENABLE_PAYLOAD_REVERT}" == "true" ]]; then - if [[ "${REVERT_EXIT}" -ne 0 ]]; then - FAILURE_COUNT=$(( FAILURE_COUNT + 1 )) - PHASE_CASES="${PHASE_CASES} - - Claude payload revert exited with code ${REVERT_EXIT}. - " - else - PHASE_CASES="${PHASE_CASES} - " - fi -fi TIMEOUT_TEST_COUNT=0 if [[ "${CLAUDE_EXIT}" -eq 124 ]]; then @@ -343,10 +324,7 @@ else TIMEOUT_CASES=" " fi -PHASE_COUNT=2 -if [[ "${ENABLE_PAYLOAD_REVERT}" == "true" ]]; then - PHASE_COUNT=3 -fi +PHASE_COUNT=3 TEST_COUNT=$(( PHASE_COUNT + TIMEOUT_TEST_COUNT )) cat > "${JUNIT_FILE}" < @@ -379,7 +357,7 @@ SUMMARY=$(claude \ --continue \ --output-format text \ --max-turns 5 \ - -p "Write a very brief summary of your findings suitable for a Slack message. Include the payload tag and list the failed jobs. If any revert PRs were opened, include their URLs as links for Slack. Include a brief, encouraging CI-related joke or pun. Plain text only, no markdown. 2-3 sentences max." \ + -p "Write a very brief summary of your findings suitable for a Slack message. Include the payload tag and list the failed jobs. If you identified revert candidates, mention them. Include a brief, encouraging CI-related joke or pun. Plain text only, no markdown. 2-3 sentences max." \ 2>/dev/null) || SUMMARY="" if [[ -n "${SLACK_WEBHOOK}" ]]; then diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml index d8f0a95eec2ff..4656396655120 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml @@ -15,9 +15,6 @@ ref: - namespace: test-credentials name: claude-payload-agent-github-token mount_path: /var/run/github-token - - namespace: test-credentials - name: claude-payload-agent-jira-token - mount_path: /var/run/jira-token env: - name: PAYLOAD_TAG - name: CLAUDE_CODE_USE_VERTEX @@ -34,14 +31,6 @@ ref: default: "/var/run/slack-webhook/url" - name: GITHUB_TOKEN_PATH default: "/var/run/github-token/token" - - name: JIRA_API_TOKEN_PATH - default: "/var/run/jira-token/token" - - name: JIRA_USERNAME_PATH - default: "/var/run/jira-token/username" - - name: JIRA_URL - default: "https://redhat.atlassian.net" - - name: ENABLE_PAYLOAD_REVERT - default: "false" - name: ENABLE_SLACK_NOTIFICATIONS default: "true" resources: @@ -51,9 +40,7 @@ ref: timeout: 12h0m0s grace_period: 1m0s documentation: |- - Analyzes rejected release payloads using Claude AI and optionally - stages reverts for high-confidence causes. Receives a PAYLOAD_TAG - from the release controller, polls until blocking jobs complete, - runs the analyze-payload skill to identify root causes, generates - an HTML report, and when ENABLE_PAYLOAD_REVERT is true, stages - reverts for high-confidence candidates via payload-revert. + Analyzes rejected release payloads using Claude AI. Creates a + deterministic snapshot of payload data, then runs the + payload-analysis skill to identify root causes and generate an + HTML report with revert recommendations. From 780d7ec33614676effa055e1bda59aa39a3303c4 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Mon, 1 Jun 2026 10:34:59 -0400 Subject: [PATCH 02/13] Use validation scripts from ai-helpers for output schema checks Co-Authored-By: Claude Opus 4.6 --- .../agent/openshift-claude-payload-agent-commands.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 75b186d2a7f03..93e552e2977ad 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -242,14 +242,17 @@ PHASE_NUDGE_DURATION=$(( $(date +%s) - PHASE_NUDGE_START )) # Validate structured output files, retry up to 3 times if missing/invalid SANITIZED_TAG=$(echo "${PAYLOAD_TAG}" | tr '.' '-') +VALIDATE_YAML=$(find /home/claude/.claude -name "validate.py" -path "*/payload-results-yaml/*" 2>/dev/null | head -1) +VALIDATE_JSON=$(find /home/claude/.claude -name "validate.py" -path "*/payload-autodl-json/*" 2>/dev/null | head -1) + for attempt in 1 2 3; do YAML_OK=false JSON_OK=false - if python3 -c "import yaml; yaml.safe_load(open('payload-results-${SANITIZED_TAG}.yaml'))" 2>/dev/null; then + if python3 "${VALIDATE_YAML}" "payload-results-${SANITIZED_TAG}.yaml" 2>/dev/null; then YAML_OK=true fi - if python3 -c "import json; json.load(open('payload-analysis-${SANITIZED_TAG}-autodl.json'))" 2>/dev/null; then + if python3 "${VALIDATE_JSON}" "payload-analysis-${SANITIZED_TAG}-autodl.json" 2>/dev/null; then JSON_OK=true fi From 6ec295f077b7916a4fcb3f08466d76c5ff3c9355 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Mon, 1 Jun 2026 11:14:28 -0400 Subject: [PATCH 03/13] Address CodeRabbit feedback: fail on invalid outputs, fix JUnit accounting - Fail the step (exit 1) when validators are missing or outputs are still invalid after 3 retries - Move PHASE_ANALYSIS_DURATION finalization after the retry loop so nudge + validation time is included - Increment PHASE_COUNT when recovery nudge testcase is appended Co-Authored-By: Claude Opus 4.6 --- ...openshift-claude-payload-agent-commands.sh | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 93e552e2977ad..98165532cbbbd 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -221,8 +221,6 @@ timeout 3600 claude \ -p "/ci:payload-analysis ${PAYLOAD_TAG} --snapshot-dir ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" \ --verbose 2>&1 | tee "${ARTIFACT_DIR}/claude-output.log" || CLAUDE_EXIT=$? -PHASE_ANALYSIS_DURATION=$(( $(date +%s) - PHASE_ANALYSIS_START )) - # If Claude timed out (exit 124), nudge it to wrap up with a shorter timeout PHASE_NUDGE_START=$(date +%s) NUDGE_EXIT=0 @@ -245,14 +243,19 @@ SANITIZED_TAG=$(echo "${PAYLOAD_TAG}" | tr '.' '-') VALIDATE_YAML=$(find /home/claude/.claude -name "validate.py" -path "*/payload-results-yaml/*" 2>/dev/null | head -1) VALIDATE_JSON=$(find /home/claude/.claude -name "validate.py" -path "*/payload-autodl-json/*" 2>/dev/null | head -1) +if [[ -z "${VALIDATE_YAML}" || -z "${VALIDATE_JSON}" ]]; then + echo "ERROR: validation scripts not found in the ai-helpers plugin installation." + exit 1 +fi + for attempt in 1 2 3; do YAML_OK=false JSON_OK=false - if python3 "${VALIDATE_YAML}" "payload-results-${SANITIZED_TAG}.yaml" 2>/dev/null; then + if python3 "${VALIDATE_YAML}" "payload-results-${SANITIZED_TAG}.yaml"; then YAML_OK=true fi - if python3 "${VALIDATE_JSON}" "payload-analysis-${SANITIZED_TAG}-autodl.json" 2>/dev/null; then + if python3 "${VALIDATE_JSON}" "payload-analysis-${SANITIZED_TAG}-autodl.json"; then JSON_OK=true fi @@ -262,8 +265,9 @@ for attempt in 1 2 3; do fi if [[ "${attempt}" -eq 3 ]]; then - echo "Warning: Structured outputs still invalid after 3 attempts." - break + echo "ERROR: Structured outputs still invalid after 3 attempts." + PHASE_ANALYSIS_DURATION=$(( $(date +%s) - PHASE_ANALYSIS_START )) + exit 1 fi MISSING="" @@ -281,6 +285,8 @@ for attempt in 1 2 3; do --verbose 2>&1 | tee -a "${ARTIFACT_DIR}/claude-output.log" || true done +PHASE_ANALYSIS_DURATION=$(( $(date +%s) - PHASE_ANALYSIS_START )) + # Generate JUnit XML for timeout and phase duration tracking JUNIT_FILE="${ARTIFACT_DIR}/junit_claude-ci.xml" PHASE_PREFIX="[sig-claude]" @@ -328,6 +334,9 @@ else fi PHASE_COUNT=3 +if [[ "${CLAUDE_EXIT}" -eq 124 ]]; then + PHASE_COUNT=$((PHASE_COUNT + 1)) +fi TEST_COUNT=$(( PHASE_COUNT + TIMEOUT_TEST_COUNT )) cat > "${JUNIT_FILE}" < From 9a7588a9b6e2e971948efc2243093591a52da4bd Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Tue, 2 Jun 2026 16:49:13 -0400 Subject: [PATCH 04/13] Add temporary payload agent job for 4.22 nightly 2026-06-01-074812 To be removed before merge. Co-Authored-By: Claude Opus 4.6 --- .../release/openshift-release-main__temp.yaml | 17 +++++ .../openshift-release-main-periodics.yaml | 74 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 ci-operator/config/openshift/release/openshift-release-main__temp.yaml diff --git a/ci-operator/config/openshift/release/openshift-release-main__temp.yaml b/ci-operator/config/openshift/release/openshift-release-main__temp.yaml new file mode 100644 index 0000000000000..2b5ed920694f2 --- /dev/null +++ b/ci-operator/config/openshift/release/openshift-release-main__temp.yaml @@ -0,0 +1,17 @@ +resources: + '*': + requests: + cpu: 100m + memory: 200Mi +tests: +- as: claude-payload-agent + cron: '@yearly' + steps: + env: + PAYLOAD_TAG: 4.22.0-0.nightly-2026-06-01-074812 + workflow: openshift-claude-payload +zz_generated_metadata: + branch: main + org: openshift + repo: release + variant: temp diff --git a/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml b/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml index 0a2abed76876e..25317f9dd8f4f 100644 --- a/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml +++ b/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml @@ -304409,3 +304409,77 @@ periodics: - name: github-app-credentials secret: secretName: openshift-prow-github-app +- agent: kubernetes + cluster: build09 + cron: '@yearly' + decorate: true + decoration_config: + skip_cloning: true + extra_refs: + - base_ref: main + org: openshift + repo: release + labels: + ci-operator.openshift.io/variant: temp + ci.openshift.io/generator: prowgen + ci.openshift.io/no-builds: "true" + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: periodic-ci-openshift-release-main-temp-claude-payload-agent + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --target=claude-payload-agent + - --variant=temp + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator From eaf485bf711846ac350ba8dbbd4c41a785279f76 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 07:09:32 -0400 Subject: [PATCH 05/13] Switch payload agent to sa-claude-openshift-ci credential Replace hypershift-team-claude-prow with sa-claude-openshift-ci and update GOOGLE_APPLICATION_CREDENTIALS key from claude-prow to token. Co-Authored-By: Claude Opus 4.6 --- .../payload/agent/openshift-claude-payload-agent-ref.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml index 4656396655120..94aeb9b6b6dce 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-ref.yaml @@ -7,7 +7,7 @@ ref: commands: openshift-claude-payload-agent-commands.sh credentials: - namespace: test-credentials - name: hypershift-team-claude-prow + name: sa-claude-openshift-ci mount_path: /var/run/claude-code-service-account - namespace: test-credentials name: trt-alert-slack-webhook-url @@ -24,7 +24,7 @@ ref: - name: ANTHROPIC_VERTEX_PROJECT_ID default: "itpc-gcp-hybrid-pe-eng-claude" - name: GOOGLE_APPLICATION_CREDENTIALS - default: "/var/run/claude-code-service-account/claude-prow" + default: "/var/run/claude-code-service-account/token" - name: CLAUDE_MODEL default: "claude-opus-4-6" - name: SLACK_WEBHOOK_URL From 2ebd408bc6775aa94862dfce312aa2bdb78013ef Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 07:36:34 -0400 Subject: [PATCH 06/13] Fix script paths and archive snapshot to artifacts - Use hardcoded /opt/ai-helpers paths for payload_snapshot.py and validate.py instead of searching /home/claude/.claude - Archive snapshot tarball to ARTIFACT_DIR right after creation Co-Authored-By: Claude Opus 4.6 --- .../openshift-claude-payload-agent-commands.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 98165532cbbbd..2bff78cbc9d3b 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -166,16 +166,14 @@ cd "${WORKDIR}" # Create payload snapshot deterministically (no tokens spent) echo "" echo "=== Creating payload snapshot ===" -SNAPSHOT_SCRIPT=$(find /home/claude/.claude -name "payload_snapshot.py" -path "*/payload-snapshot/*" 2>/dev/null | head -1) -if [[ -z "${SNAPSHOT_SCRIPT}" ]]; then - echo "ERROR: payload_snapshot.py not found. Is the ai-helpers plugin installed?" - exit 1 -fi +SNAPSHOT_SCRIPT="/opt/ai-helpers/plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py" SNAPSHOT_DIR="${WORKDIR}/snapshot" PHASE_SNAPSHOT_START=$(date +%s) python3 "${SNAPSHOT_SCRIPT}" "${PAYLOAD_TAG}" --output-dir "${SNAPSHOT_DIR}" PHASE_SNAPSHOT_DURATION=$(( $(date +%s) - PHASE_SNAPSHOT_START )) echo "Snapshot created in ${PHASE_SNAPSHOT_DURATION}s at ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" +echo "Archiving payload snapshot to artifacts..." +tar -czf "${ARTIFACT_DIR}/snapshot-${PAYLOAD_TAG}.tar.gz" -C "${SNAPSHOT_DIR}" "${PAYLOAD_TAG}" # Ensure reports and session logs are copied to artifacts even if the script exits early copy_reports() { @@ -240,13 +238,8 @@ PHASE_NUDGE_DURATION=$(( $(date +%s) - PHASE_NUDGE_START )) # Validate structured output files, retry up to 3 times if missing/invalid SANITIZED_TAG=$(echo "${PAYLOAD_TAG}" | tr '.' '-') -VALIDATE_YAML=$(find /home/claude/.claude -name "validate.py" -path "*/payload-results-yaml/*" 2>/dev/null | head -1) -VALIDATE_JSON=$(find /home/claude/.claude -name "validate.py" -path "*/payload-autodl-json/*" 2>/dev/null | head -1) - -if [[ -z "${VALIDATE_YAML}" || -z "${VALIDATE_JSON}" ]]; then - echo "ERROR: validation scripts not found in the ai-helpers plugin installation." - exit 1 -fi +VALIDATE_YAML="/opt/ai-helpers/plugins/ci/skills/payload-results-yaml/scripts/validate.py" +VALIDATE_JSON="/opt/ai-helpers/plugins/ci/skills/payload-autodl-json/scripts/validate.py" for attempt in 1 2 3; do YAML_OK=false From ef64a58a54997536a1430e204dffbb5bf667fde8 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 08:03:02 -0400 Subject: [PATCH 07/13] Fix snapshot archive path The snapshot script creates a nested directory structure (e.g. 4.22/nightly/...) not a flat directory named by the payload tag. Archive the entire snapshot directory contents instead. Co-Authored-By: Claude Opus 4.6 --- .../payload/agent/openshift-claude-payload-agent-commands.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 2bff78cbc9d3b..7ac2a797a6328 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -173,7 +173,7 @@ python3 "${SNAPSHOT_SCRIPT}" "${PAYLOAD_TAG}" --output-dir "${SNAPSHOT_DIR}" PHASE_SNAPSHOT_DURATION=$(( $(date +%s) - PHASE_SNAPSHOT_START )) echo "Snapshot created in ${PHASE_SNAPSHOT_DURATION}s at ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" echo "Archiving payload snapshot to artifacts..." -tar -czf "${ARTIFACT_DIR}/snapshot-${PAYLOAD_TAG}.tar.gz" -C "${SNAPSHOT_DIR}" "${PAYLOAD_TAG}" +tar -czf "${ARTIFACT_DIR}/snapshot-${PAYLOAD_TAG}.tar.gz" -C "${SNAPSHOT_DIR}" . # Ensure reports and session logs are copied to artifacts even if the script exits early copy_reports() { From beee7a02dff5fc0cc028fe7042c2b95412bbd8dc Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 08:09:28 -0400 Subject: [PATCH 08/13] Fix payload agent: hardcode script paths, archive snapshot, fix snapshot-dir - Hardcode /opt/ai-helpers paths for payload_snapshot.py and validate.py - Archive snapshot tarball to ARTIFACT_DIR immediately after creation - Fix --snapshot-dir to pass the root snapshot dir, not a tag-named subdir - Move copy_reports trap before snapshot so artifacts are captured on failure - Handle transient release API failures in the poll loop gracefully - Switch test payload to 4.22.0-0.nightly-2026-06-02-214116 Co-Authored-By: Claude Opus 4.6 --- .../release/openshift-release-main__temp.yaml | 2 +- ...openshift-claude-payload-agent-commands.sh | 34 +++++++++++-------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/ci-operator/config/openshift/release/openshift-release-main__temp.yaml b/ci-operator/config/openshift/release/openshift-release-main__temp.yaml index 2b5ed920694f2..1a81e5c0ede06 100644 --- a/ci-operator/config/openshift/release/openshift-release-main__temp.yaml +++ b/ci-operator/config/openshift/release/openshift-release-main__temp.yaml @@ -8,7 +8,7 @@ tests: cron: '@yearly' steps: env: - PAYLOAD_TAG: 4.22.0-0.nightly-2026-06-01-074812 + PAYLOAD_TAG: 4.22.0-0.nightly-2026-06-02-214116 workflow: openshift-claude-payload zz_generated_metadata: branch: main diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 7ac2a797a6328..221de94c5d664 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -76,7 +76,13 @@ echo "" while true; do POLL_COUNT=$((POLL_COUNT + 1)) - RELEASE_JSON=$(curl -sf "${API_URL}") + RELEASE_JSON=$(curl -sf "${API_URL}" || true) + if [[ -z "${RELEASE_JSON}" ]]; then + echo " Warning: Failed to fetch release API. Retrying next poll..." + sleep ${POLL_INTERVAL} + ELAPSED=$((ELAPSED + POLL_INTERVAL)) + continue + fi PENDING=$(echo "${RELEASE_JSON}" | jq '[.results.blockingJobs // {} | to_entries[] | select(.value.state == "Pending")] | length') FAILED=$(echo "${RELEASE_JSON}" | jq '[.results.blockingJobs // {} | to_entries[] | select(.value.state == "Failed")] | length') SUCCEEDED=$(echo "${RELEASE_JSON}" | jq '[.results.blockingJobs // {} | to_entries[] | select(.value.state == "Succeeded")] | length') @@ -163,18 +169,6 @@ echo "Invoking Claude to analyze payload ${PAYLOAD_TAG}..." WORKDIR=$(mktemp -d /tmp/claude-analysis-XXXXXX) cd "${WORKDIR}" -# Create payload snapshot deterministically (no tokens spent) -echo "" -echo "=== Creating payload snapshot ===" -SNAPSHOT_SCRIPT="/opt/ai-helpers/plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py" -SNAPSHOT_DIR="${WORKDIR}/snapshot" -PHASE_SNAPSHOT_START=$(date +%s) -python3 "${SNAPSHOT_SCRIPT}" "${PAYLOAD_TAG}" --output-dir "${SNAPSHOT_DIR}" -PHASE_SNAPSHOT_DURATION=$(( $(date +%s) - PHASE_SNAPSHOT_START )) -echo "Snapshot created in ${PHASE_SNAPSHOT_DURATION}s at ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" -echo "Archiving payload snapshot to artifacts..." -tar -czf "${ARTIFACT_DIR}/snapshot-${PAYLOAD_TAG}.tar.gz" -C "${SNAPSHOT_DIR}" . - # Ensure reports and session logs are copied to artifacts even if the script exits early copy_reports() { if [[ -d "${WORKDIR:-}" ]]; then @@ -195,6 +189,18 @@ copy_reports() { } trap copy_reports EXIT TERM INT +# Create payload snapshot deterministically (no tokens spent) +echo "" +echo "=== Creating payload snapshot ===" +SNAPSHOT_SCRIPT="/opt/ai-helpers/plugins/ci/skills/payload-snapshot/scripts/payload_snapshot.py" +SNAPSHOT_DIR="${WORKDIR}/snapshot" +PHASE_SNAPSHOT_START=$(date +%s) +python3 "${SNAPSHOT_SCRIPT}" "${PAYLOAD_TAG}" --output-dir "${SNAPSHOT_DIR}" +PHASE_SNAPSHOT_DURATION=$(( $(date +%s) - PHASE_SNAPSHOT_START )) +echo "Snapshot created in ${PHASE_SNAPSHOT_DURATION}s" +echo "Archiving payload snapshot to artifacts..." +tar -czf "${ARTIFACT_DIR}/snapshot-${PAYLOAD_TAG}.tar.gz" -C "${SNAPSHOT_DIR}" . + # Install the must-gather plugin for analyzing must-gather archives echo "Installing must-gather plugin..." claude plugin install must-gather@ai-helpers @@ -216,7 +222,7 @@ timeout 3600 claude \ --output-format stream-json \ --max-turns 100 \ --append-system-prompt "${SYSTEM_PROMPT}" \ - -p "/ci:payload-analysis ${PAYLOAD_TAG} --snapshot-dir ${SNAPSHOT_DIR}/${PAYLOAD_TAG}" \ + -p "/ci:payload-analysis ${PAYLOAD_TAG} --snapshot-dir ${SNAPSHOT_DIR}" \ --verbose 2>&1 | tee "${ARTIFACT_DIR}/claude-output.log" || CLAUDE_EXIT=$? # If Claude timed out (exit 124), nudge it to wrap up with a shorter timeout From 7c5976a61f5812f42d6e9259bdd288d3252adc86 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 08:10:48 -0400 Subject: [PATCH 09/13] Fix --snapshot-dir to point to directory containing summary.json The skill expects --snapshot-dir to be the directory with summary.json, which is nested under version/stream (e.g. snapshot/4.22/nightly/), not the root snapshot directory. Find summary.json after snapshot creation and pass its parent directory. Co-Authored-By: Claude Opus 4.6 --- .../payload/agent/openshift-claude-payload-agent-commands.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 221de94c5d664..71d9b8dc5efb7 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -201,6 +201,9 @@ echo "Snapshot created in ${PHASE_SNAPSHOT_DURATION}s" echo "Archiving payload snapshot to artifacts..." tar -czf "${ARTIFACT_DIR}/snapshot-${PAYLOAD_TAG}.tar.gz" -C "${SNAPSHOT_DIR}" . +SNAPSHOT_DATA_DIR=$(dirname "$(find "${SNAPSHOT_DIR}" -name summary.json -print -quit)") +echo "Snapshot data dir: ${SNAPSHOT_DATA_DIR}" + # Install the must-gather plugin for analyzing must-gather archives echo "Installing must-gather plugin..." claude plugin install must-gather@ai-helpers @@ -222,7 +225,7 @@ timeout 3600 claude \ --output-format stream-json \ --max-turns 100 \ --append-system-prompt "${SYSTEM_PROMPT}" \ - -p "/ci:payload-analysis ${PAYLOAD_TAG} --snapshot-dir ${SNAPSHOT_DIR}" \ + -p "/ci:payload-analysis ${PAYLOAD_TAG} --snapshot-dir ${SNAPSHOT_DATA_DIR}" \ --verbose 2>&1 | tee "${ARTIFACT_DIR}/claude-output.log" || CLAUDE_EXIT=$? # If Claude timed out (exit 124), nudge it to wrap up with a shorter timeout From 5b62067afc7b592876562e0b76f917629e6335da Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 08:36:07 -0400 Subject: [PATCH 10/13] Fix validation filenames to use PAYLOAD_TAG directly SANITIZED_TAG replaced dots with dashes, but Claude writes output files using the original tag with dots. The validate scripts were looking for the wrong filenames and always failing. Co-Authored-By: Claude Opus 4.6 --- .../payload/agent/openshift-claude-payload-agent-commands.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 71d9b8dc5efb7..f514d35f9081e 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -246,7 +246,6 @@ fi PHASE_NUDGE_DURATION=$(( $(date +%s) - PHASE_NUDGE_START )) # Validate structured output files, retry up to 3 times if missing/invalid -SANITIZED_TAG=$(echo "${PAYLOAD_TAG}" | tr '.' '-') VALIDATE_YAML="/opt/ai-helpers/plugins/ci/skills/payload-results-yaml/scripts/validate.py" VALIDATE_JSON="/opt/ai-helpers/plugins/ci/skills/payload-autodl-json/scripts/validate.py" @@ -254,10 +253,10 @@ for attempt in 1 2 3; do YAML_OK=false JSON_OK=false - if python3 "${VALIDATE_YAML}" "payload-results-${SANITIZED_TAG}.yaml"; then + if python3 "${VALIDATE_YAML}" "payload-results-${PAYLOAD_TAG}.yaml"; then YAML_OK=true fi - if python3 "${VALIDATE_JSON}" "payload-analysis-${SANITIZED_TAG}-autodl.json"; then + if python3 "${VALIDATE_JSON}" "payload-analysis-${PAYLOAD_TAG}-autodl.json"; then JSON_OK=true fi From 5f473c990783675e73a8f93498f9dffd1d232ab0 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 08:41:25 -0400 Subject: [PATCH 11/13] Find validation files by prefix instead of exact name Claude may write filenames with slightly different formatting. Find by glob prefix instead of constructing the exact name. Co-Authored-By: Claude Opus 4.6 --- .../agent/openshift-claude-payload-agent-commands.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index f514d35f9081e..346afdc0c024f 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -253,10 +253,13 @@ for attempt in 1 2 3; do YAML_OK=false JSON_OK=false - if python3 "${VALIDATE_YAML}" "payload-results-${PAYLOAD_TAG}.yaml"; then + RESULTS_YAML=$(find . -maxdepth 1 -name "payload-results-*.yaml" -print -quit) + RESULTS_JSON=$(find . -maxdepth 1 -name "payload-analysis-*-autodl.json" -print -quit) + + if [[ -n "${RESULTS_YAML}" ]] && python3 "${VALIDATE_YAML}" "${RESULTS_YAML}"; then YAML_OK=true fi - if python3 "${VALIDATE_JSON}" "payload-analysis-${PAYLOAD_TAG}-autodl.json"; then + if [[ -n "${RESULTS_JSON}" ]] && python3 "${VALIDATE_JSON}" "${RESULTS_JSON}"; then JSON_OK=true fi From 8c0c89a7989d6ca87fecffb3789f20c74e73fb29 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 09:24:05 -0400 Subject: [PATCH 12/13] Remove temp payload agent job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Testing complete — the payload agent works correctly. Co-Authored-By: Claude Opus 4.6 --- .../release/openshift-release-main__temp.yaml | 17 ----- .../openshift-release-main-periodics.yaml | 74 ------------------- 2 files changed, 91 deletions(-) delete mode 100644 ci-operator/config/openshift/release/openshift-release-main__temp.yaml diff --git a/ci-operator/config/openshift/release/openshift-release-main__temp.yaml b/ci-operator/config/openshift/release/openshift-release-main__temp.yaml deleted file mode 100644 index 1a81e5c0ede06..0000000000000 --- a/ci-operator/config/openshift/release/openshift-release-main__temp.yaml +++ /dev/null @@ -1,17 +0,0 @@ -resources: - '*': - requests: - cpu: 100m - memory: 200Mi -tests: -- as: claude-payload-agent - cron: '@yearly' - steps: - env: - PAYLOAD_TAG: 4.22.0-0.nightly-2026-06-02-214116 - workflow: openshift-claude-payload -zz_generated_metadata: - branch: main - org: openshift - repo: release - variant: temp diff --git a/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml b/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml index 25317f9dd8f4f..0a2abed76876e 100644 --- a/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml +++ b/ci-operator/jobs/openshift/release/openshift-release-main-periodics.yaml @@ -304409,77 +304409,3 @@ periodics: - name: github-app-credentials secret: secretName: openshift-prow-github-app -- agent: kubernetes - cluster: build09 - cron: '@yearly' - decorate: true - decoration_config: - skip_cloning: true - extra_refs: - - base_ref: main - org: openshift - repo: release - labels: - ci-operator.openshift.io/variant: temp - ci.openshift.io/generator: prowgen - ci.openshift.io/no-builds: "true" - pj-rehearse.openshift.io/can-be-rehearsed: "true" - name: periodic-ci-openshift-release-main-temp-claude-payload-agent - spec: - containers: - - args: - - --gcs-upload-secret=/secrets/gcs/service-account.json - - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson - - --lease-server-credentials-file=/etc/boskos/credentials - - --report-credentials-file=/etc/report/credentials - - --target=claude-payload-agent - - --variant=temp - command: - - ci-operator - env: - - name: HTTP_SERVER_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest - imagePullPolicy: Always - name: "" - ports: - - containerPort: 8080 - name: http - resources: - requests: - cpu: 10m - volumeMounts: - - mountPath: /etc/boskos - name: boskos - readOnly: true - - mountPath: /secrets/gcs - name: gcs-credentials - readOnly: true - - mountPath: /secrets/manifest-tool - name: manifest-tool-local-pusher - readOnly: true - - mountPath: /etc/pull-secret - name: pull-secret - readOnly: true - - mountPath: /etc/report - name: result-aggregator - readOnly: true - serviceAccountName: ci-operator - volumes: - - name: boskos - secret: - items: - - key: credentials - path: credentials - secretName: boskos-credentials - - name: manifest-tool-local-pusher - secret: - secretName: manifest-tool-local-pusher - - name: pull-secret - secret: - secretName: registry-pull-credentials - - name: result-aggregator - secret: - secretName: result-aggregator From 3fadd125194c2f233da6288961f60de59db781a5 Mon Sep 17 00:00:00 2001 From: Stephen Benjamin Date: Wed, 3 Jun 2026 09:56:33 -0400 Subject: [PATCH 13/13] Change "Agent:" to "Model:" in Slack messages Co-Authored-By: Claude Opus 4.6 --- .../payload/agent/openshift-claude-payload-agent-commands.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh index 346afdc0c024f..4bb470dc44134 100644 --- a/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh +++ b/ci-operator/step-registry/openshift/claude/payload/agent/openshift-claude-payload-agent-commands.sh @@ -114,7 +114,7 @@ while true; do SLACK_TEXT=":green-check: *Payload Accepted for <${PAYLOAD_URL}|${PAYLOAD_TAG}>* All ${TOTAL} blocking jobs succeeded.${RETRY_INFO} -_Agent: ${CLAUDE_MODEL}_" +_Model: ${CLAUDE_MODEL}_" set +x jq -n --arg text "$SLACK_TEXT" '{text: $text}' | \ @@ -382,7 +382,7 @@ if [[ -n "${SLACK_WEBHOOK}" ]]; then ${SUMMARY:-No summary available.} <${PROW_JOB_URL}|:point_right: View Full Analysis Report> -_Agent: ${CLAUDE_MODEL}_" +_Model: ${CLAUDE_MODEL}_" set +x jq -n --arg text "$SLACK_TEXT" '{text: $text}' | \