moves: the abort's lane park needs all three park hooks, through the shared predicate (Task 9a fix round 1, minor)
No arming change in movesabort.go is needed: an aborting record's target region reaches the lane park through movesfinal.go's dispatch (laneParkTarget with KindMoving/PhaseAborting), whose arming is the shared lane predicate revertLaneArmed (movesrevert.go:164), which Task 9a's step 2 made require ParkLeases, ParkView and ParkAuthorize (parkHooksArmed). TestAbortWaitsForAnUnreachableTargetRegion now proves it through the abort: with each of the three hooks missing in turn, the target box's pass logs its standing notice, tries no park and leaves the lane. RED (the predicate weakened back to ParkLeases alone): "no park view: the abort's lane park was tried by an unarmed box".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+24
−9
internal/host/movesabort_test.go+24 −9
diff --git a/internal/host/movesabort_test.go b/internal/host/movesabort_test.go| index b725d62c0..871feb728 100644 |
| --- a/internal/host/movesabort_test.go |
| +++ b/internal/host/movesabort_test.go |
| @@ -357,15 +357,30 @@ func TestAbortWaitsForAnUnreachableTargetRegion(t *testing.T) { |
| if err := hostclaim.StartGuard(c, []string{"ie"}, []string{"ie-box"}); err == nil { |
| t.Fatal("a new operation could start over the waiting abort") |
| } |
| - // An unarmed target box (production until Task 9) parks nothing either. |
| - unarmed := h.laneCfg() |
| - unarmed.ParkLeases = nil |
| - w := &movesWorker{cfg: unarmed, mirrors: map[string]lease.MirrorStore{}} |
| - if err := movesPass(context.Background(), h.s, w); err != nil { |
| - t.Fatal(err) |
| - } |
| - if h.laneChore(t) == nil || len(h.laneKeys()) == 0 { |
| - t.Fatal("an unarmed target box parked the lane") |
| + // An unarmed target box parks nothing either: the abort's lane park goes |
| + // through laneParkTarget (movesfinal.go's dispatch for an aborting |
| + // target), whose arming is the shared lane predicate, revertLaneArmed, |
| + // which requires all three of the claim's park hooks (Plan 5 Task 9a, |
| + // M17). Each one missing leaves the arm unarmed, with its standing |
| + // notice, and the lane untouched. |
| + for name, unarm := range map[string]func(*moveCfg){ |
| + "no park leases": func(c *moveCfg) { c.ParkLeases = nil }, |
| + "no park view": func(c *moveCfg) { c.ParkView = nil }, |
| + "no park authorizer": func(c *moveCfg) { c.ParkAuthorize = nil }, |
| + } { |
| + unarmed := h.laneCfg() |
| + unarm(&unarmed) |
| + logs := captureLog(t) |
| + w := &movesWorker{cfg: unarmed, mirrors: map[string]lease.MirrorStore{}} |
| + if err := movesPass(context.Background(), h.s, w); err != nil { |
| + t.Fatal(err) |
| + } |
| + if h.laneChore(t) == nil || len(h.laneKeys()) == 0 { |
| + t.Fatalf("%s: an unarmed target box parked the lane", name) |
| + } |
| + if !strings.Contains(logs(), "this box's park engine is not armed") { |
| + t.Fatalf("%s: the abort's lane park was tried by an unarmed box:\n%s", name, logs()) |
| + } |
| } |
| // Once the region returns, the abort completes. |
| h.tPass(t) |