W3C Trace Context Propagation
The observability tracer and agent_trace spans carry no IDs, so a span
on one side of an HTTP call could not be correlated with the work it triggered
on the other. This adds the W3C Trace Context standard — generate, parse, and
propagate traceparent / tracestate headers so spans, logs, and
downstream services all share one trace and span lineage.
Pure standard library (os / re); imports no PySide6. ID generation
takes an injectable RNG, so trace and span IDs are deterministic under test.
Headless API
from je_auto_control import (
new_root_context, child_context, inject_context, extract_context,
parse_traceparent, format_traceparent,
)
# Start a trace and propagate it onto an outgoing request:
ctx = new_root_context()
headers = inject_context({"accept": "application/json"}, ctx)
# headers["traceparent"] == "00-<32 hex>-<16 hex>-01"
# On the receiving side, continue the same trace:
parent = extract_context(request_headers)
if parent is not None:
span = child_context(parent) # same trace_id, new span_id
SpanContext is the immutable (trace_id, span_id, trace_flags,
tracestate) tuple. new_root_context mints a fresh trace; child_context
keeps the trace id and inherited state but allocates a new span id.
parse_traceparent / format_traceparent round-trip the version-00
header (rejecting bad versions, malformed or all-zero IDs with
TraceContextError); parse_tracestate / format_tracestate handle the
vendor list. inject_context writes the headers; extract_context reads
them back (case-insensitively).
Executor commands
AC_trace_inject propagates a context onto outgoing headers — with a
traceparent it derives a child of that parent, otherwise it starts a fresh
root — and returns {headers, traceparent, trace_id, span_id}.
AC_trace_extract reads a context back out of request headers and returns
{context} (or null when no traceparent is present). Both are exposed
as MCP tools (ac_trace_inject / ac_trace_extract) and as Script Builder
commands under Data.