moves: the arming comments and notices name the claim's park hooks and claim Plan 12 (Plan 5 Task 9a)
Comments and standing log notices that still said the arms wait on "Plan 5's view" or ruling G17's stand-ins now say what Task 9a left: the claim's park hooks come from MoveParks through armMovesParks, set only once claim Plan 12 lands, and nothing stands in for them. No behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 files changed,
+50
−44
internal/host/movesfinal.go+1 −1internal/host/movesinstall.go+5 −4internal/host/movesland.go+10 −9internal/host/moveslandcommit.go+2 −1internal/host/movesparks.go+2 −2internal/host/movespass.go+12 −10internal/host/movesrecover.go+7 −6internal/host/movesrevert.go+3 −3internal/host/movesrollback.go+8 −8
diff --git a/internal/host/movesfinal.go b/internal/host/movesfinal.go| index 01ce52ef4..4c6502015 100644 |
| --- a/internal/host/movesfinal.go |
| +++ b/internal/host/movesfinal.go |
| @@ -215,7 +215,7 @@ func (w *movesWorker) finalizeSource(ctx context.Context, s release.Store, rec p |
| return nil |
| } |
| if !sourceFinalArmed(cfg) { |
| - w.notice(rec.Host+"#final", "moves: %s: the source's finalization of %s waits: this box's finalization is not armed (Plan 5's park view and the park engine's leases are needed)", rec.Host, m.ID) |
| + w.notice(rec.Host+"#final", "moves: %s: the source's finalization of %s waits: this box's finalization is not armed (the claim's park hooks, set from MoveParks once claim Plan 12 lands, are needed)", rec.Host, m.ID) |
| return nil |
| } |
| f := &sourceFinal{w: w, s: s, rec: rec, g: provision.MoveGuard{ID: m.ID, Incarnation: m.Incarnation}} |
diff --git a/internal/host/movesinstall.go b/internal/host/movesinstall.go| index 4b0e3526d..b4b7c611c 100644 |
| --- a/internal/host/movesinstall.go |
| +++ b/internal/host/movesinstall.go |
| @@ -54,15 +54,16 @@ import ( |
| // of every pre-move artifact still at the flat paths, inside the host |
| // guard. placeStaged and restore then find nothing there, and refuse |
| // anything that appears; |
| -// - the stand-in park view's authoritative region (J24): the source's for |
| -// a landing, the target's for a return, each the other side of the move |
| -// before this side's probe is admitted. |
| +// - the authoritative region the claim's view names for its parks (J24, |
| +// §5.1): the source's for a landing, the target's for a return, each the |
| +// other side of the move before this side's probe is admitted. |
| // |
| // The phase-name convention is Plan 2's (G8): restored is written by the CAS |
| // that ends configured, after the database is installed and its markers |
| // written. Every record write goes through a provision transition (the |
| // record_seq rule). The installer is unarmed in production, as the landing |
| -// is (ruling G17): only the landing's pass and the tests call it. |
| +// is (Plan 5 Task 9a: until claim Plan 12 lands): only the landing's pass, |
| +// the recovery and the tests call it. |
| // installStepPreMove is the moves-owned rename of a return's pre-move |
| // artifacts (parkLocalArtifacts' step: the retirement id). |
diff --git a/internal/host/movesland.go b/internal/host/movesland.go| index b05582916..a24fb2aea 100644 |
| --- a/internal/host/movesland.go |
| +++ b/internal/host/movesland.go |
| @@ -70,14 +70,15 @@ import ( |
| // paths: the archive is extracted into the op's own staging and moved into |
| // place only when nothing it did not write is there. |
| // |
| -// Arming (ruling G17). armPhase1 wires the hooks that exist on main (the |
| -// guard, park.Local, the own-location lease, RenderHeld, the registry |
| -// setters, the restore-verification record, the marker writer), and leaves |
| -// ParkLeases, ParkView and ParkAuthorize nil: the production park engine |
| -// needs claim Plan 6b's regional runner for the acknowledgement half and |
| -// Plan 5's view and authorizer. landingArmed therefore answers false in |
| -// production and the pass logs a standing notice instead of landing; the |
| -// tests arm everything with fakes and the stand-ins below. Under |
| +// Arming (ruling G17; Plan 5 Task 9a). armPhase1 wires the hooks that exist |
| +// on main (the guard, park.Local, the own-location lease, RenderHeld, the |
| +// registry setters, the restore-verification record, the marker writer). |
| +// ParkLeases, ParkView and ParkAuthorize are the claim's (MoveParks), and |
| +// ParkRunHeld claim Plan 12's (M5), all set by armMovesParks only once claim |
| +// Plan 12 lands; nothing stands in for them. landingArmed therefore answers |
| +// false in production and the pass logs a standing notice instead of |
| +// landing; the tests arm everything with fakes (movesparkfakes_test.go). |
| +// Under |
| // CARLOS_HOST_CLAIM the landing refuses at checking with a recorded reason |
| // (ruling G16). The policy its held writes need, hostbox.Policy.Moves, is |
| // MovesClaimPolicy (movespolicy.go) and the timers import already selects |
| @@ -166,7 +167,7 @@ func (w *movesWorker) landingPass(ctx context.Context, s release.Store, rec prov |
| return err |
| } |
| if !landingArmed(cfg) { |
| - w.notice(rec.Host+"#landing", "moves: %s: the landing of %s waits: this box's landing is not armed (claim Plan 6b's regional runner and Plan 5's park view are needed)", rec.Host, rec.Move.ID) |
| + w.notice(rec.Host+"#landing", "moves: %s: the landing of %s waits: this box's landing is not armed (the claim's park hooks, set from MoveParks once claim Plan 12 lands, are needed)", rec.Host, rec.Move.ID) |
| return nil |
| } |
| l := &landingRun{w: w, s: s, rec: rec, g: provision.MoveGuard{ID: rec.Move.ID, Incarnation: rec.Move.Incarnation}} |
diff --git a/internal/host/moveslandcommit.go b/internal/host/moveslandcommit.go| index 721073acf..597d19885 100644 |
| --- a/internal/host/moveslandcommit.go |
| +++ b/internal/host/moveslandcommit.go |
| @@ -42,7 +42,8 @@ import ( |
| // rest and only clears the record. |
| // |
| // Unarmed in production with the rest of the landing: landingArmed fails |
| -// there (ruling G17), and the open needs ReleaseHeld. |
| +// there until claim Plan 12 lands (Plan 5 Task 9a), and the open needs |
| +// ReleaseHeld. |
| // probed commits the landing: the record's CAS, then the committed arm. |
| func (l *landingRun) probed(ctx context.Context) (bool, error) { |
diff --git a/internal/host/movesparks.go b/internal/host/movesparks.go| index 9ec7aa2d6..8abaf8631 100644 |
| --- a/internal/host/movesparks.go |
| +++ b/internal/host/movesparks.go |
| @@ -46,8 +46,8 @@ import ( |
| // Production (K4). The staging park and the close are production-live only |
| // after Plan 5 Task 9 (park arming) and claim Plans 10 and 11. The committed |
| // arm runs only where the landing is armed (landingArmed), and production |
| -// wires neither the park engine's leases nor Plan 5's view and authorizer |
| -// until Task 9; the commit and the open themselves need the probe wake of |
| +// sets the claim's park leases, view and authorizer (armMovesParks, Plan 5 |
| +// Task 9a) only once claim Plan 12 lands; the commit and the open themselves need the probe wake of |
| // claim Plan 11's launcher; and the source's location park is acknowledged |
| // by C4's regional runner, whose moves evidence is claim Plan 10's. Until |
| // then the tests arm everything with fakes. |
diff --git a/internal/host/movespass.go b/internal/host/movespass.go| index 34c5ad974..cfe003095 100644 |
| --- a/internal/host/movespass.go |
| +++ b/internal/host/movespass.go |
| @@ -303,11 +303,12 @@ func armPhase1(cfg *moveCfg, w *movesWorker, hib activator.Config, dataDir strin |
| cfg.HoldMoving = holdMoving(reg, holdStageRequester(dataDir)) |
| cfg.Timers = reg.TimersFor |
| } |
| - // The landing (movesland.go). Everything that exists on main is wired; |
| - // ParkLeases, ParkView and ParkAuthorize are not (ruling G17: the |
| - // residue parks need claim Plan 6b's regional runner for their |
| - // acknowledgement and Plan 5's view and authorizer), so landingArmed is |
| - // false in production and the landing pass only logs. The held timers |
| + // The landing (movesland.go). Everything that exists on main is wired |
| + // here; ParkLeases, ParkView and ParkAuthorize come from the claim's |
| + // MoveParks (armMovesParks, Plan 5 Task 9a, in armMovesPass), with claim |
| + // Plan 12's RunHeld and local authorizer, and are set only once claim |
| + // Plan 12 lands, so landingArmed is false in production and the landing |
| + // pass only logs. The held timers |
| // write goes through schedule.SelectedTimers with a held-timers Work |
| // selected from writes (ruling G16, heldTimersReplacer): with |
| // CARLOS_HOST_CLAIM off that is the registry's own ReplaceTimers, as |
| @@ -560,11 +561,12 @@ type moveCfg struct { |
| // over this box's data directory (its Claims are set per pass from the |
| // pass's store when nil); Local is park.Local over the same directory |
| // (its Guard, Claims and, when nil, Authorize are set per pass). |
| - // ParkLeases, ParkView and ParkAuthorize are the park engine's over the |
| - // own bucket for the residue parks: nil in production until claim Plan |
| - // 6b's regional runner and Plan 5's providers (ruling G17), which is |
| - // what leaves the landing unarmed there (landingArmed); a nil View or |
| - // Authorize with ParkLeases set gets the landing's stand-ins. OwnLease |
| + // ParkLeases, ParkView and ParkAuthorize are the claim's park engine's |
| + // (MoveParks, armMovesParks): its leases, view and authorizer over the |
| + // own bucket. Every arm requires all three (parkHooksArmed) and runs its |
| + // own check before the authorizer (movesArmAuthorize); nothing stands |
| + // in. In production they are set only once claim Plan 12 lands, which |
| + // leaves every arm unarmed there. OwnLease |
| // takes the location's lease in the own bucket for the build |
| // (hostbox.RenewingLeases over lease.Acquire). RenderHeld is |
| // appconfig.RenderHeld for the held row; ReplaceTimers is the |
diff --git a/internal/host/movesrecover.go b/internal/host/movesrecover.go| index 5fc61d7a6..af5e5757c 100644 |
| --- a/internal/host/movesrecover.go |
| +++ b/internal/host/movesrecover.go |
| @@ -91,11 +91,12 @@ import ( |
| // Every record write goes through a provision transition (the record_seq |
| // rule); every claim write through a hostclaim transition. |
| // |
| -// Arming (rulings J18, G17). Like the landing and the target's half of the |
| -// rollback, the source's recovery is unarmed in production until Plan 5: |
| -// it needs the park engine's leases (ParkLeases, for the dirty return's |
| -// residue parks), which production does not wire, so recoverySourceArmed |
| -// answers false there and the pass logs a standing notice. The probe hook is |
| +// Arming (rulings J18, G17; Plan 5 Task 9a). Like the landing and the |
| +// target's half of the rollback, the source's recovery needs the claim's |
| +// park hooks and claim Plan 12's RunHeld (for the dirty return's residue |
| +// parks), which armMovesParks sets only once claim Plan 12 lands, so |
| +// recoverySourceArmed answers false in production and the pass logs a |
| +// standing notice. The probe hook is |
| // the recovery probe adapter (armRecoveryProbe) with CARLOS_HOST_CLAIM on, |
| // bound to the activator's Group D entry. Without the claim switch the |
| // legacy nil hook still waits, recording nothing. LogEvent |
| @@ -193,7 +194,7 @@ func (w *movesWorker) recoverSource(ctx context.Context, s release.Store, rec pr |
| return nil |
| } |
| if !recoverySourceArmed(cfg) { |
| - w.notice(rec.Host+"#recover", "moves: %s: the source's recovery of rollback %s waits: this box's recovery is not armed (Plan 5's park view and the park engine's leases are needed)", rec.Host, m.Rollback.ID) |
| + w.notice(rec.Host+"#recover", "moves: %s: the source's recovery of rollback %s waits: this box's recovery is not armed (the claim's park hooks, set from MoveParks once claim Plan 12 lands, are needed)", rec.Host, m.Rollback.ID) |
| return nil |
| } |
| r := &recoverRun{w: w, s: s, rec: rec, g: provision.MoveGuard{ID: m.ID, Incarnation: m.Incarnation}, rb: m.Rollback.ID} |
diff --git a/internal/host/movesrevert.go b/internal/host/movesrevert.go| index 0689f18a9..6960da54d 100644 |
| --- a/internal/host/movesrevert.go |
| +++ b/internal/host/movesrevert.go |
| @@ -94,8 +94,8 @@ import ( |
| // unarmed in production until Plan 5: the recovery probe is nil there until |
| // Task 9 (claim Plan 10's recovery admission), so revertSourceArmed answers |
| // false and the source only writes the claim half, as Plan 2's arm did; and |
| -// the target's lane park needs the park engine's leases (ParkLeases), which |
| -// production does not wire (revertLaneArmed). LogEvent is nil in production, |
| +// the target's lane park needs the claim's park leases, view and authorizer, |
| +// which armMovesParks sets only once claim Plan 12 lands (revertLaneArmed). LogEvent is nil in production, |
| // where an event is a log line. |
| // revertStepsPerPass bounds the steps one pass runs: evidence to the close is |
| @@ -876,7 +876,7 @@ func (w *movesWorker) laneParkTarget(ctx context.Context, s release.Store, rec p |
| notice = rec.Host + "#rv-lane" |
| } |
| if !revertLaneArmed(cfg) { |
| - w.notice(notice, "moves: %s: the park of move %s's lane waits: this box's park engine is not armed (Plan 5's park view and the park engine's leases are needed)", rec.Host, m.ID) |
| + w.notice(notice, "moves: %s: the park of move %s's lane waits: this box's park engine is not armed (the claim's park hooks, set from MoveParks once claim Plan 12 lands, are needed)", rec.Host, m.ID) |
| return nil |
| } |
| host, id := rec.Host, m.ID |
diff --git a/internal/host/movesrollback.go b/internal/host/movesrollback.go| index c888a781e..f1a2c46e3 100644 |
| --- a/internal/host/movesrollback.go |
| +++ b/internal/host/movesrollback.go |
| @@ -90,10 +90,10 @@ import ( |
| // transaction under the host's hold lock (J12); the record says cleaned |
| // with target_parked_at, and the op's journal is parked last. |
| // |
| -// Arming (ruling J18). Like the landing, the rollback's target half is |
| -// unarmed in production until Plan 5: it needs the park engine's leases |
| -// (ParkLeases), which production does not wire, so rollbackTargetArmed |
| -// answers false there and the pass logs a standing notice. The decision is |
| +// Arming (ruling J18; Plan 5 Task 9a). Like the landing, the rollback's |
| +// target half needs the claim's park leases, view and authorizer, which |
| +// armMovesParks sets only once claim Plan 12 lands, so rollbackTargetArmed |
| +// answers false in production and the pass logs a standing notice. The decision is |
| // not gated (J10). The move's event log (moves.LogEvent, Plan 6) is the |
| // LogEvent hook: nil in production, where the event is a log line. The |
| // stuck mark pages an operator (pageStuck, the Page hook); the release |
| @@ -246,9 +246,9 @@ func (w *movesWorker) rollbackClaim(ctx context.Context, s release.Store, rec pr |
| } |
| // rollbackTargetArmed reports whether this box can run the target's half of |
| -// a rollback: every hook it calls is wired, the park engine's leases |
| -// included. In production ParkLeases is not (ruling G17), so this answers |
| -// false there (J18). |
| +// a rollback: every hook it calls is wired, the claim's three park hooks |
| +// included. In production armMovesParks sets them only once claim Plan 12 |
| +// lands, so this answers false there (J18). |
| func rollbackTargetArmed(cfg moveCfg) bool { |
| return cfg.Box != "" && cfg.DataDir != "" && cfg.Guard.DataDir != "" && cfg.Local.DataDir != "" && parkHooksArmed(cfg) && |
| cfg.HandHold != nil && cfg.Fence != nil && cfg.TimersDrained != nil && cfg.Evidence != nil && cfg.FinalCheckpoint != nil && |
| @@ -280,7 +280,7 @@ func (w *movesWorker) rollbackTarget(ctx context.Context, s release.Store, rec p |
| // nothing held is nothing to release. |
| releaseOwnLease(w, rec.Host) |
| if !rollbackTargetArmed(cfg) { |
| - w.notice(rec.Host+"#rollback", "moves: %s: the target's half of rollback %s waits: this box's rollback is not armed (Plan 5's park view and the park engine's leases are needed)", rec.Host, m.Rollback.ID) |
| + w.notice(rec.Host+"#rollback", "moves: %s: the target's half of rollback %s waits: this box's rollback is not armed (the claim's park hooks, set from MoveParks once claim Plan 12 lands, are needed)", rec.Host, m.Rollback.ID) |
| return nil |
| } |
| r := &rollbackRun{w: w, s: s, rec: rec, g: provision.MoveGuard{ID: m.ID, Incarnation: m.Incarnation}, rb: m.Rollback.ID} |