Repository navigation
fix(chat): bound an immediate send's waiting copy by the PC's stamp before typing - #3165
Merged
Merged
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 16 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
Owner
Author
|
Review summary at dc5c66e (no fix round needed: no HIGH).
|
Owner
Author
|
Merge note (merge pass) at head dc5c66e:
|
devswha
added a commit
that referenced
this pull request
Nov 6, 2026
…whole-second guard (#3192) Fixes #3166. ## Problem A send the PC stamps (`sending_at`, #3165) gets a baseline whose `pcFloor` is the stamp. For a transcript with whole-second times (Grok), `newerThanSend` accepted any turn with `at + 1000 >= pcFloor`. When the stamp came before the chat's first transcript read, the baseline held no shown turns, so an older identical turn of the same second (already answered within that second) cleared the new send's waiting copy. The unstamped first-read path keeps a guard for exactly this case; the stamped path skipped it. ## Fix (`src/lib/sentWaiting.ts`) - `stampedBaseline` marks a baseline made from the stamp alone (no read behind it) with `unread: true`. - In the `pcFloor` branch, a turn at or after the floor settles at once, as before. A turn admitted only by the whole-second slack on an `unread` baseline needs the unstamped path's evidence: it is the last turn read, or a turn after it is dated in a later second. - The slack comparison is now strict (`at + coarse > pcFloor`): a whole-second turn dated exactly one second before the floor was written before it. The guard is deliberately limited to `unread` baselines. An adversarial Codex pass showed that applying it to every stamped send keeps a Grok send waiting for the full 60 s whenever its answer starts in the same second (Grok keeps the answer's start time), which is the common case after a read. Before the first read that trade-off is the one the unstamped path already accepts. ## Known limit (unchanged, shared with the unstamped path) Before the chat's first read, if an older identical turn is followed by an unrelated turn from another device in a later second before the new send's own turn is written, the later turn counts as the older one's answer and settles the send. Same behaviour as the existing unstamped guard. ## Validation - Failing first: the new test "keeps a send the PC stamped before the chat's first read waiting past an older identical turn of the stamp's second" failed on origin/main and passes with the fix. - New test "settles a stamped send after the chat's read by its own whole-second turn though the answer began in that second" pins the regression Codex found in a broader first version. - `bun test src/lib/sentWaiting.test.ts src/lib/useComposerSends.test.ts src/lib/machineSession.test.ts src/components/SentWaiting.test.tsx`: 120 pass. - `bun run check fast`: pass (12799 unit tests, typecheck, build). - Skipped: integration and browser suites (client logic only, covered by unit tests). - Review: Codex (gpt-6.1-terra, adversarial) on the first version; its MEDIUM regression and LOW boundary are fixed here, its second MEDIUM is the known limit above.
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.
Fixes #2974.
What changes
An immediate (composer) send now gets the same PC stamp a queued row has. The bridge takes its clock right before it types the message and returns it as
sending_aton thesubmit-result(immediate sends, a queued send typed at once withtyped_now, and a held copy's resend that typed). The browser bounds the send's waiting copy by that stamp alone (stampedBaselineinsrc/lib/sentWaiting.ts), so neither clock's moves since the chat's last read matter:An older bridge sends no stamp, and the read-based bound from #2973 stays for it. The queued-row path in
machineSession.tsuses the same helper (same behaviour, plus the shown-turn time no longer overrides the row's stamp).Protocol:
sending_at?: stringonsubmit-result(optional, additive; older clients ignore it).Validation
src/lib/sentWaiting.test.ts,src/lib/ws.test.tsandserver/pending-input.contract.test.tsfail on origin/main (4 fails) and pass with the fix.bun test src/lib/sentWaiting.test.ts src/lib/ws.test.ts src/lib/machineSession.test.ts server/pending-input.contract.test.ts server/pending-input.test.ts: pass.bun run check fast: ok (unit 12666 pass, 0 fail).