"Whatever the claim touched, the reclaim must untouch — all of it, atomically."
The Heartbeat Stops
A worker dies mid-transcription: power loss, a crash, someone restarting the machine. The heartbeats stop. The lease runs out. Now the control plane has to clean up, and this is where a subtle, brutal bug lives.
The obvious cleanup is: expired lease → set the job back to queued so another worker can claim it. Recall does exactly that, and it does it before any new claim is granted, so a stale lease can never be double-claimed. But 'set the job back to queued' is only half the story, and the missing half is what bites.
The Claim Touched Two Things, So the Reclaim Must Too
Remember what claiming did: it moved the job from queued to leased, and it moved that job's batch item from queued to transcribing. Two rows changed. So if the reclaim only resets the job, the batch item is left saying 'transcribing' forever — with nobody transcribing it. The queue is technically correct (the job is back, another worker takes it) while the batch's progress view is permanently lying: an item eternally in-progress, an ETA computed from a fiction, an operator staring at a batch that looks alive and isn't.
So Recall's reclaim returns both the job and its batch item to queued, atomically — one transaction, both rows, all-or-nothing. That word matters: a reclaim that resets one row and crashes before the other would recreate the exact orphan it was cleaning up. The general rule is symmetry: whatever state a claim mutates, the reclaim must restore, in a single atomic step. A partial reclaim isn't a smaller fix — it's a new inconsistency wearing the costume of a cleanup.
And Heal What Crashed Between the Cracks
Even with atomic reclaim, one gap remains: a crash landing in the narrow window between 'job completed' and 'batch item updated.' The job is genuinely done, but its item still reads transcribing — and no lease will expire to fix it, because the job isn't leased anymore. So Recall adds a second safety net: on startup and on job claim, it reconciles — it looks for completed jobs whose batch items were left mid-flight and repairs them. This is the reconciliation-loop instinct: rather than trusting that every transition was perfectly paired, periodically compare reality to what the records claim and heal the difference. Leases handle the crashes you expect; reconciliation handles the crash windows you didn't.