* fix(extensions): publish a snapshot restore atomically
_FileSnapshot.restore() rolled a failed extension install back with
Path.write_bytes, which opens with O_TRUNC: if the process died during the
rollback, pyproject.toml / uv.lock / config.yaml were left half written and the
failed install took the checkout with it. Publish through a temporary file plus
os.replace, the pattern the rest of the codebase already uses.
* fix(extensions): preserve snapshot permissions on rollback
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>