Add RuboCop cop and runtime warning for direct checkpoint table reads

What does this MR do and why?

This MR adds two guardrails to catch direct reads of the legacy Ai::DuoWorkflows::Checkpoint table (p_duo_workflows_checkpoints) when incremental blob reconstruction should be used instead. Investigating #612557 (closed) found 8 consumers breaking this way, tracked under &23217 (closed). This MR does not fix any of those 8 consumers; it only prevents new violations and surfaces existing ones.

RuboCop cop Gitlab/Ai/AvoidDirectCheckpointTableRead flags <workflow>.checkpoints.{latest,earliest,order_by_created_at_desc,ordered_with_writes,with_checkpoint_writes} and any .basic_checkpoints call outside ee/app/models/ai/duo_workflows/{workflow,checkpoint}.rb, pointing callers at Workflow#checkpoint_headers/#latest_checkpoint_header/#reconstructed_channel_values. A todo file exempts the 7 files that violate it today, one per sibling issue under the epic.

Runtime warning: Checkpoint.latest/.earliest now call Gitlab::ErrorTracking.track_exception (not raising) when the fetched record's workflow.reconstruct_from_blobs? is true. Deliberately non-raising: several duo_workflow_* read flags are still disabled by default, and raising in dev/test could break specs that enable them ahead of the 8 consumers being fixed.

Closes #612601 (closed).

Verification

  • New RuboCop cop spec (spec/rubocop/cop/gitlab/ai/avoid_direct_checkpoint_table_read_spec.rb): 11 examples, all passing.
  • Ran the cop with REVEAL_RUBOCOP_TODO=1 against the 7 exempted files plus the two sanctioned model files: flagged exactly the 8 real offense sites, zero false positives.
  • Ran ee/spec/models/ai/duo_workflows/checkpoint_spec.rb: 36 examples, 0 failures (3 pre-existing pending, unrelated) -- confirms the new warning doesn't break existing specs.

Merge request reports

Loading
Loading