Image build is not reproducible from a commit sha: uv and the base image are both floating tags #46
Labels
No labels
burndown-2026-06
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/lunch-money-k8s#46
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
docs/deploy.mdstates the fleet consumes "that exact immutable reference", andscripts/publish-image.shtags by full source sha and printsverified immutable manifest. The tag is immutable. The image contents are not.Dockerfilepulls two floating tags:and
publish-image.shrunsdocker build --pull, which re-resolves both on every build rather than reusing a local layer. So building the same commit twice can produce two different images under two different sha tags, and nothing in the pipeline would show it.uv:latestis the sharper of the two, since uv ships often andlatestmoves with it.Observed on run 75 (job 47078), where step 2 failed:
That failure is the reachability half rather than the reproducibility half, but both come from the same line.
Two things to decide, and I did not decide either here:
uvto an exact version, and pin the base image by digest rather than3.12-slim. Low risk, and it makes sha -> image deterministic.uv sync --frozen, so sourcing uv from there instead would cut the external host set from two to one. Mirroring uv into the Forgejo registry would cut it further, but that is a live-registry change rather than a repo change.Not fixed in place because there is no Docker daemon on the host I was working from, so I could not build the image to validate any of it, and an unvalidated build change pushed to main is what produced the failure this came out of.
Found while fixing the run-74 format failure (
ea739b6).Confirmed transient. Run 76 built and published the identical Dockerfile line with no change to it:
So the ghcr.io TLS handshake timeout on run 75 was a blip rather than a standing egress block, and the reachability half of this issue is intermittent rather than broken. Two observations now: failed on run 75, succeeded on run 76, roughly twenty minutes apart, same runner and same unpinned tag.
That lowers the urgency but does not close it. An intermittent external fetch on the publish path still fails a run whose commit is fine, and the reproducibility half is unaffected by any of this:
uv:lateststill moves underdocker build --pull, so two builds of one sha can still differ.