carlos / platform Public

sim: hostlife: an empty dead generation still gets its park-generation chore

Found by the rev 7.12 30,000-seed baseline (seeds 15273 and 20810): the
previous commit queued no chore for a dead generation holding nothing in
the publishing region, and a dead writer's late upload or certificate
then landed in it with no chore owing it. The chore is queued for every
dead generation of this region, empty or not; only one whose objects are
another region's is left to that region's publication.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev af9b89ed5eb8518963f72e1c9a4bf52cb7230606 parent 18d977a
1 file changed, +6 −3
  • internal/sim/hostlife/protocol_test.go +6 −3
diff --git a/internal/sim/hostlife/protocol_test.go b/internal/sim/hostlife/protocol_test.go
index 8c9cc3713..df2e4e835 100644
--- a/internal/sim/hostlife/protocol_test.go
+++ b/internal/sim/hostlife/protocol_test.go
@@ -944,7 +944,7 @@ func (w *world) publishGeneration(b *box, c *claim, observedOpID, observedPhase
// stays uncovered for that region's next PublishGeneration: a
// chore queued there from here would park a generation the
// rollback may still need (seeds 33646, 40148, 1296 / rev 7.12)
- if e.Predecessor.Gen == published || !w.hasFilesAnywhere(n.Holder.Location, e.Predecessor.Gen) || hasStr(dead, e.Predecessor.Gen) && w.hasFilesIn(region, n.Holder.Location, e.Predecessor.Gen) {
+ if e.Predecessor.Gen == published || hasStr(dead, e.Predecessor.Gen) && (w.hasFilesIn(region, n.Holder.Location, e.Predecessor.Gen) || !w.hasFilesAnywhere(n.Holder.Location, e.Predecessor.Gen)) {
e.Covered = true
}
}
@@ -962,9 +962,12 @@ func (w *world) publishGeneration(b *box, c *claim, observedOpID, observedPhase
}
n.Holder.Admissions = keep
for _, retire := range dead {
- if retire == published || !w.hasFilesIn(region, n.Holder.Location, retire) {
- continue // nothing of it here: an empty generation, or one whose objects are another region's
+ if retire == published || !w.hasFilesIn(region, n.Holder.Location, retire) && w.hasFilesAnywhere(n.Holder.Location, retire) {
+ continue // its objects are another region's: that region's publication retires it
}
+ // an empty dead generation still gets its chore: a dead writer's
+ // late upload or certificate may land in it within the chore's
+ // horizon (seeds 15273 and 20810 / 30,000)
ret := retire
if ret == "" {
ret = "@root" // the sentinel for the origin generation (claim rev 6.10)