Traces

Every job in Daslab leaves a trace — an OpenTelemetry trace, written with OpenInference semantic conventions for the LLM parts and a small daslab.* extension namespace for what OTel doesn't cover. The trace is the record: what ran, in what order, what it cost, what came back. The authored plan it executed is a program.

Every Daslab concept maps to an OTel field

Daslab conceptOTel / OpenInference field
Jobtrace (root span)
Callspan
Parent callparent_span_id
Tool nameattributes['daslab.tool']
Tool inputattributes['input.value'] (OpenInference)
Tool outputattributes['output.value'] (OpenInference)
LLM model + tokensattributes['llm.model'], llm.token_count.* (OpenInference)
Statusstatus.code (OK / ERROR)

Daslab extensions live under the daslab.* attribute namespace; everything else uses the existing OTel and OpenInference vocabularies.

Span names stay human-readable

OTLP requires span_id to be hex, so the human-readable label lives in OTel's standard span.namefetch_top_ids, summarize_digest, commit_release. External OTel UIs display span.name as the row label, so readable timelines come for free.

Any OTel backend can read a run

Traces feed into Phoenix, Langfuse, Datadog, Honeycomb, or Jaeger without translation — the export is standard OTLP. If your team already has an observability stack, Daslab's runs appear in it like any other service.

What's next

  • Programs — the authored side: what a run meant to do.
  • Jobs — what a single trace covers.
  • Audit — the query layer over what happened.
  • Commit chain — state history; the trace's sibling record.

Updated 2026-07-18