OpenTelemetry GenAI Semantic Conventions: Asqav Receipt Mapping

OpenTelemetry GenAI semantic conventions define the de-facto schema for observing LLM and agent operations in distributed systems. They tell you what happened and when. An Asqav compliance receipt records the same action in a signed, externally-anchored envelope that a third party can verify offline without trusting the operator.

This page maps OTel GenAI span attributes to Asqav receipt fields so teams running OTel instrumentation can understand what the receipt adds, and so compliance engineers can correlate a receipt to its matching OTel span.

OTel GenAI attributes on this page are drawn from the OpenTelemetry GenAI Semantic Conventions specification, maintained at github.com/open-telemetry/semantic-conventions-genai. Attribute names (gen_ai.operation.name, gen_ai.provider.name, gen_ai.request.model, gen_ai.response.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, gen_ai.tool.name, gen_ai.conversation.id, gen_ai.response.id, gen_ai.response.finish_reasons, gen_ai.tool.call.id) are cited verbatim from that specification.

Source: OpenTelemetry GenAI Semantic Conventions, https://github.com/open-telemetry/semantic-conventions-genai

What OTel gives you vs what a receipt adds

OTel telemetry is mutable, operator-held, and intended for live observability. An Asqav receipt is:

OTel gives you mutable observability. The receipt gives you a signed, externally-anchored record of the same action that a third party can verify offline. They are complementary, not competing.

Trace correlation

Asqav carries a trace_correlation capability (listed in /.well-known/governance.json). You can embed the OTel trace_id and span_id into the receipt's action_id or as a producer-asserted field, so the signed receipt and the OTel span are linked by the same identifiers. This lets an incident responder move from an OTel trace in a backend like Jaeger or Tempo directly to the signed receipt covering that span, or vice versa.

The otel_span_export capability (also in governance.json) means Asqav can export receipt events as OTel spans to an OTLP-compatible collector, keeping both signals in the same observability pipeline.

Field-by-field mapping: inference spans

The table below maps OTel inference span attributes (gen_ai.inference.client span kind) to their corresponding Asqav receipt fields.

OTel attribute OTel meaning Asqav receipt field What the receipt adds
gen_ai.operation.name Name of the operation (e.g. chat, text_completion) action_type (e.g. llm:egress) Signed into the receipt envelope; cannot be altered post-issuance
gen_ai.provider.name Provider identifier (e.g. openai, anthropic) Producer-asserted field in the signed payload Binding at signing time; verifier can confirm the provider claim was not changed after the fact
gen_ai.request.model Model name sent in the request Producer-asserted field in the signed payload Proves which model was requested at T; authored_by.model_id and authored_by.model_version bind model identity on code-authorship receipts
gen_ai.response.model Actual model that generated the response authored_by.model_id / authored_by.model_version (on applicable receipt types) authored_by.attestation_source is required whenever a model id is asserted, so the value is never read as Asqav-verified attribution
gen_ai.usage.input_tokens Tokens consumed in the prompt Producer-asserted field in the signed payload Token counts are recorded as producer-asserted telemetry; the signed envelope proves the count was not altered
gen_ai.usage.output_tokens Tokens generated in the response Producer-asserted field in the signed payload Same tamper-evidence property as input tokens
gen_ai.response.id Unique completion identifier returned by the provider action_id or producer-asserted correlation field Binding at signing time; lets a verifier link the receipt to the provider's completion record
gen_ai.response.finish_reasons Why the model stopped generating (e.g. stop, length) Producer-asserted field in the signed payload Proves the termination reason was asserted at T
gen_ai.conversation.id Conversation or session identifier session_id / producer-asserted field Sessions chain receipts into a traceable audit trail; session identifiers are signed into each receipt
gen_ai.request.temperature, gen_ai.request.top_p, gen_ai.request.max_tokens Sampling parameters Producer-asserted fields in the signed payload Proves the inference configuration in use at signing time

Field-by-field mapping: tool execution spans

The table below maps OTel tool execution span attributes (execute_tool span kind) to Asqav receipt fields.

OTel attribute OTel meaning Asqav receipt field What the receipt adds
gen_ai.tool.name Name of the tool being executed action_type (e.g. tool:search, function:call) + tool_fingerprint tool_fingerprint is a 32-hex SHA-256 over tool_name|schema_canonical_json|module_path; it surfaces registry-shadow drift and naming collisions
gen_ai.tool.call.id Tool call identifier action_id or producer-asserted correlation field Binding at signing time
gen_ai.tool.description Tool description tool_fingerprint (derived from schema) The fingerprint covers the tool's schema, not free-text description
gen_ai.tool.type Tool type (function, extension, datastore) action_type namespace (e.g. function:call, data:read) Controlled vocabulary in the receipt enforces consistent classification
gen_ai.tool.call.result Tool output result_digest (sha256:<64 hex>) SHA-256 of the canonical-JSON tool response body; the receipt binds the exact output, not just a label

The gap OTel cannot fill

OTel spans live in the operator's telemetry backend. The operator controls the backend, can modify or delete spans, and holds the sole copy. That is fine for live observability. It is not sufficient when a regulator, auditor, or counterparty asks: "prove this agent acted within its mandate at time T, and prove you have not altered the record."

Asqav provides verifiable evidence for that gap with four properties OTel does not provide:

  1. Cryptographic signing (ML-DSA-65, FIPS 204): the receipt signature covers a canonical hash of all fields. Any field change breaks the signature.
  2. External time anchoring (RFC 3161 + OpenTimestamps): a witness holds an inclusion proof tying the receipt to an external chain; the operator cannot back-date the timestamp.
  3. Operator-independent verification: the public key is at /.well-known/jwks.json; any party can verify without contacting Asqav and without trusting the operator.
  4. Chain of custody: receipts chain via a hash-chain link; the full audit trail can be replayed and each link verified.

Capture topology for OTel-instrumented systems

Teams that already instrument with OTel can add the receipt layer without replacing their telemetry pipeline. The passive_telemetry capture topology (capture_topology field in governance.json) lets Asqav observe the same events the OTel SDK observes, emit a signed receipt, and forward the OTel span to the existing OTLP collector. The two pipelines run in parallel.

The in_process_sdk topology is the default for Python and TypeScript agents; the OTel SDK and the Asqav SDK can both run in the same process and share the trace context.

What Asqav does not do

Asqav does not replace an OTel collector, an observability backend, or a tracing library. It does not validate OTel attribute values, re-compute token counts, or verify that a gen_ai.response.model field matches what the provider actually used. Producer-asserted fields in a receipt carry the same trust level as OTel attributes: the producer declared them. The difference is that Asqav's signing step means that declaration cannot be changed after issuance without breaking the signature.

Related documentation