/cve-check answers 'what are we exposed to that an upgrade would fix?' without running an upgrade: per-recipe, resolve the available window for EVERY image (sidecars included), run the advisory scan over it, adjudicate whatever pass 1 could not decide, publish a report. Read-only — no PRs, no CI, no merges. /cve-check-and-upgrade does that sweep, then runs /recipe-upgrade only on the recipes whose upgrade actually closes a CVE, worst severity first, and reports on both. --min-severity high for just the urgent ones; --dry-run prints the queue and stops. Never merges. Deliberate choices, each written into the skills: - externals are SWEPT but never upgraded here — a security sweep that skipped deployed software would misreport exposure, but we don't maintain them. - an unknown count never justifies an upgrade AND is never treated as clean; it goes to the Addendum. - no upgrade available means 0 CVEs, not '?'. - subagents are told which CVEs justify their upgrade, so the PR says why it exists — a PR naming the RCE it closes gets reviewed sooner. recipe-report.py grows a page kind: 'cve' files as cve-DATE.html so a sweep can't overwrite a weekly edition, while BOTH appear in the same archive index, suffixed 'full report' / 'CVE check'. /help and /cc-ci-status updated to route to them.
6.0 KiB
name, description
| name | description |
|---|---|
| cve-check-and-upgrade | Security-driven upgrade run. Does a full /cve-check sweep first (per-image advisory scan of every recipe's available upgrade, with adjudication), then runs /recipe-upgrade ONLY on the recipes whose upgrade fixes at least one CVE — worst severity first — opening a verified recipe PR for each, and finally publishes one report covering both the sweep and the PRs. Recipes with no CVEs are left alone; that is the point. NEVER merges. Invoke as /cve-check-and-upgrade [recipe ...] [--min-severity high] [--capacity N] [--dry-run]. |
cve-check-and-upgrade
/upgrade-all upgrades everything that has an upgrade. This upgrades what has a reason. It runs
the /cve-check sweep, then spends CI time only on the recipes where an upgrade actually closes a
vulnerability, handling the worst first.
Use it when you want to act on security rather than churn the whole fleet: after a vendor announcement,
when CI capacity is short, or between weekly runs. When you only want to know, use /cve-check. When
you want everything current regardless of CVEs, use /upgrade-all.
Creates PRs. Never merges. Every PR is verified green on cc-ci and left for a human.
Arguments
<recipe> …— restrict the whole run to these recipes.--min-severity critical|high|medium|low— only upgrade recipes whose fixed CVEs reach this severity. Defaultlow(any CVE at all justifies the upgrade).--min-severity highis the useful "just the urgent ones" setting.--capacity N— subagent pool size; defaults to the liveDRONE_RUNNER_CAPACITY(the drone runner's slots), matching/upgrade-all's rolling-pool behaviour.--dry-run— do the whole sweep and print exactly which recipes would be upgraded and why, then stop without spawning a single upgrade. Publishes no report and opens no PR.
Procedure
1. Sweep — run /cve-check in full
Follow .claude/skills/cve-check/SKILL.md steps 1–5 exactly: candidate list, per-image upgrade windows,
the advisory scan per recipe, pass-2 adjudication of anything undecided, and the severity classification.
Do not publish its report — this run produces one combined report at the end instead.
Keep, per recipe: the windows scanned, the CVE count, the CVE ids with severities, and whether the count is a floor (undetermined advisories remain) or unknown.
2. Decide what to upgrade
RECIPES_TO_UPGRADE = recipes where the scan found ≥1 CVE at or above --min-severity.
Deliberate exclusions, each recorded in the report with its reason:
- 0 CVEs — an upgrade may exist, but nothing security-relevant. Left alone; that is the point of
this skill.
/upgrade-allis what sweeps those up. externaltier — swept for visibility, never upgraded here; someone else maintains it. Flag it loudly in the report if it has a critical, since the action is to tell them, not to open a PR.UPTODATE— nothing available.- count
?/ UNKNOWN — do not upgrade blind, and do not treat it as clean. Put it in the Addendum as needing a look. An unknown is a gap in our knowledge, not evidence of safety.
Order the queue by worst severity first (critical → high → …), count breaking ties. If --dry-run,
print this queue with each recipe's CVE ids and severities, and STOP here.
3. Upgrade each one — via /recipe-upgrade subagents
Run /recipe-upgrade <recipe> per queued recipe as a subagent, in the queue order above, as a
rolling pool keeping --capacity (default DRONE_RUNNER_CAPACITY) running at once and starting the
next as each finishes — the same concurrency discipline as /upgrade-all §3, and safe for the same
reason (per-run recipe trees + app-domain locks).
Each subagent does the full job: plan, implement the bump, verify green on cc-ci with !testme, and
open a recipe PR. Default mode — no --with-tests: a genuinely stale test gets an explanatory PR
comment, not a test edit.
Tell each subagent which CVEs justify its upgrade, with ids and severities, so the PR description says why it exists. That is most of this skill's value to a reviewer: a PR that names the CVSS-9.8 RCE it closes gets merged today, an unexplained version bump waits a fortnight.
Collect per recipe: PR url + number, the !testme verdict and build number, and any failure.
4. Report — one page covering sweep AND PRs
Write /tmp/cve-spec-<DATE>.json per /cve-check step 6, with these differences:
- Rows for upgraded recipes carry the real
ci(build N ✓/RED N · <stage>) +ci_url, andpr/pr_url.statusis the CI verdict (GREEN/FAILED/STALE); the live PR-status column derives itself fromrecipe+pr. - Rows for swept-but-not-upgraded recipes keep
PENDING/UPTODATEwith emptyci/pr, and anotesreason (0 CVEs — not upgraded,external — maintained elsewhere,below --min-severity). - Include
changes[]— one entry per recipe that got a PR, describing what the upgrade changes and the CVEs it closes. - Keep
"kind": "cve": it titles the page "The Recipe Report — CVE check" and files it ascve-<DATE>.html, alongside the weekly editions in the same archive index.
Then render + publish exactly as /cve-check step 7, and verify as its step 8. Print the report URL,
N swept · M upgraded · K PRs green · J failed, and CVE CHECK AND UPGRADE COMPLETE.
Guardrails
- NEVER merge. Create and verify; a human merges. Never push to true upstream.
- Never weaken a test to make a PR green, and never edit a test without
--with-tests. - Never upgrade a recipe whose CVE count is unknown on the assumption it is fine — surface it.
- Never upgrade an
externalrecipe here, even with a critical; report it instead. - Public-safe report only — no secrets, tokens, internal hostnames, raw logs, or spend figures.
- If the sweep finds nothing at or above
--min-severity, that is a good outcome: publish the report saying so and open no PRs. Do not manufacture work.