A recipe tracks an image repo and a set of registry URLs. When upstream moves, nothing errors — the old repo just stops receiving tags and the recipe looks 'up to date' forever. plausible is the case: it tracked plausible/analytics on Docker Hub while upstream moved to ghcr.io/plausible/community-edition. Every survey said 'no upgrades available' while v3 shipped elsewhere. audit-sources.py reports the signals that catch it, per image and per registry URL: image gone quiet (newest tag older than --quiet-days), deprecation wording in the registry description, and GitHub repos that are archived, renamed or gone. Signals, not verdicts — a stable image can be quiet for good reason — so each finding says what was measured. First run over 22 recipes, 11 findings, 4 alerts. It independently re-derived the plausible case (analytics quiet 1126 days), and found: - drone: harness/drone now answers as harness/harness (the image is fine) - lasuite-docs, lasuite-drive: minio/minio is ARCHIVED on GitHub - lasuite-docs: docspecio/api is ARCHIVED - matrix-synapse: halfshot/matrix-appservice-discord image quiet 2078 days - mumble: NO cc-ci-plan/upstream/mumble.md at all That last one exposed a scanner bug. With no registry file there is no source to query, yet the scan still printed '0 identified by the deterministic scan' — and that 0 was published as a clean count in the 2026-08-11 CVE check. A scan with no usable source has measured nothing and must not report a number, least of all 0. It now returns UNKNOWN and says the registry file is missing. upstream/mumble.md added; mumble now scans 6 sources for a genuine 0.
Upstream release-notes registry
Per-recipe maps of where each image's release notes / changelog live. This is the cc-ci analog of
recipe-maintainer's recipe-info/<recipe>/upstream.md: the /recipe-upgrade skill reads
cc-ci-plan/upstream/<recipe>.md so it doesn't have to rediscover the upstream source for every image
on every weekly run — discover once, persist, reuse.
How /recipe-upgrade uses it (step 1)
- Read
cc-ci-plan/upstream/<recipe>.md. - If it's missing, or an image in the recipe's
compose.ymlisn't covered (new/renamed service), discover the upstream project + releases page for each uncovered image (WebSearch the image → its GitHub/source repo → its releases/changelog page), then write/update this file and commit it (git -C /srv/cc-ci-orch add cc-ci-plan/upstream/<recipe>.md && commit && push). - Fetch the release notes from these URLs between the current → target version of each service.
Format (one file per recipe)
# Upstream sources — <recipe>
| service | image | source repo | releases / changelog |
|---------|-------|-------------|----------------------|
| app | cryptpad/cryptpad | https://github.com/cryptpad/cryptpad | https://github.com/cryptpad/cryptpad/releases |
| web | nginx | https://github.com/nginx/nginx | https://nginx.org/en/CHANGES |
## Standing notes
- <recipe-specific upgrade gotchas worth remembering between runs, e.g. "n8n: postgres volume path
changed from /var/lib/postgresql/data to /var/lib/postgresql in 2.2x">
Keep URLs canonical (the project's own releases/CHANGES page, not a mirror). Add a Standing notes section for migration gotchas you only want to learn once.