Channel history fold drops messages introduced by the compaction-triggering checkpoint
Problem
The display fold (ChannelValuesReconstructor#channel_history, and #channel_changes) keeps conversation deltas and drops mid-stream compaction snapshots. When a compaction is triggered by a turn, the gateway re-seeds every channel as full compaction snapshots in that same group boundary (gitlab_workflow.py — is_compaction → _serialize_all_channels_full). The turn's own ui_chat_log messages can then exist only inside the dropped compaction snapshot, never as a surviving conversation delta.
The fold's comment names the collision risk ("a colliding compaction would lose the version's messages") but the compaction-triggering step is the unconsidered case.
Symptom (reported while testing Manual Retry + Compaction)
- "Say 4" triggered a compaction; agent replied "4".
- On page reload, "Say 4" and "4" disappear from the chat.
- After sending "Say 5", they reappear — but after "Say 5", because the blob that carries them again sits later in chain order.
Repro
- Set
CompactionConfig(max_recent_messages=4, trim_threshold=0.1)induo_workflow_service/workflows/chat/workflow.py. - Enable
duo_workflow_incremental_checkpoints,duo_workflow_read_incremental_checkpoints,dw_read_blobs_graphql. - Chat until a message triggers compaction ("Ran compaction" badge), reload the page.
Where
ee/lib/gitlab/duo_workflow/channel_values_reconstructor.rb—channel_historydropsstep_action == COMPACTIONblobs unless they seed the base;channel_changesskips them unlessindex == 0.- Consumer: GraphQL messages/checkpoints under
dw_read_blobs_graphql(IC-D25's display fold).
Acceptance criteria
- Messages that first appear in the compaction-triggering checkpoint render after a reload, in their original position.
- Ordering stays chronological across the compaction boundary (no reappearance after later messages).
- A spec covering "delta content introduced only by a compaction snapshot".
Notes
- Not a production incident:
dw_read_blobs_graphqlhas never been enabled on gprd. It blocks enabling it (and everything downstream,#607029). - Related: the fold-vs-deletion family (IC-D13/IC-D54, #613975 (closed)).