Trigger risk classification from the flow trigger platform
What does this MR do and why?
Nothing started a risk classification. The flow existed, a project could turn it on, and it still never ran: something had to call it, and that something was a service and a worker written only for this one flow.
The flow now declares its own triggers instead. It runs when a merge request opens and when one changes from draft to ready, so turning the flow on for a project is the only switch a user touches. That is how every other foundational flow works.
Getting there needed one thing the platform did not have. A flow sometimes has to put a record in place before it starts, and there was no way to say so from a flow definition. Two optional callbacks, before_start and after_start, close that: each takes the triggered resource, each defaults to nothing. Risk classification uses before_start to record that a classification is running, which is what lets the widget tell "running" from "never ran" once it ships.
before_start fires after the last check that can still refuse a run, not before it. Otherwise a refused run would leave a record claiming a classification is in progress.
This is deliberately incomplete. Nothing scores the claims a run sends back, and nothing expires a record whose run goes quiet. Both arrive with the scoring work, which is also when duo_mr_risk_classification can be turned on. Until then a triggered run stores its claims and stops there. Left as a draft for that reason.
What the flow is told about the merge request it classifies is a separate change, !254877 (merged). Both target master and neither depends on the other, but a run started from this branch alone stops at the agent's input validation, because the agent platform config expects the inputs that MR sends. Check out both to watch a run reach the agent.
References
- Issue: #609293 (closed)
- What the flow is told about the merge request: !254877 (merged), paired with gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!6872 (merged)
- Scoring and orchestration, which fill in the rest: !253486 (merged) and !253762 (merged)
- Phase 1 epic: &23131
Screenshots or screen recordings
Not applicable. No user-facing surface changes here: the widget that reads the record ships in !251381 (merged).
How to set up and validate locally
The flow is ultimate_only, so the GDK needs an Ultimate licence. One feature flag gates the flow:
# Gates the flow itself. Without it the flow is hidden in group settings, and a
# trigger that somehow fires is refused.
Feature.enable(:duo_mr_risk_classification)The "merge request created" event needs no flag of its own. It fires for any project that already has an active trigger.
-
Turn the flow on for the top-level group. Go to the group, then Settings > GitLab Duo > Change configuration. Under Flow execution, select Allow flow execution and Allow foundational flows, select Risk Classification, then Save changes.
-
Turn it on for the project. Go to the project, then Settings > General, expand GitLab Duo, turn on GitLab Duo, Allow flow execution and Allow foundational flows, then Save changes.
-
Confirm the triggers came with it. Go to AI > Triggers in the project. Risk Classification has a trigger listing the merge request and merge request ready events, created for you when the flow was turned on. That is the point of this MR: enabling the flow is the only switch, where before nothing started a classification at all.
-
Open a merge request, or mark an existing draft as ready. Then go to AI > Sessions: a Risk Classification session appears for it.
-
Confirm
before_startrecorded the run, which is what the widget will read to tell "running" from "never ran":mr = MergeRequest.last mr.risk_assessment.status # => "pending" mr.risk_assessment.diff_sha # => the merge request head SHA mr.risk_assessment.score # => nil, nothing scores it yet -
This branch alone stopped at input validation. The agent platform config asked for inputs this branch does not send:
input 'risk_classification' does not match specified schema: 'merge_request_iid' is a required propertyThe two merge requests that supplied the missing inputs, !254877 (merged) and gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!6872 (merged), have since merged. A run on current master now reaches its submit step instead. This MR is responsible for everything up to that point: the trigger fired, a session started, and the record is in place.
-
Confirm a flow that declares no callbacks is unaffected, so this changes nothing for every other flow:
Ai::Catalog::FoundationalFlow.code_review_v1.run_before_start(resource: MergeRequest.last) # => nil
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.