Skip to content

USHIFT-7425: Update LVMS CI Doctor with recent updates to MicroShift CI Doctor - #244

Merged
openshift-merge-bot[bot] merged 11 commits into
openshift-eng:mainfrom
pmtk:sync-lvms-doctah
Jul 29, 2026
Merged

USHIFT-7425: Update LVMS CI Doctor with recent updates to MicroShift CI Doctor#244
openshift-merge-bot[bot] merged 11 commits into
openshift-eng:mainfrom
pmtk:sync-lvms-doctah

Conversation

@pmtk

@pmtk pmtk commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added an automated Prow job root-cause analyzer that produces structured JSON failure reports with severity, confidence, stack layer, and supporting evidence.
  • Improvements

    • Updated LVMS CI and Microshift CI RCA tooling to validate analyzer output against a strict schema (including evidence checks) via a stop-hook.
    • Refreshed analyzer/workflow guidance for agent-driven artifact handling (local artifacts or job URLs), more readable reporting, and optional raw JSON saving.
    • Bumped plugin versions (lvms-ci to 1.3.0, microshift-ci to 1.5.3).

@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 28, 2026
@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pmtk

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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 28, 2026
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@pmtk, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 16 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c5288a1e-c7b3-4c6a-989f-58a090fe5144

📥 Commits

Reviewing files that changed from the base of the PR and between b2d8469 and 0af92f4.

📒 Files selected for processing (10)
  • .claude-plugin/marketplace.json
  • plugins/lvms-ci/.claude-plugin/plugin.json
  • plugins/lvms-ci/.claude/settings.json
  • plugins/lvms-ci/agents/prow-job-analyzer.md
  • plugins/lvms-ci/skills/doctor/SKILL.md
  • plugins/lvms-ci/skills/prow-job/SKILL.md
  • plugins/microshift-ci/.claude-plugin/plugin.json
  • plugins/microshift-ci/.claude/settings.json
  • plugins/microshift-ci/skills/prow-job/SKILL.md
  • plugins/shared/scripts/validate-rca-output.py

Walkthrough

Changes

Prow RCA workflow

