POST writes the keeper pack-log + idx as the FIRST store mutation (post.js:242-243), THEN advances the ref with an expected-old CAS (post.js:246 → advanceRef, post.js:112-118). When the CAS loses — a concurrent advance, exactly the race the CAS defends — advanceRef throws POSTNOFF (post.js:114-116) AFTER the pack is on disk. There is no rollback and no GC path anywhere, so each lost-CAS post leaves the just-written pack-log + idx orphaned: a permanent per-incident disk leak. Content is content-addressed, so it is a leak, not corruption. Method: Issues.
post.js:242-243: commitM.writePack(reader.shard, info.wt, …) —"the FIRST store mutation" (the comment :240 says so).
post.js:246: `advanceRef(reader, reader.shard, branchKey,expectedOld, commit.sha)` runs AFTER the pack write.
post.js:112-118 advanceRef: `if ((cur||"") !== (expectedOld||""))throw "POSTNOFF: REFS … advanced concurrently — retry"` — the lost CAS.
the NNNNNNNNNN.keeper(+.idx) just written stays on disk forever.
is written only after the ref slot is reserved, or it is unlinked on the POSTNOFF path).
POST-017 all-or-nothing intent.
writePack byte-output unchanged.writePack (re-check expected-old,then write, then commit the ref).
advanceRef in a catch that unlinks the freshly written
pack-log + idx before re-throwing POSTNOFF (record their paths from writePack).
test/js/post/*: force a lost CAS (mutate the ref between
pre-flight and advanceRef) and assert NO orphan pack-log/idx remains.
writePack must surface the exact file names it created so a catch canunlink precisely (avoid clobbering a concurrent winner's pack).
verbs/post/post.js:685
commitM.writePack(reader.shard,…) runs BEFORE :692 advanceRef(…); no catch/unlink, no GC. A lost CAS (advanceRef:222-225 POSTNOFF) leaves the pack-log+idx orphaned.