Files
xarmian 25153bcda5 fix(decision): a failure the store refuses is still counted, and an empty message is never a supersede (BUG-4022) (#2317)
* fix(decision): a failure the store refuses is still counted, and an empty message is never a supersede (BUG-4022)

FailDecisionJob's UPDATE carried the failure text. When the store refused
it, the attempt went unrecorded: attempts stayed 0, the backoff never grew,
the permanent drop never fired, and the job was re-run (a paid provider
call) every lease, forever. It now fails open: one fallback UPDATE with the
same WHERE and lease records the attempt with a fixed last_error, plus the
SQLSTATE when it has the fixed five-character shape. Both errors are
returned only if the fallback is refused too.

A failure whose cause has no text (nil, or Error() == "") was read as a
supersede, releasing the claim with no attempt and no last_error, so the
job was re-run on every tick. releaseDecisionJob is split into
releaseDecisionClaim (complete, release) and recordDecisionFailure (fail),
and an empty cause records a fixed message.

Claude-Session: https://claude.ai/code/session_01Hk4vxsaKDm3E1LvsoHtHeV

* fix(decision): the fallback counts an attempt only if the first write did not (BUG-4022 r1 H1)

Claude-Session: https://claude.ai/code/session_01Hk4vxsaKDm3E1LvsoHtHeV
2026-10-25 19:51:26 -04:00
..