Surface Duo SAST triage recommendation in MR comment
What does this MR do and why?
Phase 2 of automated SAST triage, following the shadow-mode classifier shipped in !236130 (merged).
Until now the shadow-mode SastTriageClassifier only wrote per-finding verdicts to the gl-sast-triage-verdicts.json CI artifact. This MR surfaces the Duo verdict to the engineer: it appends a short Duo triage recommendation block to the existing inline SAST comment stating likely true positive / likely false positive, the confidence, and a one-line rationale.
Gating
A new SAST_TRIAGE_COMMENT_ENABLED CI variable (default "0") controls this, kept separate from SAST_TRIAGE_ENABLED so silent shadow-mode data collection stays possible without surfacing anything to engineers. Both must be 1 for a recommendation to appear. The code lands inert.
Security: rationale sanitization
The rationale is model-derived from a prompt that includes the attacker-influenced code excerpt under review, so it is untrusted output the bot would otherwise post with its PAT. Before posting it is sanitized: whitespace is collapsed (defuses line-leading GitLab quick actions such as /label, /assign), backticks are stripped, and the result is wrapped in an inline code span (neutralizes @mentions and Markdown/HTML). A spec exercises an injection payload.
Only definitive tp/fp verdicts are surfaced; uncertain or errored verdicts fall back to the standard comment.
Note for reviewers
Flipping the flag on an MR that already has a bot comment does not backfill a recommendation — findings are deduped by fingerprint header, so recommendations only appear on findings commented after the flip. This matches existing dedup behavior.
References
References https://gitlab.com/gitlab-com/gl-security/product-security/appsec/appsec-team/-/work_items/1647