Open source / Developer preview

Make AI quality observable.

Quality signals on your original AI traces. Evaluate completed generation spans, keep their identity, and bring the results into your observability stack.

OTLP/HTTP JSON Node.js 22+ Apache-2.0

AI traces connect through a central gateway to quality charts.
01 / THE EXPORT PATHSame trace. More context.

01 Preserve trace identity

02 Make coverage visible

03 Calibrate before paging

The architecture

Your traces already tell a story.
Add the quality context.

OpenSpanGuard sits between an OpenTelemetry SDK and your collector. Evaluation happens during export, with the original trace IDs, span IDs, and timestamps preserved.

  1. 01 / CAPTURE

    Finish the generation

    Explicitly capture supported prompt and response content. An asynchronous SDK span processor exports completed spans without waiting for scoring on the generation path.

  2. 02 / ENRICH

    Evaluate in the gateway

    Eligible spans receive quality signals. Recognized content fields are removed before forwarding. Evaluation and delivery still add export latency.

  3. 03 / OBSERVE

    Use your existing stack

    Forward enriched traces to the collector. Prometheus scrapes gateway metrics; Grafana queries Prometheus and Tempo to connect quality with trace context.

OpenSpanGuard architecture: completed AI spans flow through the gateway to a collector and Tempo. Optional Jev evaluation, Prometheus scraping, Grafana queries, and Alertmanager routing are shown.
FIG. 01 From completed generation to observable qualityOpen full size ↗Editable .drawio ↓
Read the architecture as text

An AI agent ends a generation span. Its OpenTelemetry SDK asynchronously sends OTLP/HTTP JSON to OpenSpanGuard. The gateway can call Jev’s score and noul primitives when remote content has been explicitly authorized. It enriches exported spans, removes recognized content fields, and forwards to an OpenTelemetry Collector, which writes to Tempo.

Prometheus pulls the gateway’s metrics. Grafana queries Prometheus for metrics and Tempo for traces. Prometheus sends firing alerts to Alertmanager, which routes them to a webhook.

Raw content is present in incoming telemetry and process memory before redaction. Unrecognized custom fields can retain content. Application-side minimization and operator review are required.

A deliberate boundary

Remote Jev evaluation requires explicit content capture and OSG_ALLOW_REMOTE_CONTENT=true. Review what you send before enabling it. Read the integration guide ↗

Start with evidence

Clone. Run.
Follow a trace.

The offline demo checks the complete export path with synthetic scores and a loopback collector. After dependencies are installed, it needs no API key, Docker, or internet.

  • Original IDs and timestamps survive forwarding
  • Concurrent replay suppression and missing-content coverage
  • Content redaction and streaming event/token handling
  • A real OpenTelemetry HTTP/JSON exporter

Look for "result": "pass" in the final JSON.

TERMINAL / NODE.JS 22+
git clone https://github.com/alebgl77/openspanguard.git
cd openspanguard
npm ci
npm run build
npm run demo

The quality loop

A low score is a signal.
Context makes it useful.

The example relevance alert only fires when a cohort has enough evaluations, sufficient coverage, and sustained low mean relevance. The thresholds are starting values to calibrate for your workload.

≥ 20evaluations in 5 minutes
≥ 80%successful evaluation coverage
< 0.60mean relevance over 5 minutes
2 minall conditions held
Quality loop: cohort sample, coverage, and relevance conditions must hold for two minutes before Alertmanager routes a webhook. Low coverage and missing data are monitored separately.
FIG. 02 From cohort evidence to an actionable alertOpen full size ↗Editable .drawio ↓
Read the exact alert conditions

For each cohort, the low-relevance rule requires a 5-minute score-count increase of at least 20, a 5-minute successful-evaluation rate divided by the observed-generation-span rate of at least 0.8, and a score-sum rate divided by score-count rate below 0.6. All three conditions must hold for 2 minutes. Prometheus evaluates this rule group every 15 seconds.

The separate low-coverage rule requires coverage below 0.8 and at least 20 observed spans in 5 minutes, held for 2 minutes. Missing successful-evaluation series are treated as zero for observed cohorts. The informational no-data rule covers an unavailable or missing scrape target, zero span increase over 10 minutes, or a missing span counter, held for 2 minutes; a quiet service can trigger it.

Inspect the PromQL source ↗

Coverage is part of the result. Missing evaluations do not imply good quality. Coverage records the first observed outcome for each identity within a process-local window. A later retry can succeed without changing coverage for that window.

Scores have limits. Relevance does not prove factual correctness. Evaluator confidence is not truth, and the Jev noul answer is a rubric-specific nonsense probability, not a general hallucination probability. Read measurement limits ↗

Built in the open

A useful preview.
With visible boundaries.

Explore the implementation, reproduce the demo, and validate a canary before relying on these signals in production.

Available today

  • OTLP/HTTP JSON enrichment with preserved trace identity
  • Synthetic offline evaluation and opt-in remote Jev scoring
  • Bounded evaluation queue and process-local deduplication
  • Cohort quality, coverage, and export-health metrics
  • A local observability stack and example alert rules

Know the boundaries

  • JSON only; protobuf export is not supported
  • No disk queue or exactly-once delivery guarantee
  • Cache expiry, eviction, restarts, or replicas can repeat evaluation
  • Known content fields are removed; custom fields need review
  • Live Jev accuracy and latency have not been benchmarked

Help shape the next release

Bring your workload.
Make the evidence better.

Reproducible integrations, evaluation feedback, and clear bug reports help turn this preview into a stronger tool.