Show ultimate_only agents when paid license is present

What does this MR do and why?

Fixes a regression introduced in 18.11 where the Security Analyst foundational chat agent (the only agent currently flagged ultimate_only) disappears from the chat agent selector on self-managed and Dedicated instances that have both:

  • A paid license (Premium / Ultimate / Duo Enterprise), and
  • An active instance-level gitlab_credits add-on (for example, a trial credit pool)

The Free DAP self-managed path in FoundationalChatAgentsResolver was checking only whether a gitlab_credits add-on was active, and if so, hiding all ultimate_only agents. It did not check whether the instance also had a paid license that should still grant access. Customers on Dedicated with a paid license and a trial credit pool layered on top would unexpectedly lose Security Analyst.

This MR mirrors the existing SaaS branch logic: only apply the free-tier filter when the instance does not have the :ai_catalog licensed feature (Premium-or-higher).

Related to #602167

Behavior change

License (Premium+) gitlab_credits add-on Before After
no absent shows ultimate_only shows ultimate_only (unchanged)
no present (Free DAP) hides ultimate_only hides ultimate_only (unchanged)
yes absent shows ultimate_only shows ultimate_only (unchanged)
yes present hides (bug) shows (fixed)

Root cause

Make DAP Free tier available on self-managed (!228648 - merged) added an unconditional reject(&:ultimate_only) filter on the self-managed path whenever any active gitlab_credits add-on was present at the instance level. The check did not consider the instance's license tier.

How to set up and validate locally

  1. Configure a self-managed instance with an active paid license that includes the ai_catalog feature.
  2. Add an active gitlab_credits add-on at the instance level:
    add_on = GitlabSubscriptions::AddOn.find_or_create_by_name(:gitlab_credits)
    GitlabSubscriptions::AddOnPurchase.create!(
      add_on: add_on,
      namespace: nil,
      started_at: Time.current,
      expires_on: 1.year.from_now,
      quantity: 1,
      purchase_xid: 'test-xid',
      organization: Organizations::Organization.default_organization
    )
  3. Run the following GraphQL query as a regular user:
    query {
      aiFoundationalChatAgents(projectId: null, namespaceId: null) {
        nodes { id name referenceWithVersion selectableInChat }
      }
    }
  4. Before this MR: Security Analyst is missing from the response.
  5. After this MR: Security Analyst appears in the response.

Customer impact

Reported via a Support ticket against a Dedicated instance on 18.11.4. Reproduces on any self-managed or Dedicated instance that combines a paid license with an active gitlab_credits add-on. Should be backported to 18-11-stable-ee.

Workaround for affected customers

Removing the trial gitlab_credits add-on from the instance restores Security Analyst immediately. The trade-off is loss of access to the trial credits.

Screenshots or screen recordings

N/A — behavior is verified via GraphQL response and specs.

How to test the change

bundle exec rspec ee/spec/graphql/resolvers/ai/foundational_chat_agents_resolver_spec.rb

Specs cover all four combinations of (license present/absent) × (gitlab_credits add-on present/absent). The new "Premium-or-higher license + active gitlab_credits add-on" case is the regression test for this issue.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Vitali Tatarintev

Merge request reports

Loading