Let platform manifests go only on a confirmed collect, and copy again what a sweep took

An unrecorded index or a copy in progress can name a platform the records do not see, so
only a person's collect, after its dry run, takes an index's platforms, and only once every
kept index of each repository it touches was read. A copy missing a platform is copied
again, and a copy a build holds again is no longer recorded as collected (review of #144).
This commit is contained in:
jochen
2026-10-08 15:47:42 +02:00
parent 9907df6530
commit c5663aa18b
12 changed files with 485 additions and 48 deletions
+21 -7
View File
@@ -31,6 +31,11 @@ type sweepBounds struct {
most int
// budget is the longest it keeps its caller waiting.
budget time.Duration
// platforms is whether an index is let go of with its own platform manifests (novox/hq ADR 0257).
// Only a sweep a person confirmed, after its dry run listed what stays and names a platform: the
// records cannot see an unrecorded index, or a copy in progress, naming the same platform, and the
// store's tools can.
platforms bool
}
// afterBuild are the bounds of the sweep inside somebody's build.
@@ -76,18 +81,27 @@ func sweep(ctx context.Context, inv *inventory.Inventory, store artifacts.Store,
// as builds come, and is two HEADs each once done. A kept archive that could not be held stops
// the sweep before it deletes anything: "everything kept is held" is the precondition the
// collector's safety rests on, and a store refusing a hold would refuse the deletes too.
// **An index goes with its platform manifests, and a kept index keeps its own** (novox/hq ADR
// 0257): which of a repository's platform manifests a kept index names is read from the store
// before anything there is let go of. A keep set that cannot be read stops the sweep before it
// deletes anything, as a kept archive that cannot be held does.
if store.Spare == nil && inv != nil {
// **An index goes with its platform manifests only when a person confirmed it** (novox/hq ADR
// 0257), and a kept index keeps its own: which platform manifests the kept indexes name is read
// from the store for every repository the sweep will touch, before the first delete. A single
// read that fails stops the sweep before it deletes anything, as a kept archive that cannot be
// held does. The sweep after a build lets an index go alone, as it always has.
store.Spare = nil
if bounds.platforms {
if inv == nil {
r.Stopped = "no records to read which platform manifests a kept index names, so nothing was let go"
r.Left = len(references)
return r
}
images, err := inv.KeptImages(ctx)
if err == nil {
store.Spare, err = store.SpareKeptIndexes(within, images, references)
}
if err != nil {
r.Stopped = fmt.Sprintf("the images the mesh keeps could not be read, so nothing was let go: %v", err)
r.Stopped = fmt.Sprintf("which platform manifests a kept index names could not be read, so nothing was let go: %v", err)
r.Left = len(references)
return r
}
store.Spare = store.SpareKeptIndexes(images)
}
wrote, missing, err := holdKept(within, store, kept)