S03 spec: observability tracing framework contract
Context
Spawned by the narrowing of S03 to logging-only on !56 (merged). The tracing framework was cut from S03 to keep the narrowing focused. This issue tracks the follow-up spec that picks it up.
The trace-correlation enrichment wrapper stays in S03 (it is logging behavior). This spec covers the rest of the tracing surface.
Scope
Define:
- The LabKit v2
traceintegration: OTLP/HTTP exporter, sampler, W3Ctraceparentpropagator set globally viaotel.SetTextMapPropagator. - Span naming conventions (low-cardinality, never embed user-provided values).
- Service-set OTel semantic-convention attributes (semconv v1.26.0) and the
artifactregistry.*custom attribute namespace. - The forbidden-attribute-values list.
- The four sanctioned async-context propagation patterns.
- Error recording via
span.RecordErrorandcodes.Error/codes.Unset. - Cross-service tracing bridge with the GitLab Ruby monolith (Jaeger
uber-trace-idtranslation). - The
TraceConfigproto message, defaults, and LabKit v2 mapping.
Source material
The pre-narrowing version of S03 at commit 5592b76, specifically:
- Lines 404-609:
### Tracingand all subsections (sampler/propagator, span naming, attributes, forbidden values, async context, error recording, cross-service bridge). - Lines 1035-1059: the
TraceConfigproto block.
Author treats those sections as starting material, not a frozen contract. Reviewer feedback on the original sections is in !56 (merged)'s history.
Related
- The trace-correlation enrichment wrapper survives in S03 (Logging Conventions). Until this spec ships and trace initialization is wired, no span is ever active in this service. Wide-event consumers must treat
trace_idandspan_idas nullable. - Sister follow-ups: metrics framework, readiness + internal listener.
- !56 (merged) (the narrowing MR).
Closure criterion
The framework spec ships and replaces the placeholder reference to this issue in:
docs/specs/S03-observability.mdSummary and Out of Scope.docs/dev/observability.mdcatalog header.