Use span.context() for traceparent extraction; scope trait imports locally
Replace current_traceparent() (thread-local OTEL context) with
traceparent_from_span(span) using OpenTelemetrySpanExt::context(),
matching the set_parent pattern on the receiving side.

Move the anonymous trait imports (TextMapPropagator, TracerProvider,
OpenTelemetrySpanExt) from file scope to the individual functions that
need them, since they're invisible by name and only used in one place each.

https://claude.ai/code/session_01Tbgz29e8A9KS4Bh94skkFX
change
commit b559e244757dea07c90eaa9cd29f1c473347aacf
author Claude <noreply@anthropic.com>
date
parent 224ecfb8
diff --git a/quire-core/src/telemetry.rs b/quire-core/src/telemetry.rs
index e3d14df..5b77c0b 100644
--- a/quire-core/src/telemetry.rs
+++ b/quire-core/src/telemetry.rs
@@ -4,9 +4,6 @@ use std::io::IsTerminal;
 use std::sync::Arc;
 
 use miette::IntoDiagnostic;
-use opentelemetry::propagation::TextMapPropagator as _;
-use opentelemetry::trace::TracerProvider as _;
-use tracing_opentelemetry::OpenTelemetrySpanExt as _;
 use tracing_subscriber::EnvFilter;
 use tracing_subscriber::Layer;
 use tracing_subscriber::layer::SubscriberExt;
@@ -201,11 +198,13 @@ impl Drop for TracingGuard {
     }
 }
 
-/// Extract the W3C traceparent for the currently active tracing span.
-/// Returns None when no OTEL span is active (e.g. no DSN, not yet entered a span).
-pub fn current_traceparent() -> Option<String> {
+/// Extract the W3C traceparent from a tracing span's OTEL context.
+/// Returns None when the span has no valid OTEL context (e.g. OTEL not initialised).
+pub fn traceparent_from_span(span: &tracing::Span) -> Option<String> {
+    use opentelemetry::propagation::TextMapPropagator as _;
+    use tracing_opentelemetry::OpenTelemetrySpanExt as _;
     let propagator = opentelemetry_sdk::propagation::TraceContextPropagator::new();
-    let cx = opentelemetry::Context::current();
+    let cx = span.context();
     let mut carrier = std::collections::HashMap::new();
     propagator.inject_context(&cx, &mut carrier);
     carrier.remove("traceparent")
@@ -214,6 +213,7 @@ pub fn current_traceparent() -> Option<String> {
 /// Decode a W3C traceparent string into an OTEL context suitable for
 /// passing to [`tracing_opentelemetry::OpenTelemetrySpanExt::set_parent`].
 pub fn context_from_traceparent(traceparent: &str) -> opentelemetry::Context {
+    use opentelemetry::propagation::TextMapPropagator as _;
     let propagator = opentelemetry_sdk::propagation::TraceContextPropagator::new();
     let mut carrier = std::collections::HashMap::new();
     carrier.insert("traceparent".to_string(), traceparent.to_string());
@@ -245,6 +245,7 @@ pub fn init_tracing(miette_layer: MietteLayer, fmt_mode: FmtMode) -> miette::Res
         }
     };
 
+    use opentelemetry::trace::TracerProvider as _;
     let provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
         .with_span_processor(sentry_opentelemetry::SentrySpanProcessor::new())
         .build();
diff --git a/quire-server/src/ci/mod.rs b/quire-server/src/ci/mod.rs
index d601d0a..e59511f 100644
--- a/quire-server/src/ci/mod.rs
+++ b/quire-server/src/ci/mod.rs
@@ -168,12 +168,11 @@ fn run_ref(ctx: &TriggerContext<'_>, pushed_at: jiff::Timestamp, push_ref: &Push
     let session = ApiSession::new(ctx.port);
 
     let span = tracing::info_span!("quire.ci.run", repo = %ctx.event_repo);
-    let _guard = span.enter();
-
     let traceparent = ctx
         .sentry_dsn
         .as_ref()
-        .and_then(|_| telemetry::current_traceparent());
+        .and_then(|_| telemetry::traceparent_from_span(&span));
+    let _guard = span.enter();
 
     sentry::with_scope(
         |scope| {