The problem
Each AHP client that instruments its own operation (request spans, message counters, reconnect and dropped-event metrics) has to name those spans, metrics, and attributes. There is no shared vocabulary across the Go, Rust, Swift, Kotlin, TypeScript, and .NET clients today. When one client emits ahp.client.messages.sent and another emits ahp_messages_sent, an operator running a fleet of mixed-language agents cannot write one OpenTelemetry dashboard or alert that works across all of them.
Why it belongs at the protocol layer
The self-instrumentation names are an interop surface, the same way the wire types are. They have to be byte-identical across clients or downstream OpenTelemetry tooling fragments, and that requirement is what makes the name contract a protocol concern rather than a per-client detail. The instrumentation code stays per-client and idiomatic; only the names are shared. This is separate from the existing "OpenTelemetry over AHP" channel (docs/specification/telemetry-channel.md), which carries OTel data over the protocol. This standardizes what each client emits about its own operation.
Proposed mechanism
A single source of truth, types/telemetry/registry.ts (string enums for spans, metrics, and attributes, plus a units map), consumed by the existing scripts/generate-*.ts codegen to emit a generated name holder per client. It is the same shape the protocol enums already use, with a generated-output freshness gate so the holders cannot drift.
Proof of concept
Two reference adopters, both with recorder-based emission tests that prove the names actually fire: the .NET client (request spans plus eight metrics via ActivitySource and Meter) in #206, and the Rust client (the same metrics through the metrics facade) in #237.
The decision
Whether AHP wants a spec'd cross-client self-instrumentation names contract, and if so the initial scope (which spans, metrics, and attributes) and which clients adopt first. I'll shape it to whatever scope you bless and keep #237 a draft until then.
The problem
Each AHP client that instruments its own operation (request spans, message counters, reconnect and dropped-event metrics) has to name those spans, metrics, and attributes. There is no shared vocabulary across the Go, Rust, Swift, Kotlin, TypeScript, and .NET clients today. When one client emits
ahp.client.messages.sentand another emitsahp_messages_sent, an operator running a fleet of mixed-language agents cannot write one OpenTelemetry dashboard or alert that works across all of them.Why it belongs at the protocol layer
The self-instrumentation names are an interop surface, the same way the wire types are. They have to be byte-identical across clients or downstream OpenTelemetry tooling fragments, and that requirement is what makes the name contract a protocol concern rather than a per-client detail. The instrumentation code stays per-client and idiomatic; only the names are shared. This is separate from the existing "OpenTelemetry over AHP" channel (
docs/specification/telemetry-channel.md), which carries OTel data over the protocol. This standardizes what each client emits about its own operation.Proposed mechanism
A single source of truth,
types/telemetry/registry.ts(string enums for spans, metrics, and attributes, plus a units map), consumed by the existingscripts/generate-*.tscodegen to emit a generated name holder per client. It is the same shape the protocol enums already use, with a generated-output freshness gate so the holders cannot drift.Proof of concept
Two reference adopters, both with recorder-based emission tests that prove the names actually fire: the .NET client (request spans plus eight metrics via
ActivitySourceandMeter) in #206, and the Rust client (the same metrics through themetricsfacade) in #237.The decision
Whether AHP wants a spec'd cross-client self-instrumentation names contract, and if so the initial scope (which spans, metrics, and attributes) and which clients adopt first. I'll shape it to whatever scope you bless and keep #237 a draft until then.