carlos / platform Public

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
Paul Campbell pushed by paul@keymail.dev 6059beb7bce9bbd2d54fd4f24ec8dff0889c3e23 parent 38b0b8d
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).