fix(playbooks): compare image IDs, not the created-from tag; make the repin idempotent

Two defects the worldtree-pinned case exposed in the guard written an hour
ago.

1. The guard compared the container's .Config.Image STRING against the tag
   being pinned. That string is only the tag the container was CREATED from,
   which can differ from what it actually runs: worldtree-pinned was created
   from `:latest` back when that tag pointed at 446e5807, and `:latest` has
   since moved to b19afd71d7cc. So the guard refused an instance whose
   pinning was correct and necessary. Now it resolves the target tag to an
   image ID and compares that against the running image ID -- asserting the
   thing actually cared about, that this tag names the bytes now running.
   It also fails closed when no such local tag exists.

2. The sed step reported CHANGED unconditionally, so a re-run on an
   already-pinned instance claimed work it had not done. Gated behind a
   `when:` that skips when the line is already correct; a second run on demo
   now reports "2 ok, 0 changed, 2 skipped / overall: OK".

Applied to worldtree-pinned under worldtree-dev authorization. That instance
needed a `docker tag` first -- its image was DANGLING (no repo tags, kept
alive only by the running container), so the fleet's frozen reference was one
`docker rm` from garbage collection. Tagged as :446e5807bf43, then pinned.

All three instances now render a SHA with no floating tag anywhere:
  worldtree          -> :ae88a057c0ed
  worldtree-personal -> :f63529168c13
  worldtree-pinned   -> :446e5807bf43
Nothing restarted -- pinned still Up 3 months, its start time unchanged.
This commit is contained in:
vh
2026-08-22 21:52:20 -07:00
parent 064181a8fb
commit bb19a96f39
+23 -8
View File
@@ -46,16 +46,27 @@ steps:
shell: test -n "{{ expect_sha }}"
changed_when: "false"
- name: Confirm the container is actually running the SHA we are about to pin
# Guards against a deploy landing between the operator reading the SHA
# and this playbook writing it — pinning a SHA that is NOT running would
# arm the exact hazard we are disarming, just with a different image.
- name: Confirm the tag we are about to pin resolves to the running image
# Guards against a deploy landing between reading the SHA and writing it —
# pinning a SHA that is NOT running would arm the exact hazard we are
# disarming, just with a different image.
#
# Compares IMAGE IDs, not the container's .Config.Image string. The string
# is only the tag the container was CREATED from, which can differ from
# what it actually runs: worldtree-pinned was created from `:latest` back
# when that tag pointed at 446e5807, and `:latest` has since moved. A
# string compare rejects that instance even though pinning it is correct;
# an ID compare asserts the thing we actually care about — that this tag
# names the bytes currently running.
shell: |
running=$(docker inspect {{ api_container }} --format '{{.Config.Image}}')
test "$running" = "{{ registry }}:{{ expect_sha }}" || {
echo "REFUSING: {{ api_container }} runs $running, not {{ registry }}:{{ expect_sha }}"
running=$(docker inspect {{ api_container }} --format '{{.Image}}')
tagged=$(docker image inspect {{ registry }}:{{ expect_sha }} --format '{{.Id}}' 2>/dev/null) || {
echo "REFUSING: no local image tagged {{ registry }}:{{ expect_sha }} — tag it first"
exit 1; }
echo "confirmed: $running"
test "$running" = "$tagged" || {
echo "REFUSING: {{ api_container }} runs $running but {{ registry }}:{{ expect_sha }} is $tagged"
exit 1; }
echo "confirmed: {{ registry }}:{{ expect_sha }} == running image $running"
changed_when: "false"
- name: Back up .env
@@ -65,6 +76,10 @@ steps:
- name: Re-pin WORLDTREE_IMAGE to the running SHA
sudo: true
# Skipped when already correct, so a re-run reports OK rather than a
# phantom CHANGED — a playbook that always claims to have changed
# something trains you to stop reading the summary.
when: "! sudo grep -q '^WORLDTREE_IMAGE={{ registry }}:{{ expect_sha }}$' {{ instance_dir }}/.env"
# `|` delimiter because the image reference contains slashes.
shell: |
grep -q '^WORLDTREE_IMAGE=' {{ instance_dir }}/.env || {