Include all scalar channels in the incremental checkpoint blob delta
Problem
The gateway only serializes list/dict channels into the incremental blob delta, with status as the sole scalar exception (_ALWAYS_BLOBBED_SCALAR_CHANNELS in duo_workflow_service/checkpointer/gitlab_workflow.py). Every other scalar channel — branch:to:*, approval, goal, namespace, last_human_input — is never blobbed.
While the full checkpoint row is written this is harmless (the scalars live there). Under duo_workflow_write_incremental_only there is no full row, so these scalars are lost on reconstruction. Most critically branch:to:* — LangGraph's run queue — whose absence makes a resumed graph see zero armed tasks and silently terminate (QA scenario 2 on gitlab-org/gitlab!247134 (merged), note).
What
Blob every channel in channel_values regardless of type. Replace the _ALWAYS_BLOBBED_SCALAR_CHANNELS exact-match allowlist with "blob all channels" at both filter sites (_serialize_channel_blobs, _serialize_all_channels_full), and delete the allowlist rather than growing it.
A verified PoC (from the MR note) that only added channel.startswith("branch:to:") makes scenario 2 pass, but the correct fix is to stop special-casing type at all — scalars are cheap and the model should carry them uniformly.
Encoding notes (from the PoC)
- Scalars serialize as
write_type: "json"; aNone-valued scalar (e.g.branch:to:X = null) blobs cleanly and RailsChannelValuesReconstructor.decodereturnsnilwith the key preserved. is_compaction/current_threadbehavior is unchanged (no spurious group bump).- Write-side only — cannot repair sessions checkpointed before the change.
Depends on / pairs with
This alone is not sufficient and must not ship without the membership fix. Blobs are append-only, so blobbing all scalars makes deleted channels linger (the reconstructed key set is the union of every channel ever blobbed). The header must carry the live membership so the read path selects only current channels:
- Header membership (write, Rails): gitlab-org/gitlab#613956 (closed) — persist
channel_values.keyson the checkpoint header. - Reconstruction filter (read, Rails): gitlab-org/gitlab!247134 (merged) — fold blobs, then select only the header's declared keys.
Related
- MR note with full analysis: gitlab-org/gitlab!247134 (comment 3652137773)
- Write-only rollout FF: gitlab-org/gitlab#607029
- Gateway read consumer: !6363 (merged)