Gate messaging/notifications checkpoint reads on per-consumer flag

What

Gate the messaging/notifications consumers of the Duo Workflow incremental-checkpoint read path on a per-consumer feature flag.

The callback worker, progress reader, and input-required mailer all read ui_chat_log from the checkpoint header. Behind the notifications gate they now reconstruct ui_chat_log from incremental checkpoint blobs instead of the full header JSONB.

  • reconstruct_from_blobs_for_notifications? on Ai::DuoWorkflows::Workflow (master kill switch duo_workflow_read_incremental_checkpoints plus the per-consumer dw_read_blobs_notifications, literal flag per Gitlab/FeatureFlagKeyDynamic).
  • Channel-scoped reconstructed_channel(checkpoint, channel) that decodes only the requested channel's blobs (avoids folding every channel just for ui_chat_log).
  • Checkpoint#ui_chat_log branches on the gate; the mailer now reads via Checkpoint#ui_chat_log so it is gated alongside the worker and reader.

Feature flag

dw_read_blobs_notifications (wip, default disabled).

Issues

Database

No schema change / no migration. The only new query is the channel equality added onto the engine's already-reviewed accumulated_blobs_for (!247133 (merged)):

SELECT "p_duo_workflows_checkpoint_blobs".*
FROM "p_duo_workflows_checkpoint_blobs"
WHERE "workflow_created_at" = $1
  AND "project_id" = $2
  AND "current_thread" = $3
  AND "thread_ts" IN ($4, ...)
  AND "channel" = $5
ORDER BY "id" ASC;

Served by idx_duo_wf_checkpoint_blobs_dedup (project_id, workflow_id, thread_ts, channel, version, step_action, workflow_created_at), led by project_id; the added channel equality narrows within the scan. thread_ts is one bounded current_thread group (small N); the path runs in low-frequency messaging/notification code, not a hot endpoint. ~"database::review pending" applied.

Edited by Eduardo Bonet

Merge request reports

Loading