You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sync-bak/sync-tmp: each suffix gets one consistent meaning
Conceptual fix: before this change, `.sync-bak` was ambiguous — it
meant "old bytes backed up" in atomicWriteFile's 5-step pull-replace
protocol AND "new bytes staged" in ConflictStore.create's 3-step
sibling registration. The same suffix encoding opposite semantics
made the recovery sweep harder to reason about and trapped readers
who assumed "bak" implied a backup of something pre-existing.
After:
- `.sync-tmp` = NEW bytes staged for a target.
Ambiguous between two callsites; the recovery sweep dispatches
by ownership via ConflictStore.getBySibling(finalPath):
- record exists → forward-finalize (Path B sibling registration)
- no record → drop as transient (Path A pull-replace artefact)
- `.sync-bak` = OLD bytes backed up before an overwrite.
Produced only by atomicWriteFile; ConflictStore never writes
`.sync-bak` after this change. Recovery is snapshot-based with no
ownership dispatch needed — simpler code path.
Changes:
- ConflictStore.create now stages at `<sibling>.sync-tmp.<ext>`
(was `.sync-bak.<ext>`). 3-step protocol unchanged otherwise.
- AtomicWriteRecovery.sweep moves the ownership-dispatch block
from the `.sync-bak` loop into the `.sync-tmp` loop.
`.sync-bak` handling simplifies to snapshot-based recovery only.
- File-level comments in atomic-write.ts + conflict-store.ts
updated to describe the new contract.
- atomic-write.test.ts: N9/N9b renamed (.sync-bak → .sync-tmp in
titles + stagingPathFor() arg). Existing orphan-tmp test retitled
for clarity. New N9c pins the dispatch: a Path A transient
.sync-tmp must drop even when ConflictStore is in the recovery
constructor, as long as no record names its finalPath.
- conflict-store.test.ts: 2 comments + 1 test title updated.
Migration: at rest there are no `.sync-bak` staging files for
ConflictStore-owned siblings (Step 3 promotes them immediately on
success), so existing installations migrate transparently. The only
edge case — an upgrade landing exactly during a mid-Step-3 crash
window — is benign because the conservative-restore branch in the
`.sync-bak` handler would still rename the leftover into place,
which is the same outcome the new code would produce via the
.sync-tmp branch.
Tests: 526/526 unit pass (was 525, +1 for N9c). Build clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments