attachment.rs (crate-private): save(store, sandbox, room_id, image) re-verifies through
chat_image::load_bytes (load keeps its signature and calls it), names the file
<sha256>.<ext> from the verified type, refuses a .git at the sandbox root or in
attachments/, and writes through rustix openat/linkat on held descriptors: temp name
.part unlinked first, 0600 in the create call, fsync, linkat (never replaces), bounded
nonblocking regular-file compare on EEXIST. cfg(windows) half returns WriteFailed.
rustix gains the fs feature; no crate added.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>