Layer / File(s) Summary
Analyzer contract
plugins/lvms-ci/agents/prow-job-analyzer.md
Defines artifact investigation rules and a structured JSON output for up to 10 independent failures.
RCA output validation
plugins/shared/scripts/validate-rca-output.py, plugins/lvms-ci/scripts/validate-rca-output.py, plugins/microshift-ci/scripts/validate-rca-output.py, plugins/lvms-ci/.claude/settings.json
Adds shared schema and evidence validation, exposes it through plugin script links, and invokes it on analyzer completion.
Agent-based skill integration
plugins/lvms-ci/skills/prow-job/SKILL.md, plugins/lvms-ci/skills/doctor/SKILL.md, plugins/microshift-ci/skills/prow-job/SKILL.md
Updates workflows and permissions to use the analyzer agent and format its JSON results.
Plugin metadata
.claude-plugin/marketplace.json, plugins/*/.claude-plugin/plugin.json
Bumps the LVMS and MicroShift plugin versions.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ai-Attribution ⚠️ Warning PR commits contain 11 Claude 'Co-Authored-By' trailers, and no 'Assisted-by'/'Generated-by' trailers were found. Replace AI-related Co-Authored-By trailers with Red Hat Assisted-by or Generated-by trailers on the affected commits.
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main theme: bringing LVMS CI Doctor in line with newer MicroShift CI Doctor updates.
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-Weak-Crypto ✅ Passed Changed files are docs/config plus a Python validator using json/os/re/sys only; no MD5/SHA1/DES/RC4/3DES/Blowfish, ECB, custom crypto, or secret comparisons found.
Container-Privileges ✅ Passed Changed files are docs/config/scripts only; no container/K8s manifests or privileged, hostPID, hostNetwork, hostIPC, SYS_ADMIN, or allowPrivilegeEscalation fields were added.
No-Sensitive-Data-In-Logs ✅ Passed New hook/validator output only emits fixed warnings/status and structured schema errors; no sensitive literals or secret-bearing logging were added.
No-Hardcoded-Secrets ✅ Passed Scanned modified files; no API keys, tokens, passwords, private keys, embedded credentials, or long base64 literals found.
No-Injection-Vectors ✅ Passed No listed injection primitives were introduced in the changed code paths; searches found none of shell=True, eval/exec, pickle.loads, yaml.load, os.system, or dangerous innerHTML use.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@pmtk pmtk changed the title https://redhat.atlassian.net/browse/USHIFT-7425 USHIFT-7425: Update LVMS CI Doctor with recent updates to MicroShift CI Doctor Jul 28, 2026
@pmtk
pmtk force-pushed the sync-lvms-doctah branch from 9157a17 to 53286ee Compare July 28, 2026 12:09

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
plugins/lvms-ci/skills/prow-job/SKILL.md (1)

74-84: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the URL-input workflow use the initialized variables.

Step 0 sets JOB_URL, but Step 1 builds GCS_PATH from undefined PROW_URL; URL-based analysis therefore downloads from an invalid source. Also create <WORKDIR> before mktemp -d <WORKDIR>/..., otherwise a first-time invocation fails. Use ${JOB_URL} consistently and add mkdir -p <WORKDIR>.

🤖 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/lvms-ci/skills/prow-job/SKILL.md` around lines 74 - 84, Update the
URL-input workflow in SKILL.md to derive GCS_PATH from the initialized JOB_URL
variable, replacing the undefined PROW_URL reference. Before invoking mktemp for
the temporary analysis directory, create WORKDIR with mkdir -p.
plugins/lvms-ci/skills/doctor/SKILL.md (1)

76-96: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Define an inline failure policy for each analyzer agent.

Specify how to handle an Agent failure or validation block before writing its JSON: retry policy, how to record the affected job, and whether finalization may continue without that result. Step 3 is mandatory, so leaving the result set unspecified makes aggregation behavior unreliable.

As per path instructions, “Flag missing edge cases or safety guards as severity ‘high’.” Based on learnings, failure policies should be co-located with the relevant tool invocation.

🤖 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/lvms-ci/skills/doctor/SKILL.md` around lines 76 - 96, Add an inline
failure policy alongside each analyzer Agent invocation in the Step 2
instructions: define validation handling, a bounded retry policy, and how to
record jobs whose results remain unavailable after retries. State explicitly
that Step 3 must continue with those jobs marked as failed or missing, rather
than silently omitting them, and ensure the policy is co-located with the tool
invocation guidance.

Sources: Path instructions, Learnings

🤖 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/lvms-ci/.claude-plugin/plugin.json`:
- Line 4: Update the matching lvms-ci entry in marketplace.json to version
1.3.0, keeping it synchronized with the version declared in the plugin manifest
and ensuring the marketplace file is included in the change.

In `@plugins/lvms-ci/agents/prow-job-analyzer.md`:
- Around line 131-140: Update the RAW_ERROR rules to define an exact
deterministic truncation: after removing the specified leading timestamp prefix,
retain exactly the first 150 characters when the error exceeds that length.
Replace the subjective “~150 characters” and “keep the distinctive part” wording
while preserving the requirement to copy one primary error verbatim.

In `@plugins/shared/scripts/validate-rca-output.py`:
- Around line 152-214: Add tests for the validation flow centered on
validate_json_text and validate_message: include a valid RCA array, malformed
JSON, invalid schema values, and invalid evidence citations. Assert that valid
input produces no errors and each invalid case returns the expected validation
errors, following the repository’s existing test conventions.
- Around line 57-72: Update the evidence validation flow around the validator
function containing the path checks to accept the trusted artifacts directory,
canonicalize both the artifact root and evidence path, and reject evidence
containing traversal or resolving outside that root before any file existence
check or read. Preserve valid citations to files within the supplied artifacts
directory and pass the trusted root through all callers.
- Around line 118-180: Extend validate_entry to enforce the complete RCA schema:
require causal-chain cause, evidence, and quote values to be strings; require
every analysis_gaps and scenarios item to be a string; reject entry keys outside
the documented schema; and enforce the documented maximum of 10 entries in
validate_json_text before processing them. Preserve the existing required-field
and evidence validation errors while reporting each new violation consistently.

---

Outside diff comments:
In `@plugins/lvms-ci/skills/doctor/SKILL.md`:
- Around line 76-96: Add an inline failure policy alongside each analyzer Agent
invocation in the Step 2 instructions: define validation handling, a bounded
retry policy, and how to record jobs whose results remain unavailable after
retries. State explicitly that Step 3 must continue with those jobs marked as
failed or missing, rather than silently omitting them, and ensure the policy is
co-located with the tool invocation guidance.

In `@plugins/lvms-ci/skills/prow-job/SKILL.md`:
- Around line 74-84: Update the URL-input workflow in SKILL.md to derive
GCS_PATH from the initialized JOB_URL variable, replacing the undefined PROW_URL
reference. Before invoking mktemp for the temporary analysis directory, create
WORKDIR with mkdir -p.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: cef326e6-95fb-4b55-9ef0-3acb2f7a3268

📥 Commits

Reviewing files that changed from the base of the PR and between 932e3ca and 9157a17.

📒 Files selected for processing (10)
  • plugins/lvms-ci/.claude-plugin/plugin.json
  • plugins/lvms-ci/.claude/settings.json
  • plugins/lvms-ci/agents/prow-job-analyzer.md
  • plugins/lvms-ci/scripts/validate-rca-output.py
  • plugins/lvms-ci/skills/doctor/SKILL.md
  • plugins/lvms-ci/skills/prow-job/SKILL.md
  • plugins/microshift-ci/scripts/validate-rca-output.py
  • plugins/microshift-ci/scripts/validate-rca-output.py
  • plugins/microshift-ci/skills/prow-job/SKILL.md
  • plugins/shared/scripts/validate-rca-output.py

Comment thread plugins/lvms-ci/.claude-plugin/plugin.json
Comment on lines +131 to +140
### RAW_ERROR rules

The `raw_error` field is used by downstream scripts for deterministic grouping. Two runs analyzing the same job MUST produce the same `raw_error`. Keep it simple — fewer rules mean less room for variation.

1. **Copy-paste the exact error text** from the log — do NOT paraphrase, summarize, or reword
2. **Pick only ONE error** — the primary error that caused the step to fail. If multiple errors exist, pick the first fatal one.
3. **Only strip timestamps** — remove leading timestamps like `2026-04-01T06:21:48Z`. Keep everything else verbatim.
4. **Never concatenate multiple errors** — pick ONE error, not a semicolon-separated list
5. **Truncate to ~150 characters** if the raw message is very long — keep the distinctive part

@coderabbitai coderabbitai Bot Jul 28, 2026

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make raw_error truncation deterministic.

“~150 characters” and “keep the distinctive part” permit different truncation choices for the same log line, contradicting the requirement that repeated analyses produce identical values. Specify an exact transformation, such as stripping a defined timestamp prefix and retaining the first 150 characters.

🤖 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/lvms-ci/agents/prow-job-analyzer.md` around lines 131 - 140, Update
the RAW_ERROR rules to define an exact deterministic truncation: after removing
the specified leading timestamp prefix, retain exactly the first 150 characters
when the error exceeds that length. Replace the subjective “~150 characters” and
“keep the distinctive part” wording while preserving the requirement to copy one
primary error verbatim.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Let's not get into this right now - deterministic grouping is out of scope for this PR

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.

@pmtk, acknowledged. I’ll defer this for the current PR. Would you like me to open a follow-up issue to track deterministic raw_error grouping?

Comment on lines +57 to +72
m = re.fullmatch(r"(.+):(\d+)", evidence)
if not m:
return [f"{prefix}: evidence must be absolute_path:line_number, got: {evidence}"]

path, line_no = m.group(1), int(m.group(2))

if not os.path.isabs(path):
return [f"{prefix}: evidence path must be absolute, got: {path}"]

if not os.path.isfile(path):
return [f"{prefix}: evidence file not found: {path}"]

if any(path.endswith(ext) for ext in BINARY_EXTENSIONS):
return []

lines = _read_lines(path, file_cache)

@coderabbitai coderabbitai Bot Jul 28, 2026

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.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Restrict evidence reads to the supplied artifacts directory.

evidence comes from agent output, yet any absolute path is accepted and opened. A prompt-injected artifact can therefore make the hook read arbitrary host-readable files. Pass a trusted artifact root into the validator, resolve both paths, and reject citations outside that root before opening them.

As per path instructions, “Path traversal: canonicalize paths, reject ../”.

🤖 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/shared/scripts/validate-rca-output.py` around lines 57 - 72, Update
the evidence validation flow around the validator function containing the path
checks to accept the trusted artifacts directory, canonicalize both the artifact
root and evidence path, and reject evidence containing traversal or resolving
outside that root before any file existence check or read. Preserve valid
citations to files within the supplied artifacts directory and pass the trusted
root through all callers.

Source: Path instructions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The validator runs as a SubagentStop hook on the local machine. The "attacker" would be the AI agent itself, which already has full Bash access to the same filesystem. Path-restricting evidence validation adds no security boundary — the agent can already read any file.

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.

@pmtk, agreed. Since the analyzer already has equivalent local filesystem access through Bash, constraining this hook’s read-only evidence verification would not provide a meaningful security boundary. I’m withdrawing this finding.


✏️ Learnings added
Learnt from: pmtk
Repo: openshift-eng/edge-tooling PR: 244
File: plugins/shared/scripts/validate-rca-output.py:57-72
Timestamp: 2026-07-28T13:25:49.557Z
Learning: In openshift-eng/edge-tooling, `plugins/shared/scripts/validate-rca-output.py` runs as a local Claude `SubagentStop` hook for the prow-job-analyzer. That analyzer already has Bash access to the same local filesystem, so do not raise path-restriction findings solely because the validator reads absolute evidence paths from agent output; restricting those reads to an artifacts directory does not create a meaningful security boundary in this local execution model.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: kasturinarra
Repo: openshift-eng/edge-tooling PR: 186
File: plugins/shared/scripts/extract-index-image.sh:79-124
Timestamp: 2026-06-12T14:09:05.662Z
Learning: When reviewing scripts in plugins/shared/scripts (e.g., extract-index-image.sh and related helpers like create-report.py), don’t insist on path-traversal sanitization/validation for parameters such as `release` and `artifacts_dir` if they are only used by a local operator running these CLI tools and the values originate solely from `doctor.sh`’s own argument parsing (i.e., there’s no untrusted/external input path being fed into these parameters). In other words: skip “missing path validation” findings for this tooling when the trust boundary is the local shell operator, and only flag path-validation gaps if the scripts can receive untrusted data from outside this doctor.sh-controlled flow.

Comment on lines +118 to +180
chain = entry.get("causal_chain")
if not isinstance(chain, list):
if chain is not None:
errors.append(f"entry[{index}]: 'causal_chain' must be an array")
else:
errors.append(f"entry[{index}]: 'causal_chain' must be a non-empty array, got null")
elif not chain:
errors.append(f"entry[{index}]: 'causal_chain' must be a non-empty array")
else:
for ci, link in enumerate(chain):
if not isinstance(link, dict):
errors.append(f"entry[{index}].causal_chain[{ci}]: must be an object")
continue
if "cause" not in link:
errors.append(f"entry[{index}].causal_chain[{ci}]: missing required key 'cause'")
if "evidence" not in link:
errors.append(f"entry[{index}].causal_chain[{ci}]: missing required key 'evidence'")
if "quote" not in link:
errors.append(f"entry[{index}].causal_chain[{ci}]: missing required key 'quote'")
evidence = link.get("evidence", "")
quote = link.get("quote", "")
if isinstance(evidence, str) and evidence:
errors.extend(validate_evidence(
evidence, quote,
f"entry[{index}].causal_chain[{ci}]", file_cache))

for field in ("analysis_gaps", "scenarios"):
val = entry.get(field)
if val is not None and not isinstance(val, list):
errors.append(f"entry[{index}]: '{field}' must be an array")

return errors


def validate_json_text(text):
try:
data = json.loads(text)
except json.JSONDecodeError as e:
if "--- STRUCTURED SUMMARY ---" in text:
return [
"Output contains prose and STRUCTURED SUMMARY markers. "
"Your entire response must be a valid JSON array only — no prose, no markers."
]
return [f"Output is not valid JSON: {e}. Your entire response must be a valid JSON array."]

if isinstance(data, dict):
return [
"Output is a JSON object, not an array. "
"Wrap your output in [...] — single failures must still be a JSON array."
]
elif not isinstance(data, list):
return [f"Expected a JSON array, got {type(data).__name__}"]

if not data:
return ["JSON array is empty. Expected at least one failure entry."]

file_cache = {}
all_errors = []
for i, entry in enumerate(data):
if not isinstance(entry, dict):
all_errors.append(f"entry[{i}]: expected an object, got {type(entry).__name__}")
continue
all_errors.extend(validate_entry(entry, i, file_cache))

@coderabbitai coderabbitai Bot Jul 28, 2026

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Enforce the complete RCA schema before accepting output.

The validator accepts malformed values such as non-string causal-chain fields, non-string scenarios items, extra fields despite the “exactly these fields” contract, and more than the documented 10 entries. This allows invalid agent output into downstream aggregation/reporting; for example, ", ".join(scenarios) fails for non-string items. Validate link field types, array element types, unexpected keys, and the entry limit.

🤖 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/shared/scripts/validate-rca-output.py` around lines 118 - 180, Extend
validate_entry to enforce the complete RCA schema: require causal-chain cause,
evidence, and quote values to be strings; require every analysis_gaps and
scenarios item to be a string; reject entry keys outside the documented schema;
and enforce the documented maximum of 10 entries in validate_json_text before
processing them. Preserve the existing required-field and evidence validation
errors while reporting each new violation consistently.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Look now

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.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '=== Validator structure ==='
ast-grep outline plugins/shared/scripts/validate-rca-output.py --items all \
  --type function --view expanded

printf '%s\n' '=== Relevant schema checks ==='
rg -n -C 4 \
  'unexpected|extra|allowed|REQUIRED_FIELDS|causal_chain|analysis_gaps|scenarios|10|len\(data\)' \
  plugins/shared/scripts/validate-rca-output.py

printf '%s\n' '=== Candidate focused tests ==='
fd -t f . | rg '(test|validate-rca|rca-output)' || true

Length of output: 6559


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '=== Complete validation implementation ==='
sed -n '90,214p' plugins/shared/scripts/validate-rca-output.py

printf '%s\n' '=== Analyzer schema and entry-limit contract ==='
rg -n -C 5 \
  'exactly|fields|10|maximum|JSON array|causal_chain|analysis_gaps|scenarios' \
  plugins/lvms-ci/agents/prow-job-analyzer.md \
  plugins/microshift-ci/agents/prow-job-analyzer.md 2>/dev/null || true

printf '%s\n' '=== Working-tree state for the validator ==='
git diff --check -- plugins/shared/scripts/validate-rca-output.py
git status --short -- plugins/shared/scripts/validate-rca-output.py

Length of output: 29598


@pmtk, rechecked. The causal-chain field-type validation and string-item checks for analysis_gaps/scenarios are now addressed.

The finding still applies to two documented constraints:

  • Unexpected fields: validate_entry() checks only missing keys; it does not reject keys outside REQUIRED_FIELDS, while both analyzer schemas say each entry has exactly those fields.
  • Maximum entries: validate_json_text() processes arbitrary-length arrays; both analyzer schemas require at most 10 entries.

So I’m leaving the comment unresolved, narrowed to those two remaining validations.

Comment thread plugins/shared/scripts/validate-rca-output.py

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

🤖 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/lvms-ci/skills/prow-job/SKILL.md`:
- Around line 113-118: Update the Causal Chain template to iterate over every
item in causal_chain and render each link’s cause, evidence, and quote with
dynamically generated numbering. Remove the hard-coded causal_chain[0] and
causal_chain[1] references so non-empty chains, including a single-link chain,
render correctly.
- Around line 74-76: Create the computed WORKDIR parent directory before the
mktemp invocation in the URL-processing branch, and check that directory
creation succeeds before continuing. Keep the existing TMP assignment and
artifact-download flow unchanged after successful creation.
- Around line 74-76: Strengthen the local-directory branch in the input handling
step by explicitly validating that <ARGUMENTS> is a directory containing both
build-log.txt and finished.json before setting TMP or skipping download. If any
check fails, stop in that workflow step with an actionable error identifying the
missing or invalid artifact; leave URL handling unchanged.
- Around line 74-76: Update the URL handling in the prow-job workflow to use the
same variable throughout: the `JOB_URL` assigned in the input-type setup must be
the variable consumed when constructing `GCS_PATH` and invoking the downloader.
Remove the stale `PROW_URL` reference while preserving the existing
local-directory and URL input behavior.
- Around line 105-121: Update the “Display results” workflow to validate the
parsed agent output with plugins/shared/scripts/validate-rca-output.py before
formatting or saving any entries. Stop immediately when validation fails, and
proceed to the existing formatting and persistence steps only after the shared
RCA schema validation succeeds.
- Around line 123-125: Update the raw JSON save-path guidance in the prow-job
skill to strictly allow-list the derived RELEASE and JOB_ID identifiers,
rejecting empty or path-traversal values such as slashes and “..”. Before
writing, resolve the destination and verify it remains within <WORKDIR>/jobs;
only then save the file.

In `@plugins/shared/scripts/validate-rca-output.py`:
- Around line 124-137: Update the causal-chain validation loop around
validate_evidence so quote may be an empty string when the evidence is an image
supported by validate_evidence’s binary-extension exemption. Keep quote required
as a non-empty string for non-image evidence, while preserving the existing
evidence and type validation.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: f44577cb-73a6-4cd7-8f31-783d07eac841

📥 Commits

Reviewing files that changed from the base of the PR and between 9157a17 and b2d8469.

📒 Files selected for processing (12)
  • .claude-plugin/marketplace.json
  • plugins/lvms-ci/.claude-plugin/plugin.json
  • plugins/lvms-ci/.claude/settings.json
  • plugins/lvms-ci/agents/prow-job-analyzer.md
  • plugins/lvms-ci/scripts/validate-rca-output.py
  • plugins/lvms-ci/skills/doctor/SKILL.md
  • plugins/lvms-ci/skills/prow-job/SKILL.md
  • plugins/microshift-ci/.claude-plugin/plugin.json
  • plugins/microshift-ci/scripts/validate-rca-output.py
  • plugins/microshift-ci/scripts/validate-rca-output.py
  • plugins/microshift-ci/skills/prow-job/SKILL.md
  • plugins/shared/scripts/validate-rca-output.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • plugins/lvms-ci/.claude/settings.json
  • plugins/lvms-ci/skills/doctor/SKILL.md
  • plugins/microshift-ci/skills/prow-job/SKILL.md
  • plugins/lvms-ci/.claude-plugin/plugin.json
  • plugins/microshift-ci/scripts/validate-rca-output.py

Comment thread plugins/lvms-ci/skills/prow-job/SKILL.md
Comment thread plugins/lvms-ci/skills/prow-job/SKILL.md
Comment thread plugins/lvms-ci/skills/prow-job/SKILL.md Outdated
Comment thread plugins/lvms-ci/skills/prow-job/SKILL.md
Comment thread plugins/shared/scripts/validate-rca-output.py
@pmtk
pmtk force-pushed the sync-lvms-doctah branch from daf07f9 to afa2045 Compare July 28, 2026 13:48
@pmtk
pmtk marked this pull request as ready for review July 28, 2026 18:54
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 28, 2026

1. There are many setup and teardown stages so fatal errors may be buried by log output from the teardown phase. It is not common to find the fatal error at the end of the log.
2. You can quickly determine the failed step from the build-log.txt by reading the last `Running step ...` line before the container logs appear.
3. Check the CatalogSource and operator setup steps (`lvms-catalogsource`, `operatorhub-subscribe-lvm-operator`, `storage-create-lvm-cluster`) early — if any failed, the operator was never fully deployed and all downstream test failures are secondary.

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.

Investigation Principles and Tips have overlapping content

CatalogSource check — appears in both Investigation Principles ("Check the operator setup chain early...") and here ("Check the CatalogSource and operator setup steps..."). Nearly
identical wording.

@kasturinarra

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 29, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 33fef01 into openshift-eng:main Jul 29, 2026
7 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.

2 participants