feat(telemetry): send coding agent, CLI version and platform

Description

Stacked on !3822 (merged), which it targets. GitLab retargets this to main automatically when !3822 (merged) merges.

DetectCodingAgent already resolves which AI coding agent is driving glab, but the value only reached the outbound HTTP User-Agent. It lands in GitLab's API request logs, which are not joinable to this event stream, and never reaches Snowplow. CLIENT_NAME and AGENT_NAME are 100% NULL across the whole gitlab_cli_command_used stream.

This adds four properties, all already on BuildInfo at hook time:

property example
coding_agent claude-code
cli_version v1.116.0
platform darwin
architecture arm64

Cardinality is low and bounded, and none of them carry user or project identifiers.

Reading coding_agent correctly

coding_agent is omitted when no agent is detected. Older clients don't send it either, so NULL on its own is ambiguous and has to be disambiguated with cli_version, which new clients always send:

cli_version coding_agent meaning
present present agent-driven
present NULL genuinely not agent-driven
NULL NULL client predates the change, tells us nothing

Agent share therefore has to be scoped WHERE cli_version IS NOT NULL. Folding the third row into "human" would understate agent share badly during rollout, when most traffic is still old clients. This is written up for the dashboard in gitlab-data/product-analytics#3622.

An explicit none sentinel would have removed the ambiguity without the join, at the cost of a property on every event; we chose the omission plus the cli_version rule.

Monolith dependency

These land in gsc_extra and need declaring in config/events/gitlab_cli_command_used.ymlgitlab!253241 (merged). EventsRouter#public_additional_properties slices additional_properties down to the declared keys before the split into reserved columns and extra, so undeclared properties are dropped rather than passed through. No Iglu schema change, no collector change, no new mart column — the dashboard reads them with a JSON path.

Merging this ahead of the definition change is harmless: the properties are simply sliced off until the YAML deploys.

Resolves #8528 Related #8331

How has this been tested?

Table test covering the agent-detected and no-agent cases, and asserting version, platform and architecture. The payload assertions in the shared telemetry tests run against a real httptest server and check the encoded body, so these properties are verified on the wire rather than through a mock.

Verified end-to-end against a local instance: every command carries coding_agent and cli_version in the track_event body.

Edited by Kai Armstrong

Merge request reports

Loading
Loading