resolve-images.py — abra-independent version resolver. abra FATAs on a tag+digest pin and abandons the whole recipe, which is how immich silently dropped out of every survey. Handles Docker Hub, ghcr and any OCI registry via its own auth challenge; matches tag shapes; reports both newest_within_major and newest_same_shape and refuses to choose. 21/21 recipes resolve, and it found upgrades abra missed in five — plausible's clickhouse carried 4 CVEs.
audit-sources.py — flags images gone quiet, deprecation wording, and archived/renamed/missing GitHub repos. It independently re-derived the plausible case and found minio archived, drone renamed, and mumble with no registry file at all (which exposed the scan reporting 0 with zero sources — now UNKNOWN).
tests/STYLE.md pointers — every test-editing path now reads the rulebook first.
Retrospective review PR. These commits were pushed straight to main during the 2026-08-11 session; they are already live. This PR exists so the work is reviewable and commentable as a unit — its base is a branch pinned at the pre-session commit, so merging it simply advances that pointer and changes nothing on main. Going forward, orchestrator changes go through a PR before landing.
- **`resolve-images.py`** — abra-independent version resolver. abra FATAs on a tag+digest pin and abandons the *whole* recipe, which is how immich silently dropped out of every survey. Handles Docker Hub, ghcr and any OCI registry via its own auth challenge; matches tag *shapes*; reports both `newest_within_major` and `newest_same_shape` and refuses to choose. **21/21 recipes resolve**, and it found upgrades abra missed in five — plausible's clickhouse carried 4 CVEs.
- **`audit-sources.py`** — flags images gone quiet, deprecation wording, and archived/renamed/missing GitHub repos. It independently re-derived the plausible case and found minio archived, drone renamed, and mumble with no registry file at all (which exposed the scan reporting `0` with zero sources — now `UNKNOWN`).
- **`tests/STYLE.md` pointers** — every test-editing path now reads the rulebook first.
---
*Retrospective review PR.* These commits were pushed straight to `main` during the 2026-08-11 session; they are already live. This PR exists so the work is reviewable and commentable as a unit — its base is a branch pinned at the pre-session commit, so merging it simply advances that pointer and changes nothing on `main`. Going forward, orchestrator changes go through a PR before landing.
immich pins two images with BOTH a tag and a digest, which makes abra FATA and
abandon the WHOLE recipe. It therefore contributed no version data at all and
silently dropped out of every survey — indistinguishable from 'up to date'. The
standing answer was prose in three skills telling an agent to check registries by
hand. This replaces it with a tool.
resolve-images.py reads the compose files and queries registries itself:
- Docker Hub, ghcr, and any OCI registry via its own auth challenge (lscr.io
and dock.mau.dev advertise different realms; assuming ghcr's shape 401'd).
- tag SHAPES (digits -> '#') so -alpine stays on -alpine and 'latest' is never
proposed as an upgrade.
- reports newest_within_major AND newest_same_shape, and refuses to choose:
immich's postgres tag encodes the pg major plus the vectorchord/pgvectors
build immich-server expects, so taking the newest breaks the deploy.
- integrity check: if the CURRENT pin is absent from the listing, the listing
was truncated and any 'newest' is a guess. ghcr caps out past 40k tags, so
that falls back to the project's GitHub releases.
- per-repo cache + backoff + Docker Hub auth: a fleet sweep re-reads nginx,
redis and postgres many times and was getting 429s reported as 'unresolved'.
21/21 recipes now resolve. It found upgrades abra missed entirely in five:
mumble (abra said 'no new versions'; four patches behind), plausible's
clickhouse, lasuite-drive's collabora, gitea's mariadb, immich's postgres.
plausible's carried four CVEs, three high.
Also fixes a real over-count found while validating that: a fix inside the
numeric window is not a fix on the branch you land on. ClickHouse patched
CVE-2023-48704 in 23.9.6.20 AND 23.10.5.20 — landing on 23.10.4.25 crosses the
23.9 fix but sits below its own line's, so it does NOT have it. A fix named on
the target's own line and above the target is now proof of absence.
70 tests (64 offline + 6 live). keycloak's live expectation moves 7 -> 12 and
mailu's 0 -> 2: both are the release-note source finding real fixes that were
never filed as advisories.
/recipe-upgrade --with-tests, /ci-test-review and /cc-ci-tests-update all author
test changes, and all three had only 'never weaken a test' as guidance. That did
not stop the plausible failure: the fixture INSERTed rows into the app's database,
which was correct for v2 and silently wrong for v3, where a site must belong to a
team. Events were acked 202 and discarded; the recipe sat RED for six weeks.
The rule that would have prevented it — set state up through the app's own
interface, not its database — now lives in tests/STYLE.md in the cc-ci repo, and
each of the three paths is told to read it before editing a test.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
resolve-images.py— abra-independent version resolver. abra FATAs on a tag+digest pin and abandons the whole recipe, which is how immich silently dropped out of every survey. Handles Docker Hub, ghcr and any OCI registry via its own auth challenge; matches tag shapes; reports bothnewest_within_majorandnewest_same_shapeand refuses to choose. 21/21 recipes resolve, and it found upgrades abra missed in five — plausible's clickhouse carried 4 CVEs.audit-sources.py— flags images gone quiet, deprecation wording, and archived/renamed/missing GitHub repos. It independently re-derived the plausible case and found minio archived, drone renamed, and mumble with no registry file at all (which exposed the scan reporting0with zero sources — nowUNKNOWN).tests/STYLE.mdpointers — every test-editing path now reads the rulebook first.Retrospective review PR. These commits were pushed straight to
mainduring the 2026-08-11 session; they are already live. This PR exists so the work is reviewable and commentable as a unit — its base is a branch pinned at the pre-session commit, so merging it simply advances that pointer and changes nothing onmain. Going forward, orchestrator changes go through a PR before landing.immich pins two images with BOTH a tag and a digest, which makes abra FATA and abandon the WHOLE recipe. It therefore contributed no version data at all and silently dropped out of every survey — indistinguishable from 'up to date'. The standing answer was prose in three skills telling an agent to check registries by hand. This replaces it with a tool. resolve-images.py reads the compose files and queries registries itself: - Docker Hub, ghcr, and any OCI registry via its own auth challenge (lscr.io and dock.mau.dev advertise different realms; assuming ghcr's shape 401'd). - tag SHAPES (digits -> '#') so -alpine stays on -alpine and 'latest' is never proposed as an upgrade. - reports newest_within_major AND newest_same_shape, and refuses to choose: immich's postgres tag encodes the pg major plus the vectorchord/pgvectors build immich-server expects, so taking the newest breaks the deploy. - integrity check: if the CURRENT pin is absent from the listing, the listing was truncated and any 'newest' is a guess. ghcr caps out past 40k tags, so that falls back to the project's GitHub releases. - per-repo cache + backoff + Docker Hub auth: a fleet sweep re-reads nginx, redis and postgres many times and was getting 429s reported as 'unresolved'. 21/21 recipes now resolve. It found upgrades abra missed entirely in five: mumble (abra said 'no new versions'; four patches behind), plausible's clickhouse, lasuite-drive's collabora, gitea's mariadb, immich's postgres. plausible's carried four CVEs, three high. Also fixes a real over-count found while validating that: a fix inside the numeric window is not a fix on the branch you land on. ClickHouse patched CVE-2023-48704 in 23.9.6.20 AND 23.10.5.20 — landing on 23.10.4.25 crosses the 23.9 fix but sits below its own line's, so it does NOT have it. A fix named on the target's own line and above the target is now proof of absence. 70 tests (64 offline + 6 live). keycloak's live expectation moves 7 -> 12 and mailu's 0 -> 2: both are the release-note source finding real fixes that were never filed as advisories.