One state in the claim table can strand an event: claimed. If the run dies after the claim row is written but before the AI step finishes, say a timeout on the model call or a scenario error, every retry of that event hits Path A and stops, because the row still says claimed. The duplicate gate then turns a crash into a lost dispute, and nothing fails visibly. A lease handles it. Treat a claimed row as live only while claimed_at is younger than the longest a run can reasonably take, and let a retry take over a stale claim by updating it. The failed status has the same weakness, since writing it needs the run to survive long enough to write it. A small scheduled step that lists claims older than the lease gives a human a short list to check.
Hayrullah Kar