b8d818ed99
DOCKER_HUB.md claimed ~1.1 GB for :latest while Docker Hub served 1.37 GB --
20% wrong, drifting quietly across eight releases, and POSTed to Docker Hub by
update-description every time. It is the first number a stranger reads about
this image.
Root cause is structural, not carelessness: every OTHER claim check-doc-drift.sh
guards is anchored to a build file (a pin, an ARG, a placeholder), so it cannot
rot without someone editing the thing it describes. Nothing in this repo states
the image size, so nothing measured it.
Corrected against measured full_size after v1.9.2 published (amd64/arm64):
:latest ~1.1 -> ~1.23 GB (1.228 / 1.211)
:latest-studio ~1.15 -> ~1.25 GB (1.255 / 1.238)
:base-latest ~1.0 -> ~1.17 GB (1.167 / 1.151)
full_size tracks the FIRST manifest entry (amd64), not the sum across arches --
measured: full_size=1.228, amd64=1.228, arm64=1.211, sum=2.439 -- which is what
the table's per-arch "Size (compressed)" column claims.
New check 8 gates those claims against Hub. Fails on drift; SKIPS LOUDLY via a
new skip() helper (counted, named in the summary) when curl/python3 are absent,
the API is unreachable, or SKIP_SIZE_CHECK=1. A skip is deliberately neither OK
nor a failure: printing an unverified claim as OK is the habit this file exists
to break, and failing on Docker Hub's uptime would hold releases hostage to a
third party. Not wired into hooks/pre-push, so pushes stay offline.
Two bugs caught by writing the expected exit code down before running the check:
1. The tolerance would have missed its own motivating case. The percentage is
computed against the MEASURED size, but the 20% first chosen came from the
claim-relative figure; the real drift was |1.1-1.37|/1.37 = 19.7% and would
have passed. Now 15%, inside a window with both bounds measured: above the
largest legitimate skew (11.4%, a claim describing the published release
while the next tag changes the size) and below the rot it must catch.
2. A `|| true` on the python invocation made the gate FAIL OPEN -- it printed
DRIFT and exited 0. Removed; the outer `|| SIZE_RC=$?` satisfies set -e
without swallowing the code. Verified two-sided: 19% drift exits 1 at the
default tolerance and 0 at SIZE_TOLERANCE_PCT=25, so the threshold does the
work rather than the ordering.
NOT covered, and the script says so where a reader will see it: README.md's
~3.2 GB figures are UNCOMPRESSED and the registry exposes compressed sizes only,
so measuring them needs a real pull. A green check 8 says nothing about them.
Verified: check-doc-drift.sh rc=0 on the corrected tree, rc=1 on injected drift,
rc=0 with --warn-only, SKIP+rc=0 on the offline path (proxy to a dead port);
shellcheck clean at default severity (the sed single-quote SC2016 carries a
disable with its reason); lint-shell.sh 16 files clean.