Merge & clean up is a minute of destructive work behind one click, and
nothing recorded that it was running: /api/task/complete took a second
request as readily as the first.
state.py grows COMPLETING — claimed before the first step, released in a
finally after the last one, on success, conflict and crash alike. The
steps are already narrated as board events against the file, so
record_board_event folds the latest summary into the claim rather than
asking complete_task to report twice. It is memory, not disk: a board
killed mid-completion leaves no card stuck busy.
/api/state carries the registry and every change publishes it, so the
board renders the busy card from the server's truth rather than from
what one tab happened to click.