fix: make SaveIdentity atomic (temp+rename+fsync) (PILOT-248)#6
Conversation
…te) (PILOT-248) Replace os.WriteFile with fsutil.AtomicWrite to prevent truncated identity files from crashes mid-write. Previously a crash between file-open and the final write could leave a 0-byte or partial JSON file — next daemon start would fail to unmarshal and regenerate a new identity, losing the peer trust graph.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
🦞 Matthew PR Check — #6 PILOT-248Status
Summary
CommitBranch |
🦞 Matthew PR Explain — #6 PILOT-248What this changes
WhyA torn identity file causes silent load failures or key corruption on next daemon start. The temp+rename+fsync pattern is the standard POSIX-safe approach for atomic file writes. RiskSmall — ≤3 files, ≤50 LoC. Only changes the write path; read path unchanged. Temp file is in the same directory (same filesystem) for rename atomicity. |
🦾 Matthew PR Check — #6 PILOT-248Status
VerdictCLEAN — all CI green, atomic save pattern is well-scoped. Ready for operator review. |
🦜 Matthew Explains — #6 PILOT-248What this doesMakes
This prevents a crash or power loss mid-write from leaving a truncated/corrupt identity file on disk. The old code wrote directly to the target path with Why it mattersA corrupted identity file on restart means the daemon silently loses its identity — no warning, no crash, just a new keypair. This is a durability bug in a security-critical path. |
Summary
crypto/identity.go:98usedos.WriteFiledirectly, which is not atomic. A crash between file-open and final write leaves a 0-byte or partial JSON file on disk. Next daemon start fails to unmarshal and regenerates a new identity — peer trust graph is lost.os.WriteFilewithfsutil.AtomicWrite(temp + rename + fsync pattern, already in this same repo atfsutil/fsutil.go). This ensures the identity file is never left truncated.crypto/identity.go, +5/-1)matthew-fix)go build ./...✅,go vet ./...✅,go test ./...✅ (all 13 packages pass, includingcryptopackage tests)artifact: none)Diff