carlos / platform Public

spec: host lifecycle claim rev 6.3, the installation stamp's lifecycle (R5-4)

holder.stamp written by every installing CAS (create, adoption, flip,
reinstall, dirty rollback, push commit); local records initialized only
from a fresh claim read naming this box; no record means refuse;
retire-artifacts(S) distinct from retire-installation. Joint R5 copied
unedited.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 8faa89a49d71447eb8ac0530ba3d4367c0fe1a72 parent 30d572c
2 files changed, +205 −11
  • docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md +53 −11
  • docs/superpowers/specs/CODEX-FINDINGS-JOINT-R5.md +152 −0

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 fdb16e669..852b43783 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 6.2**. A small primitive cited by:
+Design, 2026-10-03, **rev 6.3**. A small primitive cited by:
- **#199**, deleting an instance and parking its data:
`2026-10-02-replica-ownership-design.md`, which this spec supersedes
@@ -17,7 +17,10 @@ I-7, adopts its replacement for D4, and answers N1, N3 to N10, N12 and the
carried-forward R3-12. The moves-only findings (N2's move side, N11, N13,
N14, N15) are the moves spec's. §12 maps every finding to its section.
-**Rev 6.2** answers the claim side of joint round 4
+**Rev 6.3** answers R5-4 from joint round 5 (`CODEX-FINDINGS-JOINT-R5.md`):
+the installation stamp's lifecycle.
+
+**Rev 6.2** answered the claim side of joint round 4
(`CODEX-FINDINGS-JOINT-R4.md`): R4-2, the claim half of R4-3, R4-4, and
Q2.
@@ -82,7 +85,8 @@ replaced whole with conditional writes (`If-Match` on the ETag read).
"account": "bab", "app": "jam", "name": "",
"incarnation": "<hex>", "created_at": "<record CreatedAt>",
"location": "instances/shop.bab.oncarlos.com/<incarnation>",
- "generation": "<op id of the installed generation, or \"\">"
+ "generation": "<op id of the installed generation, or \"\">",
+ "stamp": 41
},
"op": {
"kind": "serving",
@@ -126,6 +130,19 @@ Field rules:
set and never changes while that holder holds the host. Same-incarnation
generations within it (moves, push) are the moves spec's, scoped by
operation id.
+- **`holder.stamp`** is the current installation's stamp (§6.4, R5-4):
+ the claim `gen` produced by the CAS that made that installation
+ current. **That same CAS writes it**, so it is persisted atomically with
+ the transition, and the claim is always where a box recovers it. These
+ CASes are:
+ - create step 4 (`creating → serving`);
+ - adoption;
+ - a move's flip;
+ - a reinstall, a dirty rollback's install of a new generation, and a
+ push's commit.
+
+ Each writes `holder.stamp = its own resulting gen`. A transition that
+ doesn't change the installation leaves `holder.stamp` alone.
- **`holder.generation`** names the installed generation within
`holder.location` (CC18). The moves spec owns its values and its
markers. Its start check compares this field with all three of its
@@ -706,12 +723,13 @@ harmless.
**Installation stamps (R3-3, R4-2).** Local fencing is scoped to an
installation, not to the whole incarnation.
-- **The stamp.** An installation's stamp is the claim `gen` **captured
- at the CAS that made that installation current** on this box: a
- create's step 4, or a landing or reinstall made current by its
- operation. It is a captured revision, never "the current revision".
- The stamp is kept for as long as the installation exists, serving
- included.
+- **The stamp.** An installation's stamp is the claim `gen` **produced by
+ the CAS that made that installation current**. That CAS also wrote it
+ into `holder.stamp` (§2). It is a captured revision, never "the
+ current revision". The stamp is kept for as long as the installation
+ exists, serving included. Every transition that installs a new
+ generation issues a new stamp. That includes a dirty rollback, which
+ never keeps its predecessor's stamp.
- **The writer.** Every host-state writer carries
`{incarnation, stamp}` for the installation it acts for. It takes them
from its fresh read under the guard (§6.4).
@@ -723,8 +741,31 @@ installation, not to the whole incarnation.
- a stamp lower than `active_stamp`;
- a stamp in `retired_stamps`;
- any stamp while `active_stamp` is `none`.
-- **Retirement** (§6.3), under the guard, moves `active_stamp` into
- `retired_stamps` and sets it to `none`.
+- **Initialization (R5-4).** A box creates or refreshes its local record
+ only from a fresh claim read under the guard, and only when the claim
+ names this box as `op.exec` (or as the landing participant, per the
+ moves spec's phase table). It sets `active_stamp = holder.stamp`. That
+ covers:
+ - a create's first wake;
+ - adoption, on the box serving the legacy host, after the adoption CAS;
+ - a box whose local record was lost, on restart.
+
+ In every case the claim is the recovery source.
+- **No local record:** refuse. A writer for a host with no local stamp
+ record is never admitted until initialization has run.
+- **Two different retirements (R5-4).** Local artifacts are tagged in
+ the inventory (§6.3) with the stamp of the installation that produced
+ them.
+ - **`retire-artifacts(stamp S)`** parks only the artifacts tagged `S`
+ and adds `S` to `retired_stamps`. It never touches `active_stamp`.
+ A landing that has activated its own stamp uses this to park its
+ predecessor's leftovers.
+ - **`retire-installation`** (§6.3, local park at delete or a move away)
+ moves `active_stamp` into `retired_stamps`, sets it to `none`, and
+ parks every artifact.
+
+ A helper must name which of the two it is. Nothing calls
+ `retire-installation` to clean up a predecessor.
- **A new installation** of the same incarnation, such as a move back to
a region the instance left, sets `active_stamp` to its own captured
stamp. It does this under the guard, conditional on a fresh claim read
@@ -981,6 +1022,7 @@ the model catches it.
| J4-R4-3 | §6.2a, the region-qualified live set |
| J4-R4-4 | §5.3 step 4 |
| J4-Q2 | §5.1 step 5 |
+| J5-R5-4 | §2 `holder.stamp`, §6.4 initialization, refusal with no record, the two retirements |
## 13. S3 behaviour this relies on, verified
diff --git a/docs/superpowers/specs/CODEX-FINDINGS-JOINT-R5.md b/docs/superpowers/specs/CODEX-FINDINGS-JOINT-R5.md
new file mode 100644
index 000000000..f0a43fcbd
--- /dev/null
+++ b/docs/superpowers/specs/CODEX-FINDINGS-JOINT-R5.md
@@ -0,0 +1,152 @@
+**A, B and C are not yet ready as the joint Phase 1 planning baseline.** The main remaining blocker is the integration with pinned Litestream: replication restart, checksum availability and snapshot retention differ materially from the model.
+
+I read AGENTS.md first. Reviewed A at `30d572c4` and B/C at clean HEAD `cdc98845`, including the prior findings and change notes. Two GPT-6 subreviews supported this review; the repository-requested Opus model was unavailable.
+
+Both requested tests failed before compilation:
+
+```text
+go test ./internal/sim/hostlife/ -count=1
+go test ./internal/sim/hostlife/ -run Witness -count=1 -v
+
+go: creating work dir: mkdir /home/paulca/.cache/tmp/go-build…: read-only file system
+```
+
+These are **static findings**, not reproduced failing seeds. Shell syntax checking passed for `mutate.sh`. Source inspection confirms **75 rules, 30 witnesses, 102 baseline/subset/full-set runs and 15 expected misses**. Published sweep results remain unverified here. No files changed.
+
+The round-4 dispositions are:
+
+| Round-4 finding or point | Spec | Model | Why |
+|---|---|---|---|
+| **R4-1: compacted continuation** | **Partly** | **Partly** | Overlap selection and explicit snapshot identity fix the reported algorithm defect; real replication restart, checksums and retention remain incompatible. |
+| **R4-2: replacement retirement fence** | **Partly** | **Partly** | Equality and captured revisions remove the off-by-one and opaque-ID ordering problems; stamp initialization and replacement are not fully specified or faithfully encoded. |
+| **R4-3: wrong-region live-set exemption** | **Resolved** | **Resolved** | Region qualifies protection for data and markers; the late remote PUT has a targeted witness. |
+| **R4-4: purge cannot enter retirement** | **Resolved** | **Resolved** | A §5.3 explicitly permits purge-owned retirement; C records the version, deletes conditionally and requires teardown before parking. |
+| **Full histories conceal restore defects** | **Resolved within the stated abstraction** | **Resolved within the stated abstraction** | Restoration consumes page images and ranges; transaction history is oracle-only. This does not establish library integration. |
+| **Witness-specific failures and subset evidence** | **Resolved** | **Resolved** | The gate requires every proper subset to hold and the full set’s first violation to match its named failure. |
+| **Generator lacks targeted schedules and successful outcomes** | **Partly** | **Partly** | Marker holds, target freezes and successful round trips are present; the retention fixture has an off-by-one error. |
+| **Combination reporting overstates minimality** | **Resolved** | **Resolved for the declared scenarios** | The relevant minimal pairs are identified; subset checks support scenario-specific necessity, not global redundancy. |
+| **Q1 / model-only operation ordering** | **Resolved conceptually** | **Partly** | A chooses captured claim revision and active equality. C still uses a later revision for creation. |
+| **Q2: orphan with no claim** | **Resolved** | **Resolved** | Absence means legacy adoption, never orphan deletion. |
+| **Q3: ownership of pinned-version protection** | **Resolved** | **Resolved for the reported protection** | A owns the regional sweep guarantee; B supplies generation-specific versions. The current generation’s versions are preserved in the authoritative bucket. |
+
+The new findings follow. I have not reopened M1–M18 or the explicitly deferred §14.2.6 items.
+
+**R5-1 — P1: restoring the sealed snapshot does not establish the replication position assumed by the model.**
+
+B §5.1, §7.6; [protocol_test.go:245](/home/paulca/amadan.net/carlos/platform-moves-design/internal/sim/hostlife/protocol_test.go:245).
+
+`e08c5fd0` sets both `db.TX` and `db.Rep` to the restored TXID. That fixes the abstract model’s malformed subsequent delta, but its explanation—Litestream’s `-txid` sidecar—is incorrect for ordinary replication.
+
+Pinned Litestream writes that sidecar for **follow mode**. Normal replication derives its position from local or remote **L0 files**; its initialization returns without establishing a position when remote L0 is absent. B deliberately installs only an L9 snapshot. [Pinned restore implementation](https://raw.githubusercontent.com/benbjohnson/litestream/v0.5.14/replica.go), [pinned database initialization](https://raw.githubusercontent.com/benbjohnson/litestream/v0.5.14/db.go).
+
+Concrete failure:
+
+1. Install and restore the sealed snapshot ending at N.
+2. Start replication with rebuilt local metadata and no remote L0.
+3. Replication starts its numbering at 1.
+4. Newly acknowledged writes are uploaded with TXIDs below N.
+5. A subsequent cold restore, rooted at N, skips those files and loses the new writes.
+
+**Fix:** specify a durable restore-to-replication initialization procedure supported by the pinned library. Test snapshot-only install → write → successful replication → loss of local DB and metadata → cold restore. Setting the model’s counters is necessary but does not implement that procedure.
+
+**R5-2 — P2: the required post-apply checksums are absent from ordinary pinned Litestream files.**
+
+[B §5.1 steps 1–5](/home/paulca/amadan.net/carlos/platform-moves-design/docs/superpowers/specs/2026-10-02-move-any-app-design.md:542); [ltx_test.go:164](/home/paulca/amadan.net/carlos/platform-moves-design/internal/sim/hostlife/ltx_test.go:164).
+
+The pinned L0 writer, snapshot writer and compactor set `HeaderFlagNoChecksum`. LTX v0.5.1 requires `PostApplyChecksum == 0` with that flag. The model supplies a whole-state checksum for every file. See pinned `db.go:1948`, `db.go:2412`, `compactor.go:165` and `ltx.go:356`.
+
+A builder following B’s final database-checksum comparison literally will reject healthy continuations. Skipping the comparison silently removes a guarantee that the specification and model currently claim.
+
+**Fix:** either provide end-state checksums through explicitly changed writers and compaction, or define verification using guarantees the pinned format actually supplies. A file CRC is not a whole-database post-apply checksum. Add a test using real pinned-library output.
+
+**R5-3 — P2: permanently rooting restoration at the installation snapshot conflicts with normal retention.**
+
+B §5.1 step 4; [ltx_test.go:265](/home/paulca/amadan.net/carlos/platform-moves-design/internal/sim/hostlife/ltx_test.go:265).
+
+The model excludes later L9 snapshots and models only L0→L1 compaction. Real Litestream creates newer snapshots and expires older lower-level ranges through snapshot retention. [Pinned retention implementation](https://raw.githubusercontent.com/benbjohnson/litestream/v0.5.14/store.go).
+
+After sufficiently many newer snapshots, the current listing can contain:
+
+- the original pinned snapshot N, still retrievable by version;
+- newer complete snapshots;
+- continuation files beginning beyond N+1, because earlier ranges were legitimately retired.
+
+C ignores the newer snapshots and refuses the resulting gap. Ordinary Litestream restoration can use a newer snapshot. Protecting the original snapshot version alone does not preserve its continuation.
+
+B’s “every level” wording needs clarification: its stated reuse of `CalcRestorePlan`, and C’s implementation, exclude subsequent L9 snapshots.
+
+**Fix:** either retain a complete continuation from the pinned root, or define verified successor snapshots and safe advancement of that root. Model snapshot rotation and retention, then test cold restoration afterward.
+
+**R5-4 — P2: installation stamps lack a complete durable initialization and replacement contract.**
+
+A §6.4; B §§6.4, 7.6, 7.8; [background_test.go:198](/home/paulca/amadan.net/carlos/platform-moves-design/internal/sim/hostlife/background_test.go:198).
+
+The equality predicate is now sound. Its lifecycle is incomplete:
+
+- Creation must capture its serving-CAS revision, but C initializes the stamp later from `c.Ver` during reconciliation. Intervening claim writes change that value.
+- Landing explicitly persists `FlipGen`; creation has no equivalent specified recovery source.
+- Dirty rollback installs a new generation but retains the source’s old stamp.
+- B activates the new stamp during `checking`, then later local-parks old artifacts. A’s general local-retirement rule clears the active stamp. Reusing that helper literally can retire the new installation and refuse its probe.
+
+C also [admits a writer when no stamp record exists](/home/paulca/amadan.net/carlos/platform-moves-design/internal/sim/hostlife/world_test.go:403), whereas A requires equality with an active installation.
+
+**Fix:** persist each authorizing revision atomically with its claim transition; specify creation, adoption and dirty-reinstall initialization. Distinguish retiring predecessor artifacts from retiring the active installation. Encode those rules and crash boundaries in C.
+
+**R5-5 — P2: readiness still budgets a small incremental mirror after switching to a full final snapshot.**
+
+[B §7.3 T11](/home/paulca/amadan.net/carlos/platform-moves-design/docs/superpowers/specs/2026-10-02-move-any-app-design.md:1136), versus §5.1 step 1.
+
+T11 prices the final cross-region transfer as at most **16 MiB**. Rev 7.5 instead creates and transfers a complete snapshot after stopping the source.
+
+For example, a 2 GiB database over a 10 MiB/s transfer path requires roughly 205 seconds for that transfer alone. The existing formula can still admit it into a 120-second window by pricing only the small delta. Deadline enforcement then rolls back a predictably impossible move.
+
+**Fix:** budget snapshot construction and its full cross-region transfer, or explicitly construct the sealed snapshot on the target from previously staged material. Update the cut phases and budget test together. This is a new workload mismatch, separate from the deferred simulation timing scale.
+
+**R5-6 — P3: the retention-boundary fixture has not crossed the boundary it claims.**
+
+[sim_test.go:55](/home/paulca/amadan.net/carlos/platform-moves-design/internal/sim/hostlife/sim_test.go:55).
+
+`retentionStart` fills `Retired` with incarnations 1–32, then injects residue for `old := 1`. Incrementing `nextInc` does not remove 1 from the list.
+
+**Fix:** retire incarnation 33 first, or populate 2–33, and assert that the injected incarnation is absent. The deterministic 33-recreate witness remains valid; this finding concerns the new random fixture and its coverage claim.
+
+On the requested fidelity questions:
+
+- **Planner and page abstraction:** the overlap predicate and preference order match the pinned planner. Final page images, updates and deletes address R4’s historical-information problem. Overall fidelity remains partial because of R5-1 through R5-3.
+- **Oracle:** replaying acknowledged transactions into expected state is sound for this KV abstraction. Restoration does not consult the oracle’s transaction lists; those lists establish durability separately. The lineage assumption requires the real initialization contract in R5-1. The already-deferred release-time omissions remain limitations, not new findings here.
+- **`live-set-region`:** genuinely forces the old remote PUT to complete after adoption discovery finishes.
+- **`restore-gap-closed`:** genuinely forces refusal of snapshot 11 plus file 13 with file 12 missing. It is a deliberately malformed-replica test with an explicit refusal assertion, not evidence that this sequence arises through the normal sequential uploader.
+- **`fence-stamp`:** the witness establishes scenario-specific protection. Either the stamp or the fresh bundle check stops its stale config write; removing both produces the named failure. Equal sweep counts with `hostguard` alone add no independent evidence. An unchanged-bundle round trip would test the stamp without that particular redundant rejection.
+- **Generator changes:** marker holding and targeted freezing are legitimate scheduling changes; they do not weaken the invariant checks. R5-6 limits the retention-fixture claim.
+- **Physical format:** B/C’s `/ltx/<level>/` paths are filesystem-style. The pinned S3 client uses `<prefix>/<level-as-four-hex-digits>/<filename>`. A’s `0000/…0009/` description is correct. The adapter must explicitly reconcile this difference.
+- **Validation claim:** §14.2.6 points to §15 step 8 for real LTX validation, but that section records AWS object-operation checks, not the required restore/replicate/retention tests.
+
+The claim-owner questions are answered by A: **Q1** chooses captured revisions, subject to R5-4’s durable initialization; **Q2** requires legacy adoption, not deletion; **Q3** assigns sweep protection to A and generation-specific version selection to B.
+
+| Artifact | Ready for Phase 1 implementation planning? | Reason |
+|---|---|---|
+| **A — claim rev 6.2** | **No, as the joint contract** | Finish durable stamp initialization and replacement ordering. R4’s regional sweep and purge-transition defects are closed. |
+| **B — moves rev 7.5** | **No** | Define real replication initialization, checksum verification, retention-compatible restoration and the full-snapshot cut budget. |
+| **C — model at `cdc98845`** | **No, as the planning gate** | Stronger oracle and witness evidence, but key production behaviors are assumed or omitted; stamps are not encoded exactly. |
+
+Build the claim primitive first after resolving its stamp contract. The remaining changes do not require reopening the product rulings.
+
+---
+
+**FIRST PROMPT:**
+Joint independent round-5, read-only review of two CARLOS specs and their executable model.
+
+**WHAT:**
+Assess prior fixes, model fidelity, new defects and Phase 1 planning readiness.
+
+**STATUS:**
+Review complete: one P1, four P2 and one P3. Go execution was sandbox-blocked.
+
+**NEEDED:**
+Nothing for this review.
+
+**RECOMMENDED:**
+Resolve the pinned-library contracts and stamp lifecycle, align C, then run real-library integration tests and the model gate.
+
+**SESSION:**
+Safe to close. No files changed; nothing remains running.
\ No newline at end of file