44ff35aeb3
publishCaptures iterated every session the worker had, with no reference to whether it still owned the lease. Run 10's task was blocked and unleased for twenty-six minutes while this called the coordinator every five seconds and logged "409 Conflict: lease not owned" each time. The cost was not only the traffic. The single last_error slot stayed pinned to that dead task, so run 11's own expiry reason was never visible, which is F18 turning a small leak into a blind spot. A capture is lease-scoped. holdsLease names that invariant so the guard is testable, rather than inline where a stub backend makes the test vacuous. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVbaKucEYBjMqVeUgJUsc1