| name | fix-cve |
| description | Autonomously resolve Python CVE tickets from Jira - groups CVEs by package+branch, creates PRs, monitors Konflux builds, and updates tickets. Requires Atlassian MCP. |
Fix CVE skill
Execute the complete CVE resolution workflow autonomously — from Jira triage
through fix, PR creation, Konflux build monitoring, and summary message for Slack. No questions asked.
Prerequisites
- Atlassian MCP configured for Jira access (OAuth recommended)
- GitHub CLI (
gh) installed and authenticated
- Write access to
red-hat-data-services/notebooks repository
Commands
| Command | Description |
|---|
/fix-cve | Fix one CVE group (highest priority by due date) |
/fix-cve --count N | Fix N CVE groups |
/fix-cve RHAIENG-XXXX | Fix specific ticket (and related CVEs) |
/fix-cve status | Show assigned CVEs and their status |
/fix-cve pr-status | Check all open CVE PRs, build status, failures |
/fix-cve build-konflux IMAGE | Trigger Konflux build for specific image |
Core Concept: CVE Groups
What is a CVE Group?
A CVE Group = All tickets for the same package + same branch.
Example: If Pillow has 5 CVE tickets for rhoai-2.25:
- RHAIENG-4594 (CVE-2026-40192)
- RHAIENG-4595 (CVE-2026-40193)
- RHAIENG-4596 (CVE-2026-40194)
These form ONE group and can be fixed with ONE PR.
Important: Before grouping, verify that a single version constraint satisfies ALL CVEs in the group by checking each CVE's advisory for the minimum fixed version, then use the highest required version.
Why Group?
- Efficiency: One PR closes multiple tickets
- Consistency: Same fix applied to all related CVEs
- Reduced noise: Fewer PRs to review
/fix-cve — Main Workflow (One Group)
Default Behavior
By default, /fix-cve processes only the highest-priority CVE group (earliest due date).
JQL Query (Ordered by Due Date)
project = RHAIENG
AND component = Notebooks
AND labels IN (CVE)
AND status NOT IN (Closed, Resolved)
AND assignee IS EMPTY
ORDER BY duedate ASC
Note: This query only fetches unassigned tickets. If a workflow fails after assigning tickets, use /fix-cve status to see assigned tickets and retry them manually, or unassign them to make them available for the next run.
Grouping Logic
After fetching CVEs, group by package:branch:
groups = {
"pillow:rhoai-2.25": [RHAIENG-4594, RHAIENG-4595, ...],
"tornado:rhoai-3.3": [RHAIENG-4278, RHAIENG-4279, ...],
}
Sort groups by earliest due date, process first group.
Processing Steps
1. Find highest-priority CVE group
2. Display group table
3. Assign all tickets in group
4. Validate PACKAGE and BRANCH values (alphanumeric, dots, hyphens only)
5. Checkout: git checkout -b "fix/cve-${PACKAGE}-${BRANCH}" "rds/${BRANCH}"
6. Add constraint to dependencies/cve-constraints.txt
7. Run: make refresh-lock-files (STOP on failure, log error, unassign tickets)
8. Commit & push (STOP on failure, log error)
9. Create PR: gh pr create --base "$BRANCH" (STOP on failure, log error)
10. Comment on ALL Jira tickets with PR link
11. Trigger Konflux build for affected images
12. Log results to docs/cves/logs/
Failure Handling: If any step fails (especially steps 7-9), stop processing the current group, log the failure with details, and continue to the next group if --count N was specified.
Display Format
┌─────────────────────────────────────────────────────────────────────┐
│ CVE GROUP: Pillow @ rhoai-2.25 (5 tickets) │
├────────────────┬─────────────────┬────────────┬────────────────────┤
│ Ticket │ CVE ID │ Due Date │ Status │
├────────────────┼─────────────────┼────────────┼────────────────────┤
│ RHAIENG-4594 │ CVE-2026-40192 │ 2026-05-14 │ Backlog │
│ RHAIENG-4595 │ CVE-2026-40193 │ 2026-05-20 │ Backlog │
└────────────────┴─────────────────┴────────────┴────────────────────┘
📦 Fix: pillow>=12.3.0 (verified against all CVE advisories)
🎯 Target: red-hat-data-services/notebooks @ rhoai-2.25
/fix-cve --count N — Multiple Groups
Process N CVE groups instead of just one.
/fix-cve --count 3
Creates up to N PRs (one per group).
/fix-cve pr-status — Monitor Open PRs
Check status of all CVE-related PRs.
What It Does
- List all open CVE PRs (by label or title pattern)
- Check CI/CD status (Konflux builds)
- Check review status
- Identify failures
Command
gh pr list --repo red-hat-data-services/notebooks \
--state open --search "CVE in:title" \
--json number,title,url,statusCheckRollup,reviews,author
Note: This searches by CVE in title to include PRs from all contributors, not just the current user.
Output Format
┌───────────────────────────────────────────────────────────────────────────┐
│ OPEN CVE PRs │
├───────┬─────────────────────────────┬────────────┬───────────┬───────────┤
│ PR │ Title │ Build │ Review │ Created │
├───────┼─────────────────────────────┼────────────┼───────────┼───────────┤
│ #2630 │ Fix CVE-2026-40192 Pillow │ ✅ Passed │ ✅ Approved│ 2 days ago│
│ #2631 │ Fix CVE-2026-48526 PyJWT │ 🔄 Running │ ⏳ Pending │ 1 day ago │
│ #2632 │ Fix CVE-2026-35536 Tornado │ ❌ Failed │ ⏳ Pending │ 3 hours │
└───────┴─────────────────────────────┴────────────┴───────────┴───────────┘
❌ FAILED BUILDS:
• PR #2632: Konflux build failed
- Error: dependency conflict with codeflare-sdk
- Logs: https://github.com/.../actions/runs/12345
/fix-cve build-konflux IMAGE — Trigger Build
Manually trigger a Konflux build for a specific image.
/fix-cve build-konflux jupyter-pytorch-cuda-ubi9
Implementation
gh workflow run check-image-availability.yaml \
--repo red-hat-data-services/notebooks \
--ref "$BRANCH" \
-f image=jupyter-pytorch-cuda-ubi9
gh run list --workflow=check-image-availability.yaml --limit 1 --json status,conclusion
Note: Always use the same $BRANCH variable used for PR creation to ensure the build targets the correct release branch.
Guardrails
Fully Autonomous Execution
- NEVER ask "Would you like me to proceed?"
- NEVER offer "Next Steps" options (1, 2, 3...)
- All operations are pre-approved
Handle ALL CVEs
- Attempt even "complex" or "blocked" CVEs
- Log failures and continue to next
One PR per CVE Group
- Group by package + branch
- Single PR closes multiple tickets
Key Files
| File | Purpose |
|---|
dependencies/cve-constraints.txt | Add version constraints for CVE fixes |
docs/cves/logs/ | Session logs (APPEND only) |
Logging
Always APPEND to log file with session headers:
---
## Session: YYYY-MM-DD HH:MM
**User**: [username]
**Sprint**: [sprint]
### CVE Group: Pillow @ rhoai-2.25
- Tickets: RHAIENG-4594, RHAIENG-4595
- Fix: pillow>=12.3.0
- PR: #2630
- Konflux: ✅ Passed
---
Slack Summary (At End)
After completing the workflow, output a single summary message that can be copied to Slack:
📋 CVE Resolution Summary
✅ Fixed:
• RHAIENG-4594, RHAIENG-4595 (Pillow) → PR #2630 [rhoai-2.25]
• RHAIENG-4278 (Tornado) → PR #2631 [rhoai-3.3]
❌ Failed:
• RHAIENG-4277 (ONNX) → Dependency conflict with numpy
🔗 PRs for Review:
• https://github.com/red-hat-data-services/notebooks/pull/2630
• https://github.com/red-hat-data-services/notebooks/pull/2631
Important: Output this as ONE complete message block at the end, not incrementally.
When To Stop
ONLY stop for:
- Fatal MCP connection error
- No CVEs found
Continue through:
- Individual failures → Log and continue
- Build failures → Log and continue