Semconv Drift
A Kaggle benchmark for OpenTelemetry

Do AI models write telemetry code with names the spec already retired?

OpenTelemetry renames attributes and metrics between releases. The old names still compile, still export and still store, so nothing fails until a dashboard quietly stops matching. Semconv Drift measures how often models write them, graded in code against every release of the spec. No AI judge.

…models tested
…graded answers
1,563names in the ground truth
26spec releases, v1.21.0 to v1.44.0

Leaderboard

Overall is the average of a model's task scores, the same rule as the Kaggle leaderboard. Click a column to sort. "Retired" counts retired names written across the 12 Write requests. Hover a score for its 95% Wilson interval.

# Model Overall Write Know Fix Write + hint Retired Cost
Loading results…

Findings

Every chart is generated from the Kaggle runs by charts.py. Numbers update with each analysis run.

Leaderboard chart: overall score per model with Write, Know and Fix shown as markers
Write is where most models lose ground. Knowing the current name when asked is not the same as writing it in code.

It told me the new name, then wrote the old one

Retired names each model wrote although it named the correct replacement in the Know task
Same model, same name. Asked directly, the model gives the current name. Asked for code, it writes the retired one.

The retired names are old, not new

Most retired names that models write were retired more than a year before the run. This is stale training data, not a fast-moving spec.

Histogram of how long ago each retired name was retired
Years since the spec retired each name a model wrote.
The most frequently written retired names
db.system leads: renamed to db.system.name in v1.30.0 (January 2025).

The half fix

Outcomes when models were asked to modernize rpc.client.duration
Asked to modernize rpc.client.duration (milliseconds), most models converted the values to seconds but kept the retired name. The result matches neither spec version: queries on the old name read values 1,000 times too small, and queries on the new name, rpc.client.call.duration, find nothing.

Generations and price

Older and newer model in the same family
In every family pair, the newer model drifts less.
Cost of the full run against overall score
Above the bottom of the table, spending more does not reliably buy current names.

Every case, every model

Heatmap of pass and fail for each model and case
Green is correct, red is wrong. W: Write, K: Know, F: Fix.

How it works

Four tasks on Kaggle Benchmarks. Every answer is graded by grader.py against the spec's own release history, so every score is reproducible.

Write 12 cases

Instrument everyday code: HTTP server and client, Postgres, Redis, Kafka, gRPC, metrics and resources, in Python, Go and TypeScript. Clean only if every name is current and time units are right.

Open task

Know 22 cases

What replaced a retired name. Includes span-kind traps, silently dropped metrics and two controls whose right answer is "unchanged".

Open task

Fix 8 cases

Modernize old snippets, including real code from redis/go-redis. Units must be converted, and an enum value trap checks values as well as keys.

Open task

Write with version hint 12 cases

The Write requests plus one sentence naming the current spec version. The difference measures what one line of context buys.

Open task

Grading rules

Ground truth

Exported from the public Attrition dataset, built from every tagged release of open-telemetry/semantic-conventions.