carlos / platform Public

spec: host lifecycle claim rev 6.11, the moves spec's rev 7.11 notes

holder.admissions records unfinished/uncovered admissions across op
transitions; PublishGeneration covers the chain and queues retirement of
every predecessor (replaces QueueGenerationRetire); unfinished chains;
clean rollback only with src_covered; sealed baseline only from_db; a new
agent stops a running app; adoption sets writer_box.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 63255a3cdc4da17c183aaa03d5dc3c88daf24afd parent 3f916b0
1 file changed, +62 −4
  • docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md +62 −4

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 2bda2e6de..148f7adf3 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,10 +1,11 @@
# The host lifecycle claim
-Design, 2026-10-05, **rev 6.10**. Joint rounds 6 and 7 judged the claim ready for primitive planning. Rev
+Design, 2026-10-05, **rev 6.11**. Joint rounds 6 and 7 judged the claim ready for primitive planning. Rev
6.5 added the R6-4 rule. Rev 6.6 added writer epochs (R7-1, amadan #225).
Rev 6.7 answered the moves session's notes on §6.4a. Rev 6.8 rewrote §6.4a
around writer sessions, for joint round 8. Rev 6.10 answers joint round 10
-(R10-1, R10-2, R10-4, R10-5). Rev 6.9 answered joint round 9
+(R10-1, R10-2, R10-4, R10-5). Rev 6.11 answers the moves spec's rev 7.11
+notes. Rev 6.9 answered joint round 9
(R9-1 to R9-4) and takes **Paul's ruling R6 (2026-10-04): a box never
reuses its local database. Every writer start restores from the
certified remote.** A small primitive cited by:
@@ -99,7 +100,9 @@ replaced whole with conditional writes (`If-Match` on the ETag read).
"generation": "<op id of the installed generation, or \"\">",
"stamp": 41,
"session": 57,
- "writer_box": "adi-knitting"
+ "writer_box": "adi-knitting",
+ "admissions": [{"session": 57, "generation": "g…", "predecessor": "g…",
+ "mode": "cold", "covered": false}]
},
"op": {
"kind": "serving",
@@ -173,6 +176,13 @@ Field rules:
are retired there.
- **`holder.session`** is the current writer session's admission `gen`
(§6.4a). Every `AdmitWriter` CAS moves it forward.
+- **`holder.admissions`** is the record of writer admissions whose chain
+ is not yet finished, or whose predecessors are not yet queued for
+ retirement (rev 7.11 notes 3 and 4). It lives in the holder, so it
+ survives every operation transition, release and new operation. Each
+ entry is `{session, generation, predecessor, mode, covered,
+ writes_lost?}`. Entries are trimmed once covered, keeping at most the
+ last 8.
- **`holder.writer_box`** is the box admitted as that session's writer
(§6.4a). It lives in the holder, not only in an operation's journal, so
it survives an operation being replaced (R9-2).
@@ -918,7 +928,8 @@ After a conflicting CAS, the box re-establishes its **evidence**
fresh read alone isn't enough.
**Chores raised while serving, and the root generation (R10-5).** A chore
-queued while the claim is `serving` has `op = "session:<holder.session>"`,
+queued while the claim is `serving` (through `PublishGeneration`, rev 7.11
+note 4) has `op = "session:<holder.session>"`,
and is owned as usual. An example is retiring a superseded generation
once its successor's root is published. An adopted legacy host's
generation is the location root itself (level directories directly
@@ -1039,6 +1050,53 @@ It records this in its journal entry, and the admitting box raises an
alert. `holder.writer_box` makes the box known even when the operation
that admitted the crashed writer has since been replaced (R9-2).
+#### Readings settled with the moves spec (rev 7.11)
+
+1. **Retry limit:** five start attempts within one session, with doubling
+ backoff (1, 2, 4, 8, 16). A start the environment isn't ready for waits
+ without counting an attempt. At the fifth failure the box marks the
+ host failed and creates no session until an operator or a health
+ signal clears it. Confirmed.
+2. **A chain of unfinished admissions.** The unfinished state covers a
+ **run** of admissions, each of which died before its generation's
+ marker was published. Every generation in the chain, from the marker's
+ generation through `holder.generation`, is live, and raises no alert.
+ The baseline is the newest generation in the chain that holds an
+ object, else the marker's generation. `holder.admissions` is how the
+ chain is known.
+3. **The admissions record survives release** and the next operation,
+ because it lives in `holder.admissions`, not in an operation's
+ journal. Writes-lost declarations are kept there too. `op.journal`
+ keeps no separate writers record.
+4. **Uncovered predecessors.** Publishing a generation's marker is
+ followed by one `PublishGeneration` CAS, `(observedSession,
+ publishedGeneration, region)`. It marks every admission entry up to
+ and including `publishedGeneration` as covered, and queues a
+ `park-generation` chore (op `session:<n>`) for every predecessor
+ generation in that chain other than `publishedGeneration`, without
+ duplicates. A writer that dies after its marker landed but before this
+ CAS leaves entries uncovered. The next admission's `PublishGeneration`
+ covers them. This replaces `QueueGenerationRetire`.
+5. **A clean rollback** returns the source to its own generation **only
+ when the seal records `src_covered`**: the source's own replica
+ reached the stopped database's position, with no write pending and the
+ session's start complete. Otherwise the return carries the seal as a
+ prepared generation.
+6. **`BaselineCoversPredecessor`** may be passed only for a seal built
+ from the stopped database (`from_db`). A seal built from the remote,
+ because the disk was gone, stops at the remote's position, and the
+ writes beyond it are declared in `writes_lost`.
+7. **A new agent process stops any app it finds running** for a host,
+ because that app's session ended with the old agent. It then admits a
+ new session before restarting the app. It never reattaches to a unit
+ started under a dead session.
+8. **A declared-lost box's timers** are declared on the console's record,
+ and alerted. A rollback whose target is lost, with `src_covered`
+ false, records a second `writes_lost` for the source's cut session.
+ **Adoption** sets `holder.writer_box` to the box running the
+ pre-release process. Before the first writer of a new incarnation,
+ `writer_box` is `""`.
+
#### Readings settled with the moves spec (rev 7.10)
These are the rulings on the moves spec's rev 7.10 readings: