OpenTelemetry → ISNAD mapping¶
isnad ingest --otlp grades an existing OpenTelemetry GenAI trace as an isnād.
This documents the span→narrator mapping and — just as important — what it
can't do.
The mapping¶
| OTel | ISNAD |
|---|---|
span with gen_ai.response.model / gen_ai.request.model |
transmitter, narrator_id = model:<model> |
span with only gen_ai.operation.name |
transmitter, narrator_id = <operation> |
span with no gen_ai.* attribute (DB, HTTP, …) |
not a transmitter — skipped |
startTimeUnixNano order |
transmission order (who handled it, in order) |
last transmitter's gen_ai.completion |
the claim text (if present) |
The chain is graded weakest-link over the registry grades, exactly like a
hand-built isnād. An ungraded transmitter caps at ḍaʿīf by default
(--lenient caps at ḥasan instead).
Honest limits (the important part)¶
-
The GenAI conventions are in Development status — attribute names may change. The parser is tolerant (missing attributes → skipped), but the mapping should be re-checked against the current spec before relying on it.
-
OTel spans do not carry the claim text. The conventions standardise model/token/latency, not output content. The isnād (transmission chain) is fully reconstructable; the matn (claim) is only available if a span emits the legacy
gen_ai.completionattribute. When it's absent,isnad ingestreportsclaim_text: nulland grades the chain only — content criticism cannot run without the claim. -
Grades are operator-assigned. Ingesting a trace looks models up in the registry; it does not auto-grade them. Seed grades first (
isnad seed), or every transmitter reads as UNGRADED → ḍaʿīf. -
This is the inverse of #47. #47 proposes emitting OTel spans from the callback (ISNAD → OTel, requiring ISNAD's format). This ingests OTel spans into ISNAD (OTel → ISNAD, zero ISNAD-format adoption).
Example¶
isnad seed <<'EOF'
ISNAD_SEED_CONFIG='[{"narrator_id":"model:gpt-4","domain":"general","grade":"acceptable"}]'
EOF
isnad ingest --otlp trace.json
{
"trace_id": "abc123",
"transmitter_count": 2,
"chain": [
{"narrator_id": "retrieve", "grade": "ungraded", "span_name": "retrieve docs", "model": null},
{"narrator_id": "model:gpt-4", "grade": "acceptable", "span_name": "chat gpt-4", "model": "gpt-4"}
],
"chain_grade": "daif",
"weakest_link": "retrieve",
"claim_text": "F=ma"
}