acb2c45e35
Follow-up to the salvaged #111044 commits: - self_removal_delivery_allowed() now also requires that no record currently holds the job id. The marker alone said "this run removed its record"; it did not say the id is still empty. A replacement record (another owner reclaiming the id) must be treated as a stolen claim, not a self-removal. - Drop the allow_self_removed kwarg on fire_claim_fence: the fence already has the job_id and the ContextVar marker, so it can decide on its own; the caller no longer threads a flag it computed from the same predicate. - _FireOwnership.lost(): keep the explicit lost event and the no-owner short circuit ahead of the self-removal check so an interrupted run is still reported as lost even after it removed its record. - _finish_completed_run: skip mark_job_run entirely for a self-removed job (nothing to mark) instead of calling it and then excusing the False. - Tests trimmed to two invariants, both A/B'd against origin/main: the self-removing run delivers after a post-removal heartbeat tick (RED on main), and a self-removal followed by a replacement record is still discarded (GREEN on main, guards the new predicate). - Docs: user-guide cron.md notes that a job may remove itself and still report.