Draft: Enable false positive execution fallback for vulnerabilities filter

What does this MR do and why?

This MR is the third and final step in the execution fallback rollout. It validates the framework by implementing a real, end-to-end fallback filter: false_positive for vulnerabilities search.

It proves that the execution fallback framework can be used safely in production scenarios, with correct behaviour across PostgreSQL enrichment, resolver wiring, pagination guarantees, and feature flag control.

This MR:

  • Implements PostgreSQL enrichment for the false_positive filter via VulnerabilitiesEnrichment.false_positive
  • Adds support for filtering only flags detected as false positives (status: :detected_as_fp)
  • Wires false_positive into the execution fallback pipeline in VulnerabilitiesResolver
  • Guards execution fallback behind the :ai_experiment_sast_fp_detection feature flag
  • Automatically disables fallback once the Elasticsearch migration is complete(in this case we have to update the query so it's set to false, see #585703 (closed))
  • Refactors the FalsePositive preloader to delegate all logic to the enrichment layer
  • Adds shared specs to validate fallback activation rules (feature flag + migration state)
  • Adds focused tests for:
    • Enrichment correctness
    • Resolver configuration
    • Preloader delegation
    • Error handling and safety behavior

This MR serves as the reference implementation for future fallback filters and demonstrates that:

  • Fallback logic is reusable and composable
  • Frontend and backend development can progress in parallel
  • Pagination remains stable under mixed execution strategies
  • Multi-version compatibility is preserved

Query plan

https://console.postgres.ai/gitlab/gitlab-production-sec/sessions/47399/commands/143422

Click to expand
SELECT
  "vulnerability_occurrences"."vulnerability_id"
FROM
  "vulnerability_occurrences"
INNER JOIN
  "vulnerability_flags"
  ON "vulnerability_flags"."vulnerability_occurrence_id" =
     "vulnerability_occurrences"."id"
WHERE
  "vulnerability_occurrences"."vulnerability_id" IN (
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
    31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
    51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
    61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
    91, 92, 93, 94, 95, 96, 97, 98, 99, 100
  )
  AND (
    EXISTS (
      SELECT 1
      FROM "vulnerability_flags"
      WHERE
        "vulnerability_flags"."flag_type" = 0
        AND "vulnerability_flags"."vulnerability_occurrence_id" =
            "vulnerability_occurrences"."id"
    )
  )
  AND "vulnerability_flags"."flag_type" = 0
  AND "vulnerability_flags"."status" = 2;

References

This work is split into three MRs to make adoption incremental and easier to review:

Screenshots or screen recordings

Before After

How to set up and validate locally

The primary way to validate this change is through the test suite.

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.

Edited by Ugo Nnanna Okeadu

Merge request reports

Loading