OpenTelemetry
Any agent already traced with the OpenTelemetry GenAI semantic conventions becomes a source. One trace becomes one decision record at assurance level observed.
The endpoint
Section titled “The endpoint”Stratl accepts OTLP over HTTP with JSON encoding at POST /v1/ingest/otlp/v1/traces, authenticated with an ingest key. Point a collector at it:
exporters: otlphttp/stratl: traces_endpoint: https://api.stratl.ai/v1/ingest/otlp/v1/traces encoding: json headers: Authorization: Bearer sk_stratl_...
service: pipelines: traces: exporters: [otlphttp/stratl]What maps automatically
Section titled “What maps automatically”| Span | Becomes |
|---|---|
The root span, or the span with gen_ai.operation.name = invoke_agent |
The decision; gen_ai.agent.id or gen_ai.agent.name is the agent |
gen_ai.input.messages on the root |
An input event, fingerprinted |
Spans with operation chat, generate_content or similar |
model_call events: provider from gen_ai.provider.name (or gen_ai.system), model from gen_ai.request.model, fingerprints of gen_ai.input.messages and gen_ai.output.messages when present, otherwise content: not_captured |
Operation execute_tool |
tool_call events with gen_ai.tool.name and fingerprints of the arguments and result; an error status becomes status: error |
Operation retrieve, or stratl.retrieval.source |
retrieval events |
Prompt and completion content, when present on spans, is fingerprinted and never stored in the record.
The attributes that make it evidence
Section titled “The attributes that make it evidence”Set these on the root span from your application. Without the subject, the decision is keyed by trace id and framework packs flag it as subject not known.
| Attribute | Purpose |
|---|---|
stratl.subject.type, stratl.subject.id |
The business subject (claim, applicant, order) |
stratl.policy.id, stratl.policy.version, stratl.policy.result, stratl.policy.rule |
A policy evaluation |
stratl.approval.required, stratl.approval.approver, stratl.approval.authority, stratl.approval.decision, stratl.approval.identity_provider |
A human approval; the approver becomes a human actor |
stratl.action.name, stratl.action.target, stratl.action.result |
The action that executed |
stratl.outcome.status, stratl.outcome.adverse, stratl.outcome.category |
The outcome for the subject |
stratl.retrieval.source, stratl.retrieval.doc_ids |
A retrieval, when the span is not already a GenAI retrieve operation |
Example, in Python with the OpenTelemetry API:
span.set_attributes({ "stratl.subject.type": "applicant", "stratl.subject.id": "72819", "stratl.policy.id": "declines_require_second_review", "stratl.policy.version": "5", "stratl.policy.result": "human_required", "stratl.approval.approver": "r.okafor@lender.ng", "stratl.approval.authority": "credit_officer", "stratl.approval.decision": "approved", "stratl.action.name": "loan.decline", "stratl.action.target": "applicant/72819", "stratl.action.result": "executed", "stratl.outcome.adverse": True, "stratl.outcome.category": "credit_decline",})Idempotence
Section titled “Idempotence”The decision id is derived from the trace id, so re-exporting a trace never creates a second record. Records already in custody are returned unchanged.