Repository navigation
fix(mothership): send a late queue write to the chat a new-chat queue moved to - #8741
Conversation
… moved to On the new-chat surface, a Send-now whose Stop saw the first message admitted moved the queue to that chat, but the follow-up's busy refusal was re-queued under the dead new-chat key it was dispatched from: gone from the chat, never retried there, and liable to be adopted into a new chat later. migrate now records where a key moved, and every write that captured a key before an await (the dispatch's removal and restore, the direct send's re-queue, the history check's defer and drop) resolves it at write time (liveQueueKey). Every re-queue on a chatless surface also carries the surface, so one that lands after the surface unmounted can still be adopted.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 8 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Turn on auto-fix | Re-trigger cubic
|
…dy held When the new-chat queue moved into a chat queue that already had messages, migrate put those first, but a late write still used its index in the new-chat queue and could land ahead of them. The move now records how many messages it went behind, and late writes resolve their position, not just their key (liveQueuePosition).
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
…not an index A restored message went back at an index captured at dispatch, offset by how many messages a chat's queue held when the new-chat queue moved into it. Removing any of those while the POST was out shifted it behind a newer message. It now goes right after the last message still queued that was ahead of it (at dispatch, or in the chat's queue before the move), else at the head.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
migratenow records where a new-chat key moved (migratedTo), including when its queue was empty.awaitresolves it at write time: the dispatch's removal and restore, the direct send's re-queue after its POST, and the history check's defer and drop. Removals and defers useliveQueueKey. Inserts useliveQueuePosition, which anchors on identity: a restored message goes right after the last message still queued that was ahead of it (at dispatch, or in the chat's queue before the move), else at the head, however the queue changed meanwhile.heldSurface. If it landed after the surface unmounted, when nothing else marks the dead key's queue, no later mount adopted it.requeuedFieldsnow tags the surface for every reason.STOP_REQUEST_TIMEOUT_MSnow describes it;sendMothershipMessagenormalizes throughsendPayload().Type of Change
Testing
re-queues a Send-now refused as busy in the chat the new-chat surface moved to(DOM) reproduces the scenario. It fails on staging, where the follow-up is left under the dead key and the visible queue is empty, and passes here.send-queue-policy.test.ts: Stop-failed and failed re-queues keep their chatless surface. Fails on staging.liveQueueKeyfollows a migration, including one whose queue was empty, a late insert stays behind the messages the chat's queue already held, and stays in order when messages ahead of it are removed meanwhile.Checklist