When a config file is written atomically (tmp → rename), chokidar can
fire an 'unlink' event for the temporary removal of the destination file
before the rename completes. runReload() would then call readSnapshot(),
which returns { exists: false, valid: true, config: {} } — an empty
config that looks valid — causing diffConfigPaths() to find many changes
and triggering an unnecessary SIGUSR1 restart.
The restarted gateway process then fails to find the config file (still
in the middle of the write) and enters a crash loop with:
'Missing config. Run openclaw setup...'
Fix: guard against exists=false before the existing valid=false check,
so mid-write snapshots are silently skipped rather than treated as a
config wipe.
Fixes#23321