fix(atlas): write the Pulse snapshot atomically - #1740
Open
elhoim wants to merge 1 commit into
Open
Conversation
Atlas.ts wrote snapshot.json with writeFileSync at both call sites (sync
and export), which truncates the target before writing. Pulse reads that
same file concurrently — PULSE/modules/atlas.ts JSON.parses it on every
GET /api/atlas — so a request landing mid-write saw a truncated file and
threw. Store.ts and AtlasSystem.md both document Pulse as the reader of
record ("one writer class, one reader artifact").
Switch both writes to atomicWriteText from PULSE/lib/atomic-write (temp
file + rename), matching how LIFEOS/TOOLS reaches that helper. Byte
output is unchanged: atomicWriteText writes the string as given, so the
snapshot stays compact JSON with no trailing newline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One commit, one fix —
2df5e0c, applies cleanly onto47df8eeon its own.LIFEOS/ATLAS/Atlas.tswrites the Pulse snapshot withwriteFileSyncat two call sites (runSyncandcase "export"). That is truncate-then-write, and there is a documented concurrent reader:PULSE/modules/atlas.ts:160doesJSON.parse(readFileSync(SNAPSHOT_PATH))on everyGET /api/atlas, andATLAS/Store.ts:5states "Pulse reads a redacted snapshot, never the live DB". A reader landing mid-write sees a truncated prefix and throws.Both sites now use the existing
atomicWriteTexthelper (temp file + rename), so a reader sees either the whole previous snapshot or the whole new one.atomicWriteText, notatomicWriteJSON— the latter reformats toJSON.stringify(data, null, 2), which would change the snapshot's bytes. This keeps the compact output identical.../PULSE/lib/atomic-writefollows the convention already used byLIFEOS/TOOLS/MergeSettings.ts:16andSettingsBackport.ts:45.writeFileSyncdropped from thenode:fsimport; it had no other use in the file.Verified by bundling:
bun build --target=bun LIFEOS/ATLAS/Atlas.tsresolves 10 modules and the helper'srenameSync(tmp, filePath)is inlined in the output.Out of scope but same class:
PULSE/modules/atlas.tswrites its ownINSIGHTS_CACHEwithwriteFileSync. Left alone here.Testing. Commands and output are in the per-file notes above. I did not do a fresh-system install verification (contributing step 3) — these are targeted fixes verified per-file, not an install run.