shutil.move() can partially create palace_path before raising, which would
trip a bare os.replace(stale_path, palace_path) rollback (dest exists).
- Switch the primary swap to os.replace so same-filesystem moves stay atomic
- Branch on errno.EXDEV before falling back to shutil.move, so real errors
(permissions, EIO) surface instead of silently attempting a slow copy
- Extract rollback into _restore_stale_palace which clears any partial
destination and, if the restore itself fails, logs both stale_path and
palace_path so the operator can recover by hand
Adds three regression tests covering clean rollback, partial-copy cleanup,
and logged failure on rollback-failure.
Flagged by the Qodo reviewer on #935.