LifetimeEnded distinguishes process shutdown from an iteration's own deadline.
outside Run, explicit cancellation remains ordinary caller control flow.
Run starts immediately and repeats without waiting while an iteration finds
more work and succeeds. empty or failed iterations wait for IdleInterval.
each iteration has its own deadline; OnError decides how to report failures,
including those returned during caller cancellation.