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>
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. |