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?onAi::DuoWorkflows::Workflow(master kill switchduo_workflow_read_incremental_checkpointsplus the per-consumerdw_read_blobs_notifications, literal flag perGitlab/FeatureFlagKeyDynamic).- Channel-scoped
reconstructed_channel(checkpoint, channel)that decodes only the requested channel's blobs (avoids folding every channel just forui_chat_log). Checkpoint#ui_chat_logbranches on the gate; the mailer now reads viaCheckpoint#ui_chat_logso 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.