Fix nondeterministic finding calibration on duplicates
What does this MR do and why?
Security::OverrideUuidsService calibrates each security report finding's uuid against
previously-seen Vulnerabilities::Finding records so a vulnerability keeps a stable identity
across pipelines. The candidate records it groups by signature or by location fingerprint were
not deterministically ordered, and the lookup then picked one with Array#find, i.e. whatever
the database returned first.
On projects with duplicated finding records for the same location, signature, primary identifier
and scanner, this let two pipelines running the identical report calibrate the same finding to two
different existing records. The finding ended up with a different uuid on the source branch
pipeline than on the target branch pipeline while sharing the same overridden_uuid. The MR
security widget and scan_finding approval policy comparison then saw one uuid only in the head
pipeline and one only in the base pipeline, and reported the finding as both newly detected and
fixed, which could block the MR under a vulnerabilities_allowed: 0 policy for no real reason.
Before: which existing record a duplicate finding calibrates to depends on database return order, so head and base pipelines can disagree. After: candidates are sorted by id before grouping, so the oldest record always wins and both pipelines agree.
This does not merge or remove duplicated finding records, it only makes calibration deterministic.
How to set up and validate locally
bundle exec rspec ee/spec/services/security/override_uuids_service_spec.rb ee/spec/services/security/override_uuids_service/override_in_batch_spec.rb
bundle exec rspec ee/spec/services/security/store_scan_service_spec.rbThe first command includes two new examples covering duplicated existing findings that share a signature and tracked context: one runs the query in natural database order, the other forces the query to return the same rows in reverse order. Both must resolve to the older record. The reverse-order example fails without this fix.
References
- #601032 — duplicated finding records left behind by signature normalization, which is the data condition this nondeterminism needs to misbehave.