-- W9: notices that are not about the product; an empty fix with a closed range
  ok  W9 a GitHub Actions advisory (the project's CI) is not about the image -> not listed
  ok  W9 an empty fix with a range ending at 2.6.0 -> ADVISORY, fixed after 2.6.0 (not 'no fixed version')
  ok  W9 negative: the same notice at 2.7.0 -> not listed
  ok  W9 control: an open range with no fix still says 'no fixed version named yet'
-- W1-W4: the classes
  ok  W1 traefik v3.7.13 -> ADVISORY, fixed v3.7.14
  ok  W1 negative: traefik v3.7.16 -> CURRENT (the rc is no fix, v2 is another channel)
  ok  W1 Nextcloud 34.0.4 -> no Server advisory (fixed 34.0.1); the Deck app's advisory is not ours
  ok  W1 Nextcloud 34.0.0 -> ADVISORY GHSA-nc01
  ok  W1 an unreadable range is LISTED (unsure), never dropped
  ok  W1 OSV: Go 1.27.2 -> GO-2026-6809 fixed 1.27.3; Go 1.27.3 -> none
  ok  W2 the recorded Cloudflare blog item -> ADVISORY for cloudflared (and only that item)
  ok  W2 the VULN- marker in 2026.10.4 -> ADVISORY fixed 2026.10.4; 2026.10.2's plain bump is not one
  ok  W2 the same blog item 71 days later -> nothing (30-day window)
  ok  W2 positive control at the pin it hit: cloudflared 2026.9.3 on 2026-10-26 -> ADVISORY
  ok  W3 filebrowser 1.5.6-stable -> BEHIND 1.5.7-stable (the beta is no channel, its CVE no fix)
  ok  W3 redis 7-alpine -> FLOATING
  ok  W3 postgres gap -> GAP (BEHIND still computed: no newer 16-…)
  ok  W3 an abandoned template -> GAP, nothing looked up (no route needed)
  ok  W4 a source that fails -> NOT CHECKED, with the reason
  ok  W4 the table prints the NOT CHECKED line
-- W5-W7: memory and mails
  ok  W5 a new advisory mails that night
  ok  W5 the mail carries our version, the fixed version, the lane
  ok  W5 the same advisory the next night mails NOTHING
  ok  W5 still open 7 days later -> one reminder
  ok  W5 and not again the next night
  ok  W5 a vendor notice mails once and never repeats
  ok  W5 a pin checked clean forgets its closed advisory
  ok  W5 box programs first in the subject
-- W6: a source down
  ok  W6 one night down -> no mail
  ok  W6 two nights -> one mail naming the source
  ok  W6 a third night -> no second mail
  ok  W6 back up -> the streak resets (one more night down -> no mail)
-- W7: weekly and seed
  ok  W7 Monday -> the weekly summary
  ok  W7 not twice the same Monday
  ok  W7 a Tuesday whose last weekly is 8 days old -> the weekly (a missed Monday)
  ok  W7 a seed mails nothing, records the advisory, and says what it would have mailed
  ok  W7 a pin the seed could not read is PENDING
  ok  W7 its first real read is recorded SILENTLY; a pin added later still mails
-- W13: one image in the catalog AND on DooPlex (R-1333)
  ok  W13 a new notice on both pins is mailed for BOTH (the catalog's 5.4.1 and DooPlex's 5.4.0)
  ok  W13 the memory keeps one entry per group
  ok  W13 the old shared key is copied to the DooPlex key: no mail again
  ok  W13 a shared key whose catalog pin is gone moves to the DooPlex key (no stale twin, no mail)
  ok  W13 DooPlex's pin checked clean forgets only DooPlex's entry
-- W14: Docker Hub — retry a 429, cache a tag list for 24 h, one fetch per path, paced (R-1334)
  ok  W14 a 429 is retried after its Retry-After, and the retry's tags are used
  ok  W14 a 429 on every try -> NOT CHECKED only after the last try (4 tries)
  ok  W14 a tag list cached an hour ago -> no request
  ok  W14 a tag list cached 25 h ago -> fetched again, and the cache holds the new list
  ok  W14 two names of one Docker Hub path -> one fetch
  ok  W14 Docker Hub requests are spaced (>= 1.0 s apart)
  ok  W14 main() loads the runner's tag cache, hands it to run() and prints the TAGS line
-- W8: the inventory and its gate
  ok  W8 a gap with no reason is a problem
  ok  W8 two sources parse
  ok  W8 an unknown kind is a problem
  ok  W8 a decoy pin whose line is only a comment REFUSES (rc 1, names demo/b)
-- W10: the runtime inside an image
  ok  W10 Node 24.18.1 -> ADVISORY from runtime, CVE-2026-111497, fixed 24.22.1
  ok  W10 negative control: Node 24.22.1 -> no advisory
  ok  W10 Python Brotli 1.2.0 -> ADVISORY, fixed 1.2.1
  ok  W10 negative control: Brotli 1.2.1 -> no advisory
  ok  W10 Node 20 (no fixed release on its line) -> ADVISORY naming the end of life
  ok  W10 a layer read error -> NOT CHECKED with source runtime
  ok  W10 a registry with no route -> a note, not a failure
RUNTIME-READ ex/node-old:1.0.0 0 s ok
  ok  W10 the result is cached by digest: one full read for two nights
RUNTIME-READ ex/broken:1.0.0 0 s NOT CHECKED: layer sha256:1234 unreadable: ReadError
  ok  W10 an UNCHECKED result is not cached (tomorrow tries again)
  ok  W10 main() hands the reader to run() (off only with --no-runtime)
  ok  W10 the reader counts what it read and from the cache (the log's RUNTIME line)
-- W11: ghcr.io tags are paged
  ok  W11 both pages are read (1.1.0 is on page 2)
-- W12: the DooPlex group
  ok  W12 the list file is read, group dooplex, the catalog's sources reused
  ok  W12 an image the catalog does not ship is a stated gap (runtime + registry only)
  ok  W12 a DooPlex advisory names the homelab session and not the lane
  XX  W12 a DooPlex image in our own private registry -> GAP with the reason, no failed source (R-1334) ('NOT CHECKED', [{'source': 'runtime', 'why': 'registry gitea.dooplex.hu: no anonymous token route'}])
  ok  W12 the weekly mail has its own DooPlex block
-- W15: a timeout is tried again; a stated unreadable pin is a GAP, not a failed source (R-1334)
  XX  t_timeouts_and_stated ran SourceError: https://hub.docker.com/v2/repositories/library/redis/tags?page_size=100&ordering=last_updated: The read operation timed out
-- W16: notices that do not apply, and fixes that were missed (R-1310)
  XX  W16 another program's package in the repo (Gitea's runner) is not listed True
  ok  W16 the same notice also naming the pinned program IS listed (control)
  ok  W16 the pinned program's package is listed (control)
  XX  W16 Uptime Kuma's rootless-only notice is not listed for our image True
  XX  W16 every GHSA a release names is its own entry, once ['release:ex/app@1.0.1', 'release:ex/app@1.0.2']
  XX  W16 ... with the lowest release that names it as the fix {'release:ex/app@1.0.2': '1.0.2', 'release:ex/app@1.0.1': '1.0.1'}
  XX  W16 a GHSA in both the advisory list and a release is one entry (the advisory's) [{'id': 'GHSA-aaaa-bbbb-cccc', 'source': 'GitHub advisory', 'severity': 'high', 'summary': 'snicheck skips the check', 'fixed': '1.0.1', 'link': 'https://github.com/traefik/traefik/security/advisories/GHSA-fh26-gfpp-7xxx', 'unsure': False, 'published': '2026-10-07'}, {'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': 'Fixes GHSA-aaaa-bbbb-cccc', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
  XX  W16 a line where „security” is only a word is no ADVISORY (Traefik's announcements line) [{'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': '[security] Point security announcements to GitHub advisories (#14099)', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
  XX  W16 „no longer receives security fixes” is no ADVISORY (Dawarich) [{'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': 'Dawarich no longer receives security fixes on this line', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
  XX  W16 the same notes with a real id ARE listed, by that id (control: Traefik v3.7.17) [{'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': 'CVE fixed: Advisory GHSA-xv5x-242w-7hf7', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
  ok  W16 a plain „Security Fixes” heading with no id is still an ADVISORY (control: Vaultwarden's shape)
  XX  W16 linuxserver's YY.MM.YYYYMMDD tag is not newer than 26.09.2 26.09.20260929
  XX  W16 a real newer tag beside it still counts (control) 26.09.20260929
  ok  W16 a pin that IS on the date shape still compares its own shape (control)

FAIL: W12 a DooPlex image in our own private registry -> GAP with the reason, no failed source (R-1334) ('NOT CHECKED', [{'source': 'runtime', 'why': 'registry gitea.dooplex.hu: no anonymous token route'}])
FAIL: t_timeouts_and_stated ran SourceError: https://hub.docker.com/v2/repositories/library/redis/tags?page_size=100&ordering=last_updated: The read operation timed out
FAIL: W16 another program's package in the repo (Gitea's runner) is not listed True
FAIL: W16 Uptime Kuma's rootless-only notice is not listed for our image True
FAIL: W16 every GHSA a release names is its own entry, once ['release:ex/app@1.0.1', 'release:ex/app@1.0.2']
FAIL: W16 ... with the lowest release that names it as the fix {'release:ex/app@1.0.2': '1.0.2', 'release:ex/app@1.0.1': '1.0.1'}
FAIL: W16 a GHSA in both the advisory list and a release is one entry (the advisory's) [{'id': 'GHSA-aaaa-bbbb-cccc', 'source': 'GitHub advisory', 'severity': 'high', 'summary': 'snicheck skips the check', 'fixed': '1.0.1', 'link': 'https://github.com/traefik/traefik/security/advisories/GHSA-fh26-gfpp-7xxx', 'unsure': False, 'published': '2026-10-07'}, {'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': 'Fixes GHSA-aaaa-bbbb-cccc', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
FAIL: W16 a line where „security” is only a word is no ADVISORY (Traefik's announcements line) [{'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': '[security] Point security announcements to GitHub advisories (#14099)', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
FAIL: W16 „no longer receives security fixes” is no ADVISORY (Dawarich) [{'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': 'Dawarich no longer receives security fixes on this line', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
FAIL: W16 the same notes with a real id ARE listed, by that id (control: Traefik v3.7.17) [{'id': 'release:ex/app@1.0.1', 'source': 'release notes', 'severity': '', 'summary': 'CVE fixed: Advisory GHSA-xv5x-242w-7hf7', 'fixed': '1.0.1', 'link': 'https://github.com/ex/app/releases/tag/1.0.1', 'unsure': False, 'published': ''}]
FAIL: W16 linuxserver's YY.MM.YYYYMMDD tag is not newer than 26.09.2 26.09.20260929
FAIL: W16 a real newer tag beside it still counts (control) 26.09.20260929
