Skip to content

fix(server): do not rebind assistant turnId after queue drain#101

Merged
patroza merged 2 commits into
fork/changesfrom
fix/queue-drain-assistant-turnid-rebind
Jul 27, 2026
Merged

fix(server): do not rebind assistant turnId after queue drain#101
patroza merged 2 commits into
fork/changesfrom
fix/queue-drain-assistant-turnid-rebind

Conversation

@patroza

@patroza patroza commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

Investigated t3vm thread 16feaadd-e89d-4101-bcd9-ac7e1d723de0 (Discord + queue drain).

Event log smoking gun

At 2026-07-27T05:57:21.174Z:

  1. assistant:…:segment:5 correctly written under turn c25ca2c5 with the 1791-char final
  2. Queue drains → new user + turn 89e689f8 starts
  3. 11s later empty assistant-complete for the same messageId with turnId=89e689f8 restamps the bubble onto the next turn

Projection then showed the final as part of the follow-up turn. Discord finalized short trailers (segment:7) and deleted the tip that had held the real answer.

Fix

  • Projector: once an assistant message is bound to a turn, never rebind turnId to a different turn
  • ProviderRuntimeIngestion: skip re-complete when the message is already bound to another turn

Related

  • Discord tip finalize-before-new-delivery (child of feat(discord): Discord bot #80): fix/discord-finalize-before-queue-drain
  • Web/mobile fold rehome for the same mis-stamp class

Test plan

  • projector unit test for queue-drain restamp race
  • server typecheck (no new errors in changed files)

patroza added 2 commits July 27, 2026 08:17
When a turn completes and a queued follow-up drains in the same window,
provider runtime can re-emit assistant.complete for the same message id
under the new activeTurnId. The projector was overwriting turnId, which
orphaned the real final from its completed turn.

Keep the original assistant turn binding once set, and skip ingestion
re-complete when the bubble is already bound to a different turn.
Collapse the queue-drain restamp unit test into one Effect.gen run and
bump the projector.test.ts legacy baseline by one so Check stays green.
@patroza
patroza merged commit de1a31f into fork/changes Jul 27, 2026
10 checks passed
patroza added a commit that referenced this pull request Jul 27, 2026
* fix(server): do not rebind assistant turnId after queue drain

When a turn completes and a queued follow-up drains in the same window,
provider runtime can re-emit assistant.complete for the same message id
under the new activeTurnId. The projector was overwriting turnId, which
orphaned the real final from its completed turn.

Keep the original assistant turn binding once set, and skip ingestion
re-complete when the bubble is already bound to a different turn.

* fix(server): keep projector rebind test under Effect.runPromise baseline

Collapse the queue-drain restamp unit test into one Effect.gen run and
bump the projector.test.ts legacy baseline by one so Check stays green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant