Add aiGovernanceSessions GraphQL field

What does this MR do and why?

Adds an aiGovernanceSessions GraphQL field on groups and projects. It lists AI governance sessions, so the AI Audit Events report can show sessions from GitLab Duo and external agents such as Claude Code.

  • Reads from ClickHouse only, from the Siphon replica table siphon_ai_governance_sessions. (Siphon copies rows from PostgreSQL to ClickHouse.) It uses the ClickHouse finder Ai::Governance::Sessions::ClickHouseFinder. On GitLab.com, reads use ClickHouse.
  • When ClickHouse is not enabled for analytics, the field returns no sessions (empty list, count 0). A PostgreSQL path for self-managed instances without ClickHouse will follow separately in !257556. This MR no longer depends on it.
  • Same filters and response shape as duoWorkflowSessionArtifacts, with session-based names.
  • Pagination is keyset (cursor) pagination on session start time and ID, newest first. count runs a ClickHouse COUNT.
  • Project, group and user are batch-loaded, so there is no extra database query per row.
  • auditEventsCount comes in a follow-up MR.
  • Behind the ai_governance_sessions_api feature flag, off by default. Also gated on ClickHouse.

The ClickHouse finder was added in !258121 (merged). This MR targets that branch until it merges.

References

Screenshots or screen recordings

Not applicable. Backend only.

How to set up and validate locally

  1. Make sure ClickHouse and Siphon are running in GDK and ClickHouse is enabled for analytics (Gitlab::ClickHouse.globally_enabled_for_analytics? returns true).
  2. Enable the feature flags in a Rails console:
    Feature.enable(:ai_governance_sessions_api)
    Feature.enable(:sync_ai_governance_sessions)
  3. Run a GitLab Duo flow in a project in the group (for example an agentic chat), so a session row is written and Siphon copies it to ClickHouse. Alternatively, create a session in the console:
    group = Group.find_by_full_path('gitlab-org')
    Ai::Governance::Session.create!(namespace: group, user: User.first, source: :claude_code_glab, external_xid: SecureRandom.uuid, agent_type: 'claude-code', flow_type: 'claude_code', session_started_at: Time.current)
    Then wait a few seconds for Siphon to replicate it.
  4. Run this query in GraphiQL at /-/graphql-explorer:
    query {
      group(fullPath: "gitlab-org") {
        aiGovernanceSessions(first: 10) {
          count
          nodes { id sessionId flowType agentType source sessionStartedAt webPath downloadPath triggeredBy { username } }
        }
      }
    }
  5. Optional: disable ClickHouse for analytics and run the query again. It returns an empty list.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Hitesh Raghuvanshi

Merge request reports

Loading
Loading