v0.284.2 — the image clean-up sees digest-pulled (untagged) images (decision 53, R-736)
gates / gates (push) Successful in 26s

Found live on 9202: the product pins tag@digest, and such images are stored untagged (repo:<none>);
`docker image ls` without -a did not list them, so the retention saw almost no app image. Now `image ls -a`;
an anonymous <none>:<none> entry is never a candidate; the one-time marker is v2 so the corrected sweep runs
once everywhere. Test TestImageRetention_SeesUntaggedDigestPulledImages, red-proofed. 0.284.0/0.284.1 were
never floored.

MinAgent: 0.131.0 (unchanged).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-30 23:03:32 +02:00
parent 00fddd3816
commit a70c398dee
6 changed files with 53 additions and 5 deletions
@@ -56,7 +56,10 @@ func normRepo(r string) string {
}
func listLocalImages() ([]localImage, error) {
out, err := imageDocker("image", "ls", "--digests", "--no-trunc", "--format", "{{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.Digest}}\t{{.Size}}")
// -a (v0.284.2): the product pins `tag@digest`, and an image pulled that way is stored UNTAGGED (`repo:<none>`) —
// measured on 9202 2026-09-30: `docker image ls` without -a did not list any of them, so v0.284.1 could not see most
// app images. A fully anonymous `<none>:<none>` entry names no repository and is never a candidate.
out, err := imageDocker("image", "ls", "-a", "--digests", "--no-trunc", "--format", "{{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.Digest}}\t{{.Size}}")
if err != nil {
return nil, fmt.Errorf("docker image ls: %v: %s", err, truncateStr(out, 200))
}
@@ -336,7 +339,7 @@ func (m *Manager) catalogImageRepos() map[string]bool {
// imageRetentionMarker: the one-time sweep runs once per box (decision 53's clean-up for boxes older than it).
func (m *Manager) imageRetentionMarker() string {
return filepath.Join(m.cfg.Paths.DataDir, "image-retention-v1.done")
return filepath.Join(m.cfg.Paths.DataDir, "image-retention-v2.done") // v2 (v0.284.2): the v1 sweep could not see untagged images
}
// RunImageRetentionOnce is the one-time clean-up at the first start of this release: the same rule, applied to every