carlos / platform Public

sim: hostlife: a rollback whose target was declared lost declares what the seal held (INV-15's exception)

Found by the rev 7.11 30,000-seed baseline (seed 8035): the target was
declared lost before any return lane ran, the console's release made the
return clean, and the source's cold admission declared a write the seal
in the target's region holds. No lane can carry it and the source cannot
read the sibling bucket, so the declaration stands and the record names
where an operator finds it (§7.10).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev d1c7b839b0fa4b50b9001ad7c548dfef83a0a2ea parent 428fee1
1 file changed, +5 −1
  • internal/sim/hostlife/protocol_test.go +5 −1
diff --git a/internal/sim/hostlife/protocol_test.go b/internal/sim/hostlife/protocol_test.go
index 3073e5d5f..68f14c928 100644
--- a/internal/sim/hostlife/protocol_test.go
+++ b/internal/sim/hostlife/protocol_test.go
@@ -1414,7 +1414,11 @@ func (w *world) admitCommit(b *box, c *claim, a admitInput) bool {
for i := range w.acks {
x := &w.acks[i]
if x.Box == lost.Box && x.Inc == h.Inc && x.Kind == "write" && !x.Exempt && !w.durableInLineage(h.Location, a.NewGeneration, x.W) {
- declaredLost := contains(w.claim.Lost, lost.Box) || w.claim.Op.LostAt != 0 && w.claim.Op.LostBox == lost.Box
+ // a rollback whose target was declared lost has no return lane:
+ // what the seal holds in the target's region is the operator's
+ // (§7.10), and the source declares what its own replica lacks
+ // (seed 8035 / 30,000)
+ declaredLost := contains(w.claim.Lost, lost.Box) || w.claim.Op.LostAt != 0
if w.isDurable(x.W) && !declaredLost {
// INV-15 (rev 7.11): a write the host's remote holds is never
// declared lost while its writer's box is still with us; the