carlos / platform Public

sim: hostlife: a restored database replicates from the TXID it restored to

Rev 7.5's first baseline lost durable writes at 2 / 30,000: after a cold
restore the replicator's position stayed at 0, so the next level-0 file
claimed [1, TX] while carrying only the pending pages; the planner
preferred it and the checksum check refused the restore, correctly. The
model's restore now sets the position where litestream's -txid sidecar
does. Package doc cites claim rev 6.2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev e08c5fd0d4f8326efaa918b16f3e886af8ff5086 parent 5de710b
2 files changed, +9 −5
  • internal/sim/hostlife/protocol_test.go +7 −3
  • internal/sim/hostlife/world_test.go +2 −2
diff --git a/internal/sim/hostlife/protocol_test.go b/internal/sim/hostlife/protocol_test.go
index 6ee60967c..5a293f31c 100644
--- a/internal/sim/hostlife/protocol_test.go
+++ b/internal/sim/hostlife/protocol_test.go
@@ -192,7 +192,7 @@ func (w *world) restore(b *box, inc int, loc, gen string) *localDB {
}
if best != nil {
apply(db.State, best.B)
- db.TX, db.Key = best.B.Max, best.B.SealKey
+ db.TX, db.Rep, db.Key = best.B.Max, best.B.Max, best.B.SealKey
if best.B.Inc != 0 {
db.Inc = best.B.Inc
}
@@ -242,7 +242,11 @@ func (w *world) restore(b *box, inc int, loc, gen string) *localDB {
if last == nil && gen != "" {
return nil
}
- db.TX = cur
+ // the restored database's replication position is where the restore
+ // reached: its next LTX file starts at cur+1 (litestream's -txid
+ // sidecar). Rev 7.5's first run shipped [1, TX] with only the new pages
+ // after a cold restore; the checksum check refused it, correctly
+ db.TX, db.Rep = cur, cur
return db
}
@@ -291,7 +295,7 @@ func (w *world) spawn(b *box, c *claim, want string, probe bool) bool {
}
if newest != nil {
apply(b.DB.State, newest.B)
- b.DB.TX, b.DB.Key = newest.B.Max, newest.B.SealKey
+ b.DB.TX, b.DB.Rep, b.DB.Key = newest.B.Max, newest.B.Max, newest.B.SealKey
if newest.B.Inc != 0 {
b.DB.Inc = newest.B.Inc
}
diff --git a/internal/sim/hostlife/world_test.go b/internal/sim/hostlife/world_test.go
index 7e1299163..372891001 100644
--- a/internal/sim/hostlife/world_test.go
+++ b/internal/sim/hostlife/world_test.go
@@ -1,7 +1,7 @@
// Package hostlife is a deterministic, randomized model of the host
// lifecycle claim (docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md,
-// rev 6, 3ea3f90c) and Phase 1 of move-any-app
-// (docs/superpowers/specs/2026-10-02-move-any-app-design.md, rev 7.4).
+// rev 6.2, 30d572c4) and Phase 1 of move-any-app
+// (docs/superpowers/specs/2026-10-02-move-any-app-design.md, rev 7.5).
//
// Since joint round 2 the model encodes what the specs say and nothing
// stronger: restore reads the holder's location and the generation the