1/6

Every indexer step is two writes — the effect on the store, and the cursor commit. A crash can land between them, and their order decides which failure mode you get. There is no third option short of a transaction spanning both.

Cursor-first gives at-most-once. The checkpoint says seq=3 is done, the balance never moved, no restart re-reads it. The run finishes with total=120 against an expected 150 and reports no error at all.

Effect-first gives at-least-once. The effect landed, the checkpoint did not, so the restart replays seq=3 and reaches 180. Wrong — but wrong in a direction a dedupe key can fix.