Add forced variant assignment for backend-only experiments (no request available)

Context

This is a follow-up to #579133 (closed) (requirement 3).

The first iteration (see gitlab-org/ruby/gems/gitlab-experiment MR) adds forced variant assignment via a glex_force query parameter. This covers:

  • Requirement 1: Works in staging/production
  • Requirement 2: Handles anonymous (nil actor) entrypoint

However, the query parameter approach requires a request object with params to be available. This does not cover cases where:

  • The variant is decided fully in the backend with no clear UI/request entrypoint
  • The experiment runs in a background job (Sidekiq), service object, webhook handler, or cron job
  • Passing a parameter from a request down to where the experiment runs is complicated or impossible (deeply nested service calls)

Requirements

  1. Must work without a request object available in the experiment context
  2. Must be able to target a specific user/actor for a specific experiment
  3. Should integrate with the existing GLEX cache so the forced variant persists and behaves like a normal assignment
  4. Should be clearable (allow returning to normal rollout assignment)

Ideas

  1. Redis-backed override keyed by context key or user identity: A dedicated endpoint (or ChatOps command) stores the override in Redis. forced_variant_name checks this store when no request param is available. Adds a Redis read per experiment resolution (can be request-level cached).
  2. ChatOps integration: /experiment force signup_cta candidate user:123 writes the override to Redis. Clean UX for internal teams.
  3. Actor name convention: Prefix/suffix the actor identifier (e.g., bob_glex_candidate) to signal forced assignment. Fragile but no infrastructure needed.
  4. Configuration-level override map: Configuration.forced_assignments = { 'experiment_name' => { user_id => :variant } }. Simple but doesn't scale.

Relates to

  • #579133 (closed) (parent issue)
  • gitlab-org/ruby/gems/gitlab-experiment (GLEX gem)
Edited by 🤖 GitLab Bot 🤖