Scan trigger order in Manage profiles changes based on toggle history

Summary

In a group's Security configuration page, opening Manage profiles for a scan profile and looking at its Scan triggers section shows the trigger cards (for example Secret push protection, Branch, Merge request) in an order that can change over time instead of staying static.

Steps to reproduce

  1. Open a group's Security configuration page.
  2. Open Manage profiles for a profile with more than one trigger (for example a Secret Detection profile).
  3. Edit the profile, disable one of its triggers, save, then re-enable the same trigger and save again.
  4. Reopen Manage profiles and check the trigger order in the read-only detail view.

Actual behavior

The re-enabled trigger moves to the end of the list.

Screenshot 2026-10-05 at 13.06.08.png

Expected behavior

Scan triggers render in a fixed order (for example Merge request, Branch, Secret push protection) no matter which trigger was most recently toggled.

Screenshot 2026-10-05 at 13.06.26.png

Root cause

Investigation notes
  • resolveTriggers in ee/app/assets/javascripts/security_configuration/components/scan_profiles/utils.js rendered profile.triggers in whatever order the GraphQL API returned it, with no canonical sort.
  • ScanProfileType#triggers (ee/app/graphql/types/security/scan_profile_type.rb) maps scan_profile_triggers with no explicit order:, so rows come back in whatever order the association query happens to return them.
  • Security::ScanProfiles::UpdateService#sync_triggers! destroys a disabled trigger's row and inserts a new one when it's re-enabled, so toggling a trigger off and back on moves its row to the end of insertion order.

Related to #624191 (closed)

Edited by Chen Charnolevsky