A dispatch for 12.11.1-ci7 without sign_only rebuilt and re-pushed the
tag. The registry dropped the old manifest, so flux-config's
12.11.1-ci7@sha256:86d7e3b4 pin now 404s on the next pull. That is the
zegit#143 threat shape, done by accident. Like zegit-arc-runner, a build
now refuses a tag the registry already holds, and sign_only refuses one
it does not.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
zegit's arc-runner-pin.sh pins a runner image only when cosign verifies
its digest against the runner-image public key (zegit#143), but nothing
signed the images, so the pin refused every day. Sign the digest with
the RUNNER_IMAGE_COSIGN_KEY repository secret after the publish and
verify the signature in the same run. sign_only re-signs an image
published before signing existed.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_0147GvtJgsTjDGcrfvJsx5jS
The publish path failed at registry login on every dispatch (runs 18,
20) because it read `secrets.ZEGIT_PACKAGE_TOKEN`, a name that exists
nowhere. The package-write token every zegit-zoo image workflow uses is
ZEGIT_CI_PACKAGE_TOKEN, held above repository scope, so this repository
can read it under that name — no second token, no second copy to rotate.
buildctl v0.32 has no "cacheonly" exporter, so every push-triggered
validation build since this workflow was added failed with 'exporter
"cacheonly" could not be found' (run 16, 2026-09-08) — unnoticed, since
nothing depended on it. A build with no --output still builds every
stage on both architectures. The post-publish toolchain assertion now
also requires chromium-browser and psql (12.11.1-ci7).
build-image.yml is GitHub-only, so the image the Gitea runners are built FROM
could only be produced by GitHub. When GitHub Actions went unavailable on
2026-08-29 that circularity bit: the fix for openssl/jq missing from this image
— the absence that blocked v0.0.134 and v0.0.135 — could not be published on the
forge the project is moving to.
This publishes from the self-hosted runners through the in-cluster rootless
buildkitd, the path zegit images already use. buildah needing user namespaces
does not apply: buildkitd is a separate hardened workload and the job only
speaks to it over the network, so nothing is built inside the runner container.
Same contract as build-image.yml: a master push validates both arches and
publishes nothing, only an explicit dispatch names a tag and pushes, and a
dispatch without a package-write token fails loudly instead of reporting success
having pushed nothing.
The toolchain assertion is kept but done with buildkit rather than docker run,
which these runners lack: a stage FROM the published image whose RUN fails on a
missing tool, built natively for both arches. Verified it passes against an
image built from current master and fails with MISSING: openssl against the
deployed ci5.