Remove Labkit rate limiter feature flags, collapse to always-on

What does this MR do?

Removes the cohort 1-6 Labkit::RateLimit migration feature flags and collapses Gitlab::ApplicationRateLimiter onto the labkit path as the sole, authoritative rate limiter. With the migration fully enforced on .com, the dual-path machinery is no longer needed.

Removed:

  • The 20 rate_limiter_use_labkit_* and *_enforce wip flag YAMLs (cohorts 1-6).
  • The legacy Redis counter path (legacy_throttled?, the application_rate_limiter:* key shape, the strategy dispatch through it).
  • The shadow comparison (record_divergence, gitlab_rate_limiter_labkit_shadow_total) and the boundary-noise tagging.
  • The override-to-legacy routing (override_routes_to_legacy?, record_override, gitlab_rate_limiter_labkit_override_total). Per-call threshold:/interval: overrides are now honoured by labkit through the Rule's rule_context lambdas.
  • The gitlab_application_rate_limiter_throttle_utilization_ratio histogram (legacy-path only).
  • The now-dead flag_scope: registry metadata (the per-key/cohort flag mapping, unread once the flags are gone), the EE spec examples that asserted it, and the comments describing the removed flag/shadow machinery.

LabkitAdapter is now flag-free: shadow_or_enforce?, enforce?, and flag_basis are gone, replaced by handled? (registry membership). _throttled? returns labkit's decision directly.

Guardrail

Because there is no legacy fallback, a rate_limits key with no registry entry would no longer be rate limited at all. A new spec asserts every ApplicationRateLimiter.rate_limits key has a SupportedRateLimits entry, so a new key can't silently bypass rate limiting. As part of that, this MR registers the previously-unregistered keys token_exchange and project_generate_new_export, plus placeholder_reassignment, a key added to rate_limits on master after this branch forked that the guardrail flagged on the merge ref.

Reviewer notes

  • Merge ordering / overlap: the token_exchange and project_generate_new_export registry entries are also added by !239752 (merged) and !239753 (merged). A rebase/conflict against whichever merges first is expected. Separately, placeholder_reassignment was added to rate_limits on master after this branch forked; it is registered here ahead of the rebase so the guardrail stays green on the merge ref.
  • Metric removal: gitlab_application_rate_limiter_throttle_utilization_ratio is removed. Any Grafana panel or alert still keyed on it must be migrated to the labkit metrics (gitlab_labkit_rate_limiter_*) before this merges.
  • Dropped window specs: examples that asserted counter reset after the interval via travel_to are removed. Window expiry is now labkit's Redis-TTL behaviour, which travel_to cannot drive; it is covered by labkit's own specs.
  • resource: callers: verified the only caller passing resource: (the git-abuse BaseThrottleService) uses the unique_project_downloads_* keys, which are count_distinct (set-mode) and remain handled.
  • Follow-up (not in this MR): the legacy strategy Redis methods (BaseStrategy, IncrementPerAction#increment/#read, etc.) are now dead but still referenced for dispatch type-routing; slimming them is left to a separate MR to keep this one focused.

Do not merge until

  • Cohort 5 (*_db_duration_*, gitlab-com/gl-infra/production-engineering#28812 (closed)) fully enforced on .com. Satisfied (2026-06-11): all cohorts 1-6 are enforced on .com and the shadow path wound down ~June 9, so labkit is already authoritative for these keys; removing the flags no longer changes runtime behaviour.

Verification

Ran locally against the GDK (Redis + Rails): the rewritten application_rate_limiter_spec, labkit_adapter_spec, both supported_rate_limits_specs, and web_hooks/rate_limiter_spec all pass, plus the guardrail spec under FOSS_ONLY=1. RuboCop clean on changed files.

References

Edited by Max Woolf

Merge request reports

Loading