carlos / platform Public

spec: host lifecycle claim rev 5.1, CC20 sweep moves/<host>/ and CC21 purge fence

S3 cannot condition the claim write on the registration's version, so purge
fences a drained registration's host claim before removing it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 64eec93b798761a05ade8b1a09bfca12a39d95b6 parent 4a458a9
1 file changed, +25 −2
  • docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md +25 −2

CI passed — run details

diff --git a/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md b/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
index cb2597a7c..df41dd1b4 100644
--- a/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
+++ b/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
@@ -1,6 +1,6 @@
# The host lifecycle claim
-Design, 2026-10-03, **rev 5**. A small primitive cited by:
+Design, 2026-10-03, **rev 5.1** (rev 5 plus CC20, CC21). A small primitive cited by:
- **#199**, deleting an instance and parking its data:
`2026-10-02-replica-ownership-design.md`, which this spec supersedes
@@ -401,7 +401,26 @@ site now uses:
like any other. Expiry alone is not enough: dropping such a
registration would let purge tear down a store the create already
uses. A crashed console's registration therefore expires and drains,
- and does not block every purge. This is tested with
+ and does not block every purge.
+
+ **Fencing a paused creator (CC21).** A console can renew its
+ registration, pause, and then resume after purge has drained that
+ registration. S3 cannot make the creator's claim write conditional on
+ the registration object's version, because they are two objects. So
+ purge fences from the claim side:
+ - before removing a registration whose host claim doesn't name the
+ create, purge CASes that host's claim from free or absent to a
+ **purge fence**, `{op: {kind: "purging", id: <purge id>}}`, with no
+ holder;
+ - only then does it remove the registration.
+
+ The paused creator's claim CAS (§5.1 step 2) is from free or absent,
+ so it now fails, and the create is refused before any record exists.
+ The fence is released to free at the purge's completion (`done`).
+ The creator also re-reads its registration as its last step before
+ the claim CAS, and stops if it is gone or admission is closed. That is
+ cheap, but not sufficient on its own; the fence is what guarantees
+ it. This is tested with
at least two hosts.
1a. **Adopt first (CC6).** Run the one adoption routine (§9) for every
record of the app that has no claim, before deciding which hosts the
@@ -517,6 +536,8 @@ host it can see in its bucket that has no operation running. It lists:
- the location of every incarnation in that host's
`retired_incarnations`;
+- **`moves/<host>/`** (CC20): a staging write that completes after its
+ move's cleanup would otherwise stay there for good;
- every generation within the live `holder.location` other than
`holder.generation` (the moves spec's dead generations).
@@ -817,6 +838,8 @@ the model catches it.
| CC17 | §5.1 step 5 |
| CC18 | §2 `holder.generation` |
| CC19 | C3, the staging-work lease exception |
+| CC20 | §6.2a at-rest sweep |
+| CC21 | §5.3 step 1b, the purge fence |
## 13. S3 behaviour this relies on, verified