Add "Tool calls by risk" donut card to the AI Governance dashboard

Builds on the donut chart (Add a reusable donut chart for the AI Governanc... (!256313 - merged)) and the tool calls card (Add the tool calls card, ClickHouse reader and ... (!256578 - merged)), both merged. Verified on GDK with the flags on (screenshots below).

What does this MR do and why?

  • Adds the "Tool calls by risk" card to the AI Governance dashboard, built on the donut from Add a reusable donut chart for the AI Governanc... (!256313 - merged).
  • Splits the AI tool calls in the selected window into Read, Write, Destructive and Unclassified, with the total in the center and percentages in the legend.
  • Adds an experiment byRisk { total approximate slices { risk count } } field to aiGovernanceToolCalls, behind the same ai_governance_tool_calls flag, which gates the card too and is off by default everywhere.
  • The card asks for byRisk only, so the top tools query does not run for it, and the top tools card does not trigger the risk query.

What we're building and how

What. One card that answers "how risky are the tool calls our AI agents make?". It follows the dashboard's Show control (All agents, DAP, Connected) and date range.

What "risk" means. Each tool's risk is its action type in the tool registry, the same classification the Tool management tab uses for its default permissions (Ai::ToolRules::Registry.action_type_of):

  • Read: read-only tools, such as reading an issue or a file.
  • Write: tools that change GitLab data or files.
  • Destructive: running commands, MCP tools and Git operations.
  • MCP tools take their action type from their own read-only and destructive hints.
  • Tools the registry does not know are counted as Unclassified.

How it's calculated. The tool calls reader from Add the tool calls card, ClickHouse reader and ... (!256578 - merged) counts ai_tool_invoked events per tool name in ClickHouse for the group or project and window. This MR asks it for every tool name instead of the top 10, then maps each name to its action type and adds the counts up. At most 1,000 distinct tool names are read. Past that, the most used 1,000 are counted and approximate is true.

Data notes
  • Counts follow the reader on master: ai_tool_invoked events (tool name in details.tool_name) and, since Count Claude Code tool calls (Count Claude Code tool calls in the AI Governan... (!259239 - merged)) merged, ai_claude_tool_invoked events (name in details.name). The top tools card and this card read the same events with the same agent class filter, so their totals agree.
  • GitLab MCP tools are recorded under the prefixed name the Duo Workflow Service calls them by (gitlab_search). The card strips that prefix before classifying, so an MCP tool gets the action type the Tool management tab shows for it.
  • Claude Code's own tool names (Read, Edit, Write, Bash and so on) are not in the tool registry, so those calls count as Unclassified until a mapping lands. Follow-up proposal: Read, Grep, Glob, LS, WebFetch, WebSearch as Read; Edit, MultiEdit, Write, NotebookEdit, TodoWrite as Write; Bash, Task and other agent-spawning tools as Destructive.

Screenshots

GDK, flags on, group view, next to the Top tools card:

Light Dark
group-all-pair group-all-pair-dark

How to set up and validate locally

  1. Enable ClickHouse for analytics and the flags ai_governance_dashboard and ai_governance_tool_calls for a group.
  2. Have ai_tool_invoked events in ClickHouse for that group, using a mix of registry tools and an unknown MCP tool name.
  3. Open the group's AI Governance dashboard.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Edited by Dheeraj Joshi

Merge request reports

Loading
Loading