spec: record the review-round-1 amendments — staging wins, two-phase abort, cut re-checkpoint, worker rails (#331)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PEypt7de2X1G84aQ9rNkCf
1 file changed,
+24
−10
docs/superpowers/specs/2026-08-28-instance-move-design.md+24 −10
diff --git a/docs/superpowers/specs/2026-08-28-instance-move-design.md b/docs/superpowers/specs/2026-08-28-instance-move-design.md| index bc9ca5a82..571c75eaf 100644 |
| --- a/docs/superpowers/specs/2026-08-28-instance-move-design.md |
| +++ b/docs/superpowers/specs/2026-08-28-instance-move-design.md |
| @@ -36,7 +36,7 @@ move is in flight: |
| ```json |
| "move": { |
| "to": "uk", |
| - "state": "preparing" | "ready" | "cutting", |
| + "state": "preparing" | "ready" | "cutting" | "aborting", |
| "requested_at": "<RFC3339>", |
| "ready_at": "<RFC3339, when state >= ready>" |
| } |
| @@ -67,10 +67,11 @@ instance itself): |
| calls this only after freezing writes; the platform does not verify |
| the freeze (it cannot — the freeze is app-level), it documents it. |
| - `DELETE .../instances/{host}/move` — abort, legal in `preparing` or |
| - `ready` (clears `move`; the source drops its second replica; staged |
| - bytes in the target bucket are garbage that the next prepare |
| - overwrites and the target's post-restore cleanup deletes). Refused |
| - 409 in `cutting`: past that point the move completes forward. |
| + `ready`. TWO-PHASE (review round 1): the door marks `aborting`; the |
| + SOURCE box deletes the staged copy from the target bucket and then |
| + clears `move` — a bare clear would leave staging behind to win a |
| + later landing on the target (staging-wins below). Refused 409 in |
| + `cutting` (completes forward) and in `aborting` (already under way). |
| - State is read, not pushed: the existing single-record GET already |
| returns the record verbatim, so `move.state` is pollable today with |
| zero new read surface. |
| @@ -108,13 +109,17 @@ The reconcile/activator pass on the box whose `CARLOS_REGION` matches |
| `move.state: "preparing" → "ready"`, stamping `ready_at`. Rounds |
| keep running — ready is a level, not an edge; writes after ready |
| keep flowing into staging on the next round. |
| -3. **cutting**: on seeing `state:"cutting"`, the source (in order): |
| - set the route's Status to "moving" (a non-ready status: the edge |
| +3. **cutting** (order amended, review round 1): on seeing |
| + `state:"cutting"`, the source (in order): set the route's Status to |
| + "moving" (a non-ready status: the edge |
| stops serving it, the edges file drops it, and the activator's |
| RetireExcept sweep stops the child through the ordinary stop path — |
| - which final-checkpoints to the source's OWN bucket, the |
| - abort-recovery copy) → wait for the child to be down → one final |
| - delta round into staging (now byte-identical to the own replica) → |
| + which final-checkpoints to the source's OWN bucket — but SWALLOWS a |
| + checkpoint failure, safe only while the warm cache stood behind it) |
| + → wait for the child to be down → **re-checkpoint the local DB with |
| + the lease and wait** (proving the own replica carries the tail — |
| + review round 1, the failed-final-checkpoint data-loss hole) → one |
| + final delta round into staging (now byte-identical to the own replica) → |
| **delete the local DB, WAL/SHM, and litestream meta dirs** (the |
| warm-cache purge; without it a later move back would resurrect a |
| stale local file — the activator's warm-cache trust is exactly right |
| @@ -171,6 +176,15 @@ titogo's boot-clears-freeze rule needs exactly this. |
| (400 naming the kind) — the only class whose state the platform owns. |
| - Fleet placements (`fleet/<name>`): refused; fleets keep D6 |
| state-does-not-follow semantics on purpose. |
| +- Pooled records (`pool != ""`): refused in v1 — their data lives on |
| + the pool's box, not the platform region box that would drive the |
| + move. Non-hibernating instances (`hibernate:false`): refused — they |
| + run outside the activator, so nothing manages (or could quiesce) |
| + their data. |
| +- The worker acts only on routes its OWN registry serves: region |
| + equality alone would let a standby or second same-region box drive a |
| + cut whose child runs on its sibling (per-box registries make its |
| + Quiesced trivially true). |
| - Automatic freeze verification; region-aware unit economics; the |
| member-facing residence door (titogo builds on these verbs). |