carlos / platform Public

index: plan 2 rulings P2-7/8/9/13/14/15 folded into plan 3's execution

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 007d5ed41c551ead62b4f3357ea895bb678b2cbe parent 91c3ada
1 file changed, +51 −0
  • docs/superpowers/plans/2026-10-07-zero-downtime-deploys-0-index.md +51 −0

CI passed — run details

diff --git a/docs/superpowers/plans/2026-10-07-zero-downtime-deploys-0-index.md b/docs/superpowers/plans/2026-10-07-zero-downtime-deploys-0-index.md
index 9a45a0700..d6304d494 100644
--- a/docs/superpowers/plans/2026-10-07-zero-downtime-deploys-0-index.md
+++ b/docs/superpowers/plans/2026-10-07-zero-downtime-deploys-0-index.md
@@ -699,3 +699,54 @@ many line numbers in plans 1, 3 and 5; find each use by its quoted name.
because its build could not be published reaches members through
`memberSafeWakeReason`'s passthrough, "wake failed: " plus the redacted
error, like every other internal wake error.
+
+## Plan 2 rulings folded into plan 3's execution (2026-10-08)
+
+Plan 2's controller made rulings that change plan 3 (and in places plan 5).
+Plan 3's execution (branch `zdd-3-swap`, cut from `zdd-2-containment`
+05ee71f5) folds them in as follows. Each is a ruling in plan 3's ledger.
+
+- **P2-7: `spawnInCgroupAt` returns three results**,
+ `(*exec.Cmd, func(), error)`; the extra `func()` is a settle func every
+ spawn site calls after `Wait`. The plan 2 ledger row above (two results)
+ is stale. Plan 3 Task 1's `spawnInCgroupAtTier` is the same body with a
+ tier parameter and the same three results, and keeps plan 2's strict-host
+ gate and its `RemoveChild` on a failed spawn.
+- **P2-8: placed spawns honour the strict-host gate.** A strict host (or a
+ host whose group a move owns) cannot wake under `GenContainment` until a
+ claim path exists. Plan 3's `verdictOf` reads `ErrStrictRequired`,
+ `ErrStrictGroupInUse` and `ErrStrictCleanupPending` as NoOwnership, so a
+ swap refused there is abandoned, never recorded as a failed build.
+- **P2-9: every claims-on launch is closed on this base.** `spawnClaimedGen`
+ (plan 2 Task 12) and main's `RoleLaunch.Start` (a4cd3003) both answer
+ `ErrClaimIsolationUnavailable`; `Start` never calls its `before` hook.
+ Main's claims-on parent is assembled and journaled by the host
+ (`ClaimRoleAssembly`), not by the activator entry. Plan 3 Task 10 cannot
+ be built as written, and adapting it to `RoleLaunch` needs protocol
+ changes (reservations are keyed to the role `main`). Plan 3 builds the
+ launch-independent parts plan 5 compiles against (`StartPolicy.Gen`,
+ `Fallback`, `HealthBy`, `Gate`, `PinCheck`, `ClaimStart.Gen`,
+ `ClaimRuntime.Generations`, `actEntry.pinFailed`, `pinFailReason`,
+ `claimAdmission` after the launch, `claimProcess.Retire`), and refuses
+ every claims-on swap explicitly (abandoned, before any raise or stop).
+ **Owed** to the plan that opens the isolated launch: the claimed
+ successor spawn, the entry's strict parent and its life (`entryParent`,
+ `closeStrictParent` = `Prepared.Close` with `unclosedParents`, the P5 #2
+ invariant), and the Fallback re-Prepare. Until then claims-on boxes get
+ no zero-downtime swaps; plan 5's claimed planned wakes refuse at the
+ launch, as every claims-on wake does today.
+- **P2-13: a failed generation start whose kill can't be proven keeps the
+ lease** (plan 2's parked Astra L1, High). Plan 3 Task 2 owns it: a failed
+ `StartGen` returns its `Gen{N}` instead of `Gen{}`; the wake's nil-proc
+ arm retains the lease through `unprovenWakes` whenever the error wraps
+ `errGenUnproven` or `instancectl.ErrGenUnproven`, whatever the flag; the
+ reaper proves a nil-proc wake through `KillGen`, never by default; a
+ member with no proc is never assumed proven. Test:
+ `TestSwapWitnessUnprovenWakeKeepsTheLease`, also the killer of a ninth
+ mutant (`swapsim:M9`).
+- **P2-14 (noted, not plan 3's):** an exe-layout-only leftover is not
+ recovered by `/sweep`.
+- **P2-15 (noted, not plan 3's):** flag-off dormancy is not literally
+ byte-identical (plan 2's accepted exceptions). Plan 3 adds one more:
+ `startSidecar` asks `ownedLocked` whatever the flag, so a host that lost
+ its lease, or a box shutting down, gets no legacy sidecar co-spawn.