carlos / platform Public

moves pass: the switch off leaves the move log's memory alone too (final re-review 1, I1)

retireMoves ran on every pass, so a pass with CARLOS_MOVES_PHASE1 off
still forgot the remembered identities of moves another writer had closed
or replaced. It now runs only with the switch on, like the outbox flushes
and the tombstone sweep. The regression uses a non-empty record store
(one move closed, another replaced) and checks that the memory is
unchanged with the switch off and retired once the switch is on again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 9b5a2d5fbd35ad5ed5c5acf69431c74a7ce9561d parent 9ca5601
3 files changed, +51 −2
  • internal/host/movesevents_test.go +1 −0
  • internal/host/movespaging_test.go +44 −0
  • internal/host/movespass.go +6 −2
diff --git a/internal/host/movesevents_test.go b/internal/host/movesevents_test.go
index a0ead14b4..9b7bb9ea5 100644
--- a/internal/host/movesevents_test.go
+++ b/internal/host/movesevents_test.go
@@ -607,6 +607,7 @@ func TestLogMemoRetiresAMoveClosedElsewhere(t *testing.T) {
if w.logged.len() == 0 {
t.Fatal("nothing remembered")
}
+ w.cfg.Enabled = true // the pass forgets only with the switch on (I1)
s := release.NewDirStore(t.TempDir())
closed := flow[len(flow)-1]
if err := provision.CreateRecord(ctx, s, closed); err != nil {
diff --git a/internal/host/movespaging_test.go b/internal/host/movespaging_test.go
index 6f4899a7f..104ef9f7b 100644
--- a/internal/host/movespaging_test.go
+++ b/internal/host/movespaging_test.go
@@ -811,3 +811,47 @@ func writePageEntryFixture(dataDir string, e pageEntry) error {
}
return os.WriteFile(filepath.Join(dir, e.Rule+".json"), b, 0o600)
}
+
+// Final re-review 1, I1: with the switch off a pass touches no outbox, index
+// or memo state. Here the move log's memory remembers two moves; the store
+// then holds one host's record closed and another's replaced by a new move,
+// which a pass with the switch on would forget. Off, the memory is exactly
+// what it was.
+func TestSwitchOffPassLeavesTheLogMemo(t *testing.T) {
+ ctx := context.Background()
+ var got []moves.LogEvent
+ w := eventWorker(&got)
+ flow := doneFlow()
+ w.observeMove(ctx, nil, flow[0]) // acme.go.tito.io, mvEvMoveID: requested
+ other := mvEvRec(provision.MovePreparing, func(m *provision.MoveState) { m.ID = "mv_otherotherotherotherother" })
+ other.Host = "b.example.com"
+ w.observeMove(ctx, nil, other)
+ keys := []string{flow[0].Host + "/" + mvEvMoveID + "/requested", other.Host + "/mv_otherotherotherotherother/requested"}
+ before := w.logged.len()
+ if before != 2 || !w.logged.seen(keys[0]) || !w.logged.seen(keys[1]) {
+ t.Fatalf("the fixture's memory: %d", before)
+ }
+ s := release.NewDirStore(t.TempDir())
+ if err := provision.CreateRecord(ctx, s, flow[len(flow)-1]); err != nil { // closed
+ t.Fatal(err)
+ }
+ replaced := mvEvRec(provision.MovePreparing, func(m *provision.MoveState) { m.ID = "mv_nextnextnextnextnextnextne" })
+ replaced.Host = other.Host
+ if err := provision.CreateRecord(ctx, s, replaced); err != nil {
+ t.Fatal(err)
+ }
+ w.cfg.Enabled = false
+ if err := movesPass(ctx, s, w); err != nil {
+ t.Fatal(err)
+ }
+ if n := w.logged.len(); n != before || !w.logged.seen(keys[0]) || !w.logged.seen(keys[1]) {
+ t.Fatalf("a pass with the switch off changed the move log's memory: %d identities, want %d", n, before)
+ }
+ w.cfg.Enabled = true
+ if err := movesPass(ctx, s, w); err != nil {
+ t.Fatal(err)
+ }
+ if w.logged.seen(keys[0]) || w.logged.seen(keys[1]) {
+ t.Fatal("with the switch on the closed and replaced moves are still remembered")
+ }
+}
diff --git a/internal/host/movespass.go b/internal/host/movespass.go
index ad3d3aed2..fd9a0703c 100644
--- a/internal/host/movespass.go
+++ b/internal/host/movespass.go
@@ -770,8 +770,12 @@ func movesPass(ctx context.Context, s release.Store, w *movesWorker) error {
}
for _, rec := range recs {
// A move closed or replaced by another writer is forgotten by the
- // move log's memory (movesevents.go).
- w.retireMoves(rec)
+ // move log's memory (movesevents.go). With the switch off the pass
+ // touches no outbox, index or memory of the move log at all (final
+ // re-review 1, I1).
+ if cfg.Enabled {
+ w.retireMoves(rec)
+ }
if rec.Move != nil && !rec.Move.Legacy() {
// A Phase 1 record. With the switch off it is never touched
// (none exists unless the switch was on somewhere).