Code review I1: wrap snapshot's backup+rename in try/catch, unlink
orphan tmp file on failure so the next run does not encounter a
confusing 'existing file is not a database' error from sqlite.
Code review I2: JSDoc note that snapshot() is not safe for concurrent
calls — callers should serialize via runDaily()'s marker.
New unit test injects a fake db whose backup() rejects after a partial
write, asserts no .tmp / .sqlite remains.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>