Quay CVE Fix Controller
You manage a 4-phase CVE remediation workflow for Quay components. Each CVE
passes through find -> assess -> fix -> PR, with routing based on the
assessment verdict. PR creation is delegated to the /dev:pr skill from the
dev plugin — never create PRs inline.
Session Bootstrap
On first run, ensure Lola plugins are installed:
bash .claude/scripts/session-setup.sh
Then read component-repository-mappings.json and CLAUDE.md to load
component mappings and safety rules.
Phases
Find — the find skill
Query PROJQUAY Jira for open CVE tickets. Produce a list of CVEs with
their container names, packages, and target branches.
Assess — the assess skill (runs per CVE)
Triage each CVE: read advisory data, check if the package is in the
repo's dependency manifests, perform symbol-level analysis if needed,
and classify into a fix category.
Fix — the fix skill (runs per CVE, only for fixable categories)
Apply the version bump via /cve:fix-python, /cve:fix-go, or
/cve:fix-node (from cve plugin), or fix-konflux-stdlib for Go stdlib.
Run tests, verify the fix, and commit changes. Does NOT create the PR.
PR — the /dev:pr skill (from dev plugin), then /dev:poll
Create a pull request using /dev:pr, which handles fork management,
PR title validation against the CI regex, the standard description
template, and fallback ladder. Then start CI polling with /dev:poll.
After the PR is created, post a Jira comment with the PR URL.
Entry Points
The user can enter the workflow in several ways:
- "find CVEs" or "find" — run the find skill to discover open CVEs
- "PROJQUAY-XXXX" — jump directly to assess + fix for a specific ticket
- "CVE-YYYY-XXXXX" — assess + fix a specific CVE (look up the Jira ticket)
- "fix PROJQUAY-XXXX" — same as providing a ticket key
- "assess PROJQUAY-XXXX" — run only the assess phase (no fix)
Phase Execution
After Find
- Display the discovered CVEs grouped by component and priority
- Ask the user which CVEs to process, or process all open ones
- For each selected CVE, run assess then fix
After Assess (per CVE)
Read the verdict from the assess artifact and route:
| Verdict |
Action |
package-bump |
Proceed to fix skill, then /dev:pr |
go-stdlib |
Proceed to fix skill (targets quay-konflux-components), then /dev:pr |
rpm-layer |
Post Jira comment, log in artifacts, skip fix |
code-change-required |
Post Jira comment, escalate via AskUserQuestion |
not-affected |
Post VEX justification to Jira, log in artifacts, skip fix |
After Fix (per CVE)
- Read the fix report from
artifacts/quay-cvefix/fixes/fix-implementation-CVE-*.md
- Run the
/dev:pr skill to create the PR
/dev:pr reads the fix report to fill in the PR description template
- PR title must match the CI regex:
${JIRA_KEY}: fix(cve): ${CVE_ID} - ${PACKAGE}
/dev:pr handles fork workflow, title validation, and push
- Run
/dev:poll to start CI polling on the new PR
- Post a Jira comment with the PR URL and fix summary:
[Phase: Fix] CVE Remediation PR Created
CVE: <CVE_ID>
Package: <PACKAGE> <OLD_VERSION> -> <NEW_VERSION>
Branch: fix/cve-<ID>-<pkg>-<branch>-attempt-1
Fix Applied: <description of change>
Test Results: <PASSED / FAILED / NOT_RUN>
Post-fix Scan: <CVE resolved / still present>
PR: <full PR URL>
Backport Required: <yes/no + branch>
Next: PR ready for review.
- Move to the next CVE in the queue
Jira Comments
Post structured comments at each phase via:
bash .claude/scripts/jira-ops.sh comment <TICKET_KEY> "<text>"
Use the [Phase: <name>] prefix format. See CLAUDE.md for comment templates.
Branch Cascade Enforcement
Before fixing any CVE on a release branch (e.g., redhat-3.17):
- Check if the fix already exists on
master
- If not, fix on
master first, then backport to the release branch
- If the target is an older branch (e.g., 3.16), also verify 3.17 has the fix
- Skip EOL branches (3.11, 3.13) — log a warning
Processing Multiple CVEs
When processing a batch of CVEs:
- Group by upstream repo to minimize cloning
- Process each CVE independently (separate branch, separate PR)
- Clone once per repo, create worktrees per branch
- Clean up
/tmp clones after all CVEs are processed
Error Handling
- If assess fails (e.g., cannot reach advisory URL), log the error and
ask the user whether to proceed or skip
- If fix fails (e.g., test failures, scan still detects CVE), create the
PR anyway with failure details documented
- If PR creation fails, save the branch name and changes so the user
can create the PR manually
- Always clean up
/tmp clones, even on error
Final Summary
After processing all CVEs, print a summary:
=== CVE Fix Summary ===
PRs Created:
- CVE-YYYY-XXXXX (package): https://github.com/org/repo/pull/NNN
- ...
Skipped (not affected):
- CVE-YYYY-XXXXX: VEX justification added to PROJQUAY-XXXX
Skipped (RPM layer):
- CVE-YYYY-XXXXX: Base image package, Jira comment added
Escalated:
- CVE-YYYY-XXXXX: Code change required, needs team review
Errors:
- CVE-YYYY-XXXXX: <error description>
1---2name: controller-23description: Orchestrates the Quay CVE fix workflow through four phases: find, assess, fix, and PR. Routes each CVE based on the assessment verdict — only package-bump and go-stdlib CVEs proceed to fix and PR creation.4---56# Quay CVE Fix Controller78You manage a 4-phase CVE remediation workflow for Quay components. Each CVE9passes through find -> assess -> fix -> PR, with routing based on the10assessment verdict. PR creation is delegated to the `/dev:pr` skill from the11dev plugin — never create PRs inline.1213## Session Bootstrap1415On first run, ensure Lola plugins are installed:1617```bash18bash .claude/scripts/session-setup.sh19```2021Then read `component-repository-mappings.json` and `CLAUDE.md` to load22component mappings and safety rules.2324## Phases25261. **Find** — the `find` skill27 Query PROJQUAY Jira for open CVE tickets. Produce a list of CVEs with28 their container names, packages, and target branches.29302. **Assess** — the `assess` skill (runs per CVE)31 Triage each CVE: read advisory data, check if the package is in the32 repo's dependency manifests, perform symbol-level analysis if needed,33 and classify into a fix category.34353. **Fix** — the `fix` skill (runs per CVE, only for fixable categories)36 Apply the version bump via `/cve:fix-python`, `/cve:fix-go`, or37 `/cve:fix-node` (from cve plugin), or `fix-konflux-stdlib` for Go stdlib.38 Run tests, verify the fix, and commit changes. Does NOT create the PR.39404. **PR** — the `/dev:pr` skill (from dev plugin), then `/dev:poll`41 Create a pull request using `/dev:pr`, which handles fork management,42 PR title validation against the CI regex, the standard description43 template, and fallback ladder. Then start CI polling with `/dev:poll`.44 After the PR is created, post a Jira comment with the PR URL.4546## Entry Points4748The user can enter the workflow in several ways:4950- **"find CVEs"** or **"find"** — run the find skill to discover open CVEs51- **"PROJQUAY-XXXX"** — jump directly to assess + fix for a specific ticket52- **"CVE-YYYY-XXXXX"** — assess + fix a specific CVE (look up the Jira ticket)53- **"fix PROJQUAY-XXXX"** — same as providing a ticket key54- **"assess PROJQUAY-XXXX"** — run only the assess phase (no fix)5556## Phase Execution5758### After Find59601. Display the discovered CVEs grouped by component and priority612. Ask the user which CVEs to process, or process all open ones623. For each selected CVE, run assess then fix6364### After Assess (per CVE)6566Read the verdict from the assess artifact and route:6768| Verdict | Action |69|---------|--------|70| `package-bump` | Proceed to fix skill, then `/dev:pr` |71| `go-stdlib` | Proceed to fix skill (targets quay-konflux-components), then `/dev:pr` |72| `rpm-layer` | Post Jira comment, log in artifacts, skip fix |73| `code-change-required` | Post Jira comment, escalate via AskUserQuestion |74| `not-affected` | Post VEX justification to Jira, log in artifacts, skip fix |7576### After Fix (per CVE)77781. Read the fix report from `artifacts/quay-cvefix/fixes/fix-implementation-CVE-*.md`792. Run the `/dev:pr` skill to create the PR80 - `/dev:pr` reads the fix report to fill in the PR description template81 - PR title must match the CI regex: `${JIRA_KEY}: fix(cve): ${CVE_ID} - ${PACKAGE}`82 - `/dev:pr` handles fork workflow, title validation, and push833. Run `/dev:poll` to start CI polling on the new PR844. Post a Jira comment with the PR URL and fix summary:8586```text87[Phase: Fix] CVE Remediation PR Created8889CVE: <CVE_ID>90Package: <PACKAGE> <OLD_VERSION> -> <NEW_VERSION>91Branch: fix/cve-<ID>-<pkg>-<branch>-attempt-19293Fix Applied: <description of change>94Test Results: <PASSED / FAILED / NOT_RUN>95Post-fix Scan: <CVE resolved / still present>9697PR: <full PR URL>98Backport Required: <yes/no + branch>99100Next: PR ready for review.101```1021035. Move to the next CVE in the queue104105## Jira Comments106107Post structured comments at each phase via:108109```bash110bash .claude/scripts/jira-ops.sh comment <TICKET_KEY> "<text>"111```112113Use the `[Phase: <name>]` prefix format. See CLAUDE.md for comment templates.114115## Branch Cascade Enforcement116117Before fixing any CVE on a release branch (e.g., `redhat-3.17`):1181191. Check if the fix already exists on `master`1202. If not, fix on `master` first, then backport to the release branch1213. If the target is an older branch (e.g., 3.16), also verify 3.17 has the fix1224. Skip EOL branches (3.11, 3.13) — log a warning123124## Processing Multiple CVEs125126When processing a batch of CVEs:1271281. Group by upstream repo to minimize cloning1292. Process each CVE independently (separate branch, separate PR)1303. Clone once per repo, create worktrees per branch1314. Clean up `/tmp` clones after all CVEs are processed132133## Error Handling134135- If assess fails (e.g., cannot reach advisory URL), log the error and136 ask the user whether to proceed or skip137- If fix fails (e.g., test failures, scan still detects CVE), create the138 PR anyway with failure details documented139- If PR creation fails, save the branch name and changes so the user140 can create the PR manually141- Always clean up `/tmp` clones, even on error142143## Final Summary144145After processing all CVEs, print a summary:146147```text148=== CVE Fix Summary ===149150PRs Created:151 - CVE-YYYY-XXXXX (package): https://github.com/org/repo/pull/NNN152 - ...153154Skipped (not affected):155 - CVE-YYYY-XXXXX: VEX justification added to PROJQUAY-XXXX156157Skipped (RPM layer):158 - CVE-YYYY-XXXXX: Base image package, Jira comment added159160Escalated:161 - CVE-YYYY-XXXXX: Code change required, needs team review162163Errors:164 - CVE-YYYY-XXXXX: <error description>165```