The +60s next_run_at advance only delayed a duplicate one-shot dispatch by
one tick — a job that outlives the 60s tick interval (the reported 2.5-min
research prompt) still re-fired on the next tick after the window expired,
so the concurrent gateway+desktop double-delivery persisted.
Replace it with a durable run_claim (at+by, mirroring fire_claim) stamped
on the one-shot under the same jobs lock get_due_jobs holds, and checked at
the top of the due-scan: a fresh claim held by an in-flight run makes every
other scheduler process skip the job for its ENTIRE run, not one tick.
mark_job_run() clears the claim on completion; a ONESHOT_RUN_CLAIM_TTL
(30 min) safety valve re-dispatches a claim left by a tick that died mid-run
so a one-shot is never wedged.
E2E: long-running one-shot no longer double-fires at +28/+61/+120/+179s;
completion clears the claim + disables the job; crash recovery re-arms past
the TTL. +3 regression tests.