Skip to content

Run progress replay-gap notice can render repeatedly as the acknowledged boundary advances #2750

Description

@alectimison-maker

This was generated by AI during triage.

Summary

When a side panel reconnects to an active run whose earlier UI-journal events were acknowledged elsewhere, the “Some earlier run progress could not be replayed” notice can be rendered more than once for the same run. A real Chrome session showed two identical notices consecutively.

This is reproducible on current main (9aa969c3) in both Chrome and Firefox code paths.

Deterministic reproduction

The current dedupe mirrors this logic in applyActiveRunState():

if (unavailableBeforeSeq > lastRenderedSeq
    && unavailableBeforeSeq > replayGapBeforeSeq) {
  addRunProgressReplayGapNote();
  replayGapBeforeSeq = unavailableBeforeSeq;
}

Using the real RunUiJournal, acknowledge seq 1, poll from a remounted panel with lastRenderedSeq = 0, then record and acknowledge seq 2 and poll again. The first boundary renders one notice; the second boundary is larger than replayGapBeforeSeq, so it renders a second identical notice. The observed count is 2 for one request.

Root cause

replayGapBeforeSeq deduplicates a specific numeric boundary, not the fact that this run already has a replay-gap notice. During an active run, ackedSeq can keep advancing while a different/remounted panel still has lastRenderedSeq = 0, so each larger boundary is treated as a new user-visible gap.

The existing regression test covers repeated polling of a constant boundary, but not an advancing acknowledged boundary for the same request.

Suggested direction

  • Treat the notice as once-per-run/assistant UI state, for example with a durable boolean dataset marker or by checking for an existing run-owned notice.
  • Pass the target assistant element into the notice renderer instead of relying on global currentAssistantEl, so the marker and rendered note always belong to the same run.
  • Keep the replay cursor independent: showing the notice must not claim unavailable events were rendered.

Acceptance criteria

  • Increasing ackedSeq multiple times for one request renders exactly one replay-gap notice.
  • Repeated state polls and chat-history DOM restore do not duplicate the notice.
  • Two distinct requests may each render their own notice.
  • Terminal finalContent remains restorable after acknowledged progress is unavailable.
  • lastRenderedSeq is not advanced merely because the notice was shown.
  • Chrome and Firefox behavior and regression coverage remain aligned.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions