| 1 | ACCEPT WITH FIXES |
| 2 | |
| 3 | For **dormant merge only**: I found no new flag-off runtime defect. Before merging, obtain the complete repository gate on `55de3e4a` and record the remaining defects as enablement blockers. The supplied [wave-2 results](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/.superpowers/sdd/2026-10-07-zero-downtime-deploys-5-scheduler/final-w2-b2-report.md:225) cover selected checks at `1cc74fe5`, not that complete final-tip gate. |
| 4 | |
| 5 | Reviewed `6ae15fdb..55de3e4a`. No files or git state changed; no tests or simulations run. |
| 6 | |
| 7 | **2. R2 items** |
| 8 | |
| 9 | | Item | Status | Evidence | |
| 10 | |---|---|---| |
| 11 | | F1 — staged-instance launch gates | **ADDRESSED** | The hook reaches cgroup preparation’s far side and each launch retry: [containment.go:129](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/containment.go:129), [cgroup.go:354](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/cgroup/cgroup.go:354), [cgroup.go:367](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/cgroup/cgroup.go:367). The production-backend regressions cover preparation and retry supersession at [exec_gate_test.go:419](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/exec_gate_test.go:419). The separately parked **worker** boundary remains an enablement blocker. | |
| 12 | | N1 — outcome fence fails open | **ADDRESSED** | Timeout and cancellation return refusal while retaining the fence: [wakeplan.go:590](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/wakeplan.go:590). `doWake` returns before planning at [activator.go:1713](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/activator.go:1713); the claims path does likewise at [claimwake.go:196](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/claimwake.go:196). | |
| 13 | | N2 — later fallback after executed hold abandonment | **PARTIAL** | Scheduler outcomes now set a marker before releasing admission, and cancelled hold wakes report execution: [scheduler.go:212](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/scheduler.go:212), [wakeplan.go:419](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/wakeplan.go:419). Planned wakes enforce it, but scheduled worker fallback bypasses it, stale publication can erase it, and its admission exception contradicts the failure hold. See N5–N7. | |
| 14 | | N3 — stale config-token check | **ADDRESSED** | Token validation and `activate` now share `m.mu`; acknowledgement I/O remains outside: [wakeplan.go:436](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/wakeplan.go:436), [manager.go:1031](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/manager.go:1031). The delayed-old-event regression is at [config_race_test.go:18](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/config_race_test.go:18). | |
| 15 | | N4 — unknown execution treated as unused retry | **ADDRESSED** | Cancelled replacements join their respawn, reporting unknown on timeout: [workerswap.go:104](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/workerswap.go:104), [workerswap.go:335](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/workerswap.go:335). Nested post-start errors carry uncertainty at [backend_exec.go:1702](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/backend_exec.go:1702); overlap and hold propagate it. Failure classification remains separately parked. | |
| 16 | | F8 — retry re-arming, through N4 | **ADDRESSED** | Re-arming requires abandonment **and proof of no execution** at [scheduler.go:224](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/scheduler.go:224), with build-scoped restoration at [queue.go:455](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/queue.go:455). The older retry-generation/interleaving obligations remain separate. | |
| 17 | |
| 18 | **3. New findings in wave 2** |
| 19 | |
| 20 | All three below are **flag-on, enablement-blocking (b)**. None requires a code fix before a strictly dormant merge. |
| 21 | |
| 22 | **N5 — High: the hold-ran restriction does not cover scheduled worker fallback.** |
| 23 | |
| 24 | The new restriction is installed at [scheduler.go:213](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/scheduler.go:213), but only wake planning consumes it. |
| 25 | |
| 26 | Failing sequence: |
| 27 | |
| 28 | 1. Worker H has good A. Hold B executes. |
| 29 | 2. C supersedes B during its settle. B remains running, but returns abandoned without becoming good: [workerswap.go:173](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/workerswap.go:173). The scheduler records B’s hold-ran marker. |
| 30 | 3. The next scheduled replacement adopts overlap C. [worker.go:24](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/worker.go:24) supplies good A as fallback without consulting that marker. |
| 31 | 4. C fails; [workerswap.go:234](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/workerswap.go:234) executes A against the database B may have migrated. |
| 32 | |
| 33 | **Smallest fix:** apply the host recovery restriction to scheduled replacement/fallback selection and its execution gate; suppress A until a later build passes or explicit recovery authorizes it. |
| 34 | |
| 35 | **N6 — High: an older good-build publication can erase a newer hold-ran marker.** |
| 36 | |
| 37 | [manager.go:999](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/manager.go:999) clears whatever marker currently exists. [failures.go:234](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/failures.go:234) checks neither generation nor marker identity. |
| 38 | |
| 39 | Failing sequence: |
| 40 | |
| 41 | 1. A’s settled event passes `acknowledged` in [manager.go:898](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/manager.go:898), then pauses before `goodRecorded`. |
| 42 | 2. A is already visible to scheduler admission—the observer clears `firstWatch` before delivering `GenSettled`: [wakeplan.go:755](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/wakeplan.go:755). |
| 43 | 3. Hold B executes and is superseded; `done` records B’s marker. That path does not acquire `goodMu`. |
| 44 | 4. A’s older publication resumes and deletes B’s marker. A subsequent wake can again select good A. |
| 45 | |
| 46 | **Smallest fix:** order marker creation and successful-generation clearing with a per-host execution epoch or equivalent conditional transition. An earlier acknowledged generation must not clear a restriction established by a later execution. |
| 47 | |
| 48 | **N7 — High: a marker becomes permission to bypass an existing cohort failure.** |
| 49 | |
| 50 | [decideHoldRan:132](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/wakeplan.go:132) skips `Blocks` for the marked build; [planCheck:312](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/wakeplan.go:312) repeats that exemption at execution. |
| 51 | |
| 52 | Failing sequence: H executes hold B without passing; a sibling fails B and supersedes H; H receives the marker. An ordinary subsequent wake executes B again despite the standing failure record and without retry authorization. This is explicitly required by the new [regression test:65](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/holdran_seq_test.go:65). |
| 53 | |
| 54 | Binding [spec §8.4:687](/home/paulca/amadan.net/carlos/platform-design-zero-downtime-deploys/docs/superpowers/specs/2026-10-07-zero-downtime-deploys-design.md:687) exempts instances that **passed**, not instances that merely executed. The new [simulation exemption:840](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/sim_test.go:840) conceals this violation. |
| 55 | |
| 56 | **Smallest fix:** retain both restrictions. If B is blocked and A is unsafe, refuse the wake until explicit retry or an admissible newer build; do not reinterpret “cannot fall back” as “may retry a held build.” Correct the test and simulation expectation. |
| 57 | |
| 58 | **4. New controller rulings** |
| 59 | |
| 60 | References are to the new lines in [progress.md](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/.superpowers/sdd/2026-10-07-zero-downtime-deploys-5-scheduler/progress.md:199). |
| 61 | |
| 62 | | Ruling | Judgment | |
| 63 | |---|---| |
| 64 | | 199 — final-wave split and execution-evidence contract | **Agree.** The split is reasonable; false must mean proven unexecuted. | |
| 65 | | 200 — fail-closed outcome timeout | **Agree.** The request expires; the safety restriction does not. | |
| 66 | | 201 — persisted hold-ran marker | **Disagree as written.** Preserving a restriction without inventing a build failure is correct. Letting the marked build bypass a standing failure record is N7. Enforcement and clearing also need N5/N6. | |
| 67 | | 202 — atomic config activation | **Agree.** The implementation now performs the token check and activation together. | |
| 68 | | 205 — installed good build means explicit rollback | **Agree with conditions.** Permit an actual explicit rollback, but installed-build equality alone does not establish its provenance. Root also has automatic repoint-and-stamp machinery at [rollback.go:96](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/release/rollback.go:96). Before enablement, prove those paths cannot authorize recovery of a marked managed host, or require explicit recovery evidence. | |
| 69 | | 206 — park worker launch hook | **Agree with conditions: dormant only.** The hook still precedes cgroup preparation at [backend_exec.go:2137](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/activator/backend_exec.go:2137). Carry the ownership check to every actual worker start before enablement. | |
| 70 | | 206 — park declined-mode marker enforcement | **Agree with conditions: dormant only.** [rolloutdeclined.go:115](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/host/rolloutdeclined.go:115) reads failure records, not hold-ran restrictions. | |
| 71 | | 206 — park downgrade marker loss | **Agree with conditions: dormant only.** Parsing an additive field is insufficient when an older writer deletes its safety meaning. Preserve the restriction or refuse the unsafe downgrade. | |
| 72 | | 206 — park nested accepted-start failure classification | **Agree with conditions: dormant only.** Conservative execution evidence is correct; treating an accepted start that actually failed as abandonment can avoid hold-down/cohort failure and permit repeated starts. Resolve failure versus uncertain outcome before enablement. | |
| 73 | |
| 74 | **5. Consolidated obligations before enabling anywhere** |
| 75 | |
| 76 | This replaces the overlapping lists in [round 1’s Flag triage](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/docs/superpowers/plans/CODEX-FINDINGS-ZDD-IMPL-5.md:116) and [round 2’s owed items](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/docs/superpowers/plans/CODEX-FINDINGS-ZDD-IMPL-5-R2.md:68). |
| 77 | |
| 78 | 1. **Complete hold recovery protection:** N5–N7; ordered marker creation/clearing; explicit rollback provenance; correct nested post-start failure classification. Add deterministic regressions for these sequences. |
| 79 | 2. **Durable failure state, including markers:** F5’s unresolved-attempt/outcome protocol, refusal when its prerequisite write fails, startup reconciliation, crash/restart evidence, and protection against downgrade erasure. [failures.go:128](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/internal/rollout/failures.go:128) still only logs/retains failed saves in memory. |
| 80 | 3. **Declined boxes:** enforce records and markers on worker converge/recycle and every actual launch; refresh supported retry authorization after startup. Preserve the no-good bootstrap exception. |
| 81 | 4. **Execution admission:** worker ownership/cancellation checks after preparation and before every launch retry; revalidate `Managed` against the route used for dispatch; refuse uncaptured worker recycling through the mutable live link. |
| 82 | 5. **Retry ordering:** prevent delayed pre-retry failures from undoing newer authorization; establish the older non-canary/retried-canary boundary; verify unrelated attempts cannot consume the matching retry allowance. |
| 83 | 6. **Policy/store bounds:** serialize or version policy-cache fills; bound failed-read retries; cover missing-versus-error policy reads; bound synchronous policy/pointer reads and use the wake’s context for wake-time pointer work. |
| 84 | 7. **Config/publication lifecycle:** complete delivery-order, address-route, removal and real-host wiring coverage; bound/cancel acknowledgement writes; strengthen blocked serving-publication tests; verify shutdown joins attempts, observers and blocked publishers. |
| 85 | 8. **Workers and scheduler coverage:** align `WakeWorker` and fallback budgets; verify readiness, fallback events, clean one-shot success recording and admitting `CoalesceRecycle`; cover hold/no-good wakes, running-attempt refusal, config backoff/deferral, and concurrency-one/two-cohort operation. |
| 86 | 9. **Artifact protection:** include `GoodVersion` in bucket retention; publish the selected hold build before stopping its incumbent. |
| 87 | 10. **Truthful status/events:** close stale serving/awake and mid-wake completion gaps; test every observation terminal event; emit cohort halt when failure precedes scheduler registration. |
| 88 | 11. **Relay:** bound/revalidate unreadable-baseline retention and cover the moves call site. |
| 89 | 12. **Simulation evidence:** independently assert safety and liveness, including worker fallback and delayed callbacks; remove N7’s exemption; make replay reproducible; rerun the corrected high-seed/mutation checks and verify owned-scratch cleanup. |
| 90 | 13. **Containment evidence:** populated-legacy-parent refusal, generation placement/limits, termination proof and crash-surviving descendants; the carried D1 measurement, real-unit `KillSidecar`/control checks, and nondefault-path refusal at [ledger:19](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/.superpowers/sdd/2026-10-07-zero-downtime-deploys-5-scheduler/progress.md:19). |
| 91 | 14. **Plan 6:** member-safe planned-wake errors, robust reason classification, reviewed recovery/refusal wording—including hold-ran wording—and migration guidance. |
| 92 | 15. **Claims exclusion:** keep claims-backed launches closed. Opening them additionally requires isolated launch, selected config restart/delivery coverage, pre-body ownership-error classification, and complete claimed-wake execution/outcome evidence. |
| 93 | |
| 94 | The **merge-time obligation (a)** is the complete final-tip build/vet/test/gofmt/cross-build gate, including resolution or identification of the unexplained activator failure noted at [progress.md:207](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/zdd-5-scheduler/.superpowers/sdd/2026-10-07-zero-downtime-deploys-5-scheduler/progress.md:207). The runtime obligations above are **enablement blockers (b)**. |