Within the Phase 1 util.WaitFor condition, the stability check does case <-util.After(c.cfg.Clock, 1*time.Second). util.After spawns a goroutine and uses an unbuffered channel; if the ctx.Done() branch wins that select, the goroutine can block forever trying to send after the timer fires, leaking a goroutine per cancellation. Consider using an inline clock timer (c.cfg.Clock.NewTimer) and stopping/draining it on cancellation to avoid leaks and reduce per-iteration goroutine churn.
Originally posted by @Copilot in #208 (comment)