Skip to content

QM-54: Refresh the web chat transcript on return when no live run remains to re-attach - #1497

Merged
pcapriolo-yc merged 1 commit into
qm-29-port-factory-loopfrom
qm-54-s439776277
Sep 21, 2026
Merged

pcapriolo-yc merged 1 commit into
qm-29-port-factory-loopfrom
qm-54-s439776277

Conversation

@pcapriolo-yc

Copy link
Copy Markdown
Contributor

Closes QM-54.

Changes

Why this matters: When a phone locks or a chat tab is backgrounded, the browser drops its connection to the delivery event stream, and that stream has no replay buffer — every completion and delivery notification emitted while the tab is away is lost for good. Coming back to the tab did not repair anything: the return path only knew how to re-attach to a run that was still going, so a turn that finished while you were away left the chat showing the old transcript. The only way to see the answer was a full page reload.

What changes:

  • Returning to a backgrounded chat now refreshes the transcript when there is no live run to re-attach to, so a reply that completed while you were away appears in place, with no reload and no click.
  • The same catch-up runs when the delivery event stream reconnects after a network blip, so a tab that stayed visible through a dropout also reconciles.
  • The refresh pulls the whole turn back — assistant reply, mid-turn posts, attachments, pins and pending approval cards — using the existing transcript refresh, so approvals are immediately actionable.
  • A run that is genuinely still streaming is re-attached exactly as before: no second fetch, no interruption, and queued-run chips are preserved.

Acceptance stories:

  • A person starts a turn in the web chat, locks their phone while it runs, and returns: previously the chat still showed only the old transcript until they reloaded; now the completed reply is rendered on return.
  • A person returns to a chat whose run the server still reports as terminal: the transcript catches up instead of trying to attach to a finished run.
  • A person on a visible tab loses connectivity briefly: when the event stream reconnects, the reply that landed during the dropout appears without any tab switch or reload.
  • A person switches to a different chat while the returning chat is still fetching: the other chat's messages never paint into the one now on screen.
  • A person sends a follow-up right after the catch-up: it lands in the same session and streams normally, with the recovered turn still above it and nothing duplicated.

Test Plan

  • npm --prefix plugins/web-ui test
  • npm --prefix plugins/web-ui run typecheck
  • npm run lint
  • Manual: against a local dev stack, started a turn in the web chat, severed the delivery event stream so the tab missed every frame, let the turn finish server-side, then returned to the tab — the completed reply rendered with no reload, and a follow-up message sent afterwards landed in the same session.

Proof it works

Browser A/B against a local dev stack: with the unfixed bundle the reply is still missing after the return; with the fix it renders in place, and the JSDOM regression suite covers the terminal-run, live-run, reconnect and session-switch paths.

story1-backgrounded-return-before-fix-01-baseline.png
story1-backgrounded-return-before-fix-01-before-lock.png
story1-backgrounded-return-before-fix-01-before.png
story1-backgrounded-return-before-fix-02-stale.png
story1-backgrounded-return-before-fix-02-after-return.png
story1-backgrounded-return-before-fix-03-after-return.png
story1-backgrounded-return-after-fix-01-before.png
story1-backgrounded-return-after-fix-02-stale.png
story1-backgrounded-return-after-fix-03-after-return.png
story1-backgrounded-return-after-fix-tall-01-before.png
story1-backgrounded-return-after-fix-tall-02-stale.png
story1-backgrounded-return-after-fix-tall-03-after-return.png
story1-backgrounded-return-01-before-lock.png
story1-backgrounded-return-02-stale-on-return.png
story1-backgrounded-return-03-after-return.png
story2-missed-delivery-before-fix-01-before.png
story2-missed-delivery-before-fix-02-after.png
story2-send-after-return.png
story3-sse-reconnect-before-fix-01-during-blip.png
story3-sse-reconnect-before-fix-02-after-reconnect.png

Screen recordings are not embeddable here; they are kept as run artifacts:

@pcapriolo-yc
pcapriolo-yc merged commit 0e7e13f into qm-29-port-factory-loop Sep 21, 2026
16 checks passed
@pcapriolo-yc
pcapriolo-yc deleted the qm-54-s439776277 branch September 21, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant