* fix(runtime): bound concurrent pre-cancel snapshot Finds during drain
Unbounded Task.WhenAll of per-cycle Finds self-contends under large
live-cycle N: more 250ms timeouts, more drainInduced excludes, more
Interrupted misses. Cap snapshot Finds at 16. The 250ms budget still
starts only after a slot is acquired so queued Finds are not fail-open
excluded by waiting.
Phase C stays sequential. No store-contract change.
Closes#8083
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* fix(runtime): exclude null pre-cancel snapshots from drainInduced
A successful Find that returns no row is unknown pre-state, not a
confirmed non-Cancelled snapshot. Joining drainInduced let Phase C
rewrite a later Finished/Cancelled as Interrupted. Timeout/error
already excluded; null now does too.
Closes nothing extra; keeps #8083 fail-open exclude.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* fix(runtime): promote null snapshot after Phase A force-cancel
A successful pre-cancel Find that returns no row is not a persisted user-cancel, but excluding it from drainInduced skipped Interrupted persist after deadline-breach force-cancel of a live cycle (DeadlineBreachPersistsInterrupted). Join drainInduced only after we ourselves cancel that handle. Timeout/error and confirmed Cancelled snapshots stay excluded.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* fix(runtime): promote null snapshot only when TryCancel transitions
Cancel() is a no-op on an already-disposed handle, so treating every Cancel() call as drain-induced could rewrite a Finished/Cancelled row the runner committed while snapshot was in flight. TryCancel reports a real transition; only those ids join drainInduced after a null Find.
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>