What happens
A fullsend release builds and tags both sandbox images (sandbox-images.yml on the v* tag push: ghcr.io/fullsend-ai/fullsend-code:<version>, fullsend-sandbox:<version>) and pushes the version tag to fullsend-ai/agents (release.yml → tag-agents). Nothing updates the seven harness/*.yaml image digests in the agents repo. They were pinned once (agents e96a3b7, 2026-08-04) and moved by hand since: agents#1160 repinned to the 0.40.0 digests on 2026-09-03, after the release had already tagged the agents repo, so the v0.40.0 agents tag points at harnesses still pinned to the 0.37.0 images. Renovate does not track the digests. The .fullsend sync job propagates agents commit digests to consumers, not image digests.
Consequence: every fleet image fix (pi bump, extension pin, Claude Code pin, tirith pin) reaches :latest on merge and reaches the fleet only after a release plus a manual PR someone remembers to open. Today the fleet harnesses still pin the 0.40.0 images (Claude Code 2.1.258, pi 0.84.x, xai-vertex 0.2.0 with the Grok keepalive bug) while main's image has pi 0.85.0, xai-vertex 0.2.1 and the fullsend anthropic-vertex extension.
What should happen
On a v* tag build, sandbox-images.yml already has the pushed manifest digests (steps.push.outputs.digest for each image). Add a job that, after both pushes succeed:
- checks out fullsend-ai/agents with the existing agents App token (the one
tag-agents uses),
- rewrites the
image: line in harness/{code,fix,review}.yaml to fullsend-code@<digest> and in harness/{prioritize,retro,scribe,triage}.yaml to fullsend-sandbox@<digest>,
- opens a PR (
chore(harness): repin sandbox and code images to the <version> release digests) with the digest table, the release commit (org.opencontainers.image.revision) and a link to the release run,
- and — the ordering fix —
tag-agents waits for that PR to merge (or the release notes state that the agents tag predates the repin) so the agents tag for a release carries the release's own images.
The manual fallback is a small script that resolves the digests through the anonymous registry token (GET https://ghcr.io/token?scope=repository:fullsend-ai/<image>:pull → HEAD /v2/fullsend-ai/<image>/manifests/<version> → Docker-Content-Digest) and rewrites the seven files; it reproduces agents#1160's digests exactly and is what will be used for the next release until this lands.
Validation criteria
- A
v* tag build ends with an open agents PR whose seven digests equal the digests the same run pushed, and skopeo inspect/registry HEAD of <image>:<version> returns those digests.
- The agents version tag for the release points at a commit whose harness digests are the release's images (or the release output states explicitly that it does not).
- No manual step between "tag pushed" and "fleet harnesses pinned to the new images" other than approving the generated PR.
Related
#6986 (release gate hardening), agents#1160 (last manual repin), agents#123 (immutable digest pins), #7025 / #7024 (the image changes waiting on the next repin), #7031 / #7038 (pi persona routing, which needs the pi 0.85.0 image on the fleet).
What happens
A fullsend release builds and tags both sandbox images (
sandbox-images.ymlon thev*tag push:ghcr.io/fullsend-ai/fullsend-code:<version>,fullsend-sandbox:<version>) and pushes the version tag to fullsend-ai/agents (release.yml→tag-agents). Nothing updates the sevenharness/*.yamlimage digests in the agents repo. They were pinned once (agentse96a3b7, 2026-08-04) and moved by hand since: agents#1160 repinned to the 0.40.0 digests on 2026-09-03, after the release had already tagged the agents repo, so thev0.40.0agents tag points at harnesses still pinned to the 0.37.0 images. Renovate does not track the digests. The.fullsendsync job propagates agents commit digests to consumers, not image digests.Consequence: every fleet image fix (pi bump, extension pin, Claude Code pin, tirith pin) reaches
:lateston merge and reaches the fleet only after a release plus a manual PR someone remembers to open. Today the fleet harnesses still pin the 0.40.0 images (Claude Code 2.1.258, pi 0.84.x, xai-vertex 0.2.0 with the Grok keepalive bug) while main's image has pi 0.85.0, xai-vertex 0.2.1 and the fullsend anthropic-vertex extension.What should happen
On a
v*tag build,sandbox-images.ymlalready has the pushed manifest digests (steps.push.outputs.digestfor each image). Add a job that, after both pushes succeed:tag-agentsuses),image:line inharness/{code,fix,review}.yamltofullsend-code@<digest>and inharness/{prioritize,retro,scribe,triage}.yamltofullsend-sandbox@<digest>,chore(harness): repin sandbox and code images to the <version> release digests) with the digest table, the release commit (org.opencontainers.image.revision) and a link to the release run,tag-agentswaits for that PR to merge (or the release notes state that the agents tag predates the repin) so the agents tag for a release carries the release's own images.The manual fallback is a small script that resolves the digests through the anonymous registry token (
GET https://ghcr.io/token?scope=repository:fullsend-ai/<image>:pull→HEAD /v2/fullsend-ai/<image>/manifests/<version>→Docker-Content-Digest) and rewrites the seven files; it reproduces agents#1160's digests exactly and is what will be used for the next release until this lands.Validation criteria
v*tag build ends with an open agents PR whose seven digests equal the digests the same run pushed, andskopeo inspect/registryHEADof<image>:<version>returns those digests.Related
#6986 (release gate hardening), agents#1160 (last manual repin), agents#123 (immutable digest pins), #7025 / #7024 (the image changes waiting on the next repin), #7031 / #7038 (pi persona routing, which needs the pi 0.85.0 image on the fleet).