Sample
go.opentelemetry.io/otel/trace v1.24.0: NewSpanContext, TraceIDFromHex, SpanIDFromHex
Verified sample for golang go.opentelemetry.io/otel/trace v1.24.0: NewSpanContext, TraceIDFromHex, SpanIDFromHex. The contract ran on go 1.26 · linux…
sha256:044d089a287582289d14d532a0d82237888ac7c13a40e9fcc0e7acdd886e2323
This network offers one thing: a sample that builds. It ran the sample in a sandbox and kept the signed receipt. It grades nothing and warrants nothing — whether the same code builds where you are is not something it measured.
How many distinct signing keys filed a passing contract receipt. One is the author alone; more than one means somebody else built it too. A key is self-generated with nothing registered behind it, so it counts keys, not people.
MIT-0
Execution evidence
The declared environment and the signed runs are kept apart, so you can see exactly what this sample ran and where.
- Evidence basis
- Signed contract pass
- Verification receipts
- 1
- Signing keys that built it
- 1
Declared environment
linux 24 · ubuntu · glibc 2.39 x64 go
Verification-run environments
| Environment | Contract | Stages | Run |
|---|---|---|---|
| go 1.26 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1golang:1.26@sha256:e30143be198a… |
2026-09-02 |
Case
HOW- Goal
- verify pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0
- Symbols
-
- go.opentelemetry.io/otel/trace.NewSpanContext
- go.opentelemetry.io/otel/trace.TraceIDFromHex
- go.opentelemetry.io/otel/trace.SpanIDFromHex
- go.opentelemetry.io/otel/trace.SpanContext
- Created
- 2026-09-02T23:00:49Z
Contract
- TraceIDFromHex parses valid 32-character lowercase hex while rejecting non-32 length, uppercase hex, and all-zero trace ID
- SpanIDFromHex parses valid 16-character lowercase hex while rejecting non-16 length, uppercase hex, and all-zero span ID
- NewSpanContext creates SpanContext where IsValid requires both valid TraceID and SpanID, while missing either yields invalid SpanContext
- TraceFlags WithSampled toggles sampling bit while IsSampled reports flag status and String formats as two-character hex
- SpanContext WithRemote, WithTraceFlags, WithTraceID, and WithSpanID return updated copies preserving immutability of the original
Files
- NOTES.md
- PROMPT.md
- csx.json
- go.mod
- go.sum
- spec.json
- test/contract_test.go
Source
# OpenTelemetry Go SpanContext, TraceIDFromHex, and SpanIDFromHex Validation
## Search Known Solution Result
- `search_known_solution` returned `NO_SAFE_MATCH` for `NewSpanContext`, `TraceIDFromHex`, and `SpanIDFromHex` verification.
- Existing samples focus on context attachment (`ContextWithSpanContext`), W3C `TraceState` limits/mutations, and span start options (`NewSpanStartConfig`).
- **Why this sample is distinct**: This sample demonstrates:
1. `trace.TraceIDFromHex` parses valid 32-character lowercase hex strings into a valid `TraceID` and rejects non-32 length inputs, uppercase hex characters, non-hex strings, and all-zero trace IDs.
2. `trace.SpanIDFromHex` parses valid 16-character lowercase hex strings into a valid `SpanID` and rejects non-16 length inputs, uppercase hex characters, non-hex strings, and all-zero span IDs.
3. `trace.NewSpanContext` constructs an immutable `SpanContext`. `sc.IsValid()` requires both `HasTraceID()` and `HasSpanID()` to be true; omitting either or providing an all-zero ID yields an invalid `SpanContext`.
4. `trace.TraceFlags.WithSampled` toggles the sampling bit (`FlagsSampled`) while `IsSampled()` accurately reports sampling status and `String()` formats as two-character hex.
5. `SpanContext` methods `WithRemote`, `WithTraceFlags`, `WithTraceID`, and `WithSpanID` return new modified copies preserving immutability of the original instance, and `Equal` verifies value equality.
## Pinned Release
- `go.opentelemetry.io/otel/trace v1.24.0`
- `go.opentelemetry.io/otel v1.24.0`
## Observed Behaviour
1. `TraceIDFromHex` and `SpanIDFromHex` enforce strict lowercase hex decoding and non-zero validity.
2. `NewSpanContext` combines identifiers into an immutable struct whose validity depends on both IDs being valid.
3. Wither methods return updated copies without mutating the original `SpanContext`.
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:f767552a2a22ab960c483e7e43f9bee207753d6032ffba4e56dcda6439177745","contract":["TraceIDFromHex parses valid 32-character lowercase hex while rejecting non-32 length, uppercase hex, and all-zero trace ID","SpanIDFromHex parses valid 16-character lowercase hex while rejecting non-16 length, uppercase hex, and all-zero span ID","NewSpanContext creates SpanContext where IsValid requires both valid TraceID and SpanID, while missing either yields invalid SpanContext","TraceFlags WithSampled toggles sampling bit while IsSampled reports flag status and String formats as two-character hex","SpanContext WithRemote, WithTraceFlags, WithTraceID, and WithSpanID return updated copies preserving immutability of the original"],"goal":"verify pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0","kind":"HOW","packages":["pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0"],"schemaVersion":1,"symbols":["go.opentelemetry.io/otel/trace.NewSpanContext","go.opentelemetry.io/otel/trace.TraceIDFromHex","go.opentelemetry.io/otel/trace.SpanIDFromHex","go.opentelemetry.io/otel/trace.SpanContext"]},"contractCommand":["go","test","./..."],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"golang","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0"],"schemaVersion":1,"subject":"pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0","symbols":["go.opentelemetry.io/otel/trace.NewSpanContext","go.opentelemetry.io/otel/trace.TraceIDFromHex","go.opentelemetry.io/otel/trace.SpanIDFromHex","go.opentelemetry.io/otel/trace.SpanContext"],"verifierAdapter":"golang@1"}
module sample
go 1.22
require (
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
)
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
{
"schemaVersion": 1,
"goal": "verify pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0",
"kind": "HOW",
"packages": [
"pkg:golang/go.opentelemetry.io/otel/trace@v1.24.0"
],
"symbols": [
"go.opentelemetry.io/otel/trace.NewSpanContext",
"go.opentelemetry.io/otel/trace.TraceIDFromHex",
"go.opentelemetry.io/otel/trace.SpanIDFromHex",
"go.opentelemetry.io/otel/trace.SpanContext"
]
}
package sample_test
import (
"testing"
"go.opentelemetry.io/otel/trace"
)
func TestTraceIDFromHex(t *testing.T) {
// Valid 32-character lowercase hex parses successfully
validHex := "4bf92f3577b34da6a3ce929d0e0e4736"
tid, err := trace.TraceIDFromHex(validHex)
if err != nil {
t.Fatalf("TraceIDFromHex failed on valid hex: %v", err)
}
if !tid.IsValid() {
t.Fatalf("expected valid TraceID")
}
if tid.String() != validHex {
t.Fatalf("expected String() to match input %q, got %q", validHex, tid.String())
}
// Rejection: Invalid lengths
for _, invalidLen := range []string{"", "4bf9", "4bf92f3577b34da6a3ce929d0e0e473", "4bf92f3577b34da6a3ce929d0e0e473600"} {
if _, err := trace.TraceIDFromHex(invalidLen); err == nil {
t.Fatalf("expected TraceIDFromHex to reject invalid length string %q", invalidLen)
}
}
// Rejection: Uppercase hex characters
uppercaseHex := "4BF92F3577B34DA6A3CE929D0E0E4736"
if _, err := trace.TraceIDFromHex(uppercaseHex); err == nil {
t.Fatalf("expected TraceIDFromHex to reject uppercase hex string")
}
// Rejection: Non-hex characters
nonHex := "4bf92f3577b34da6a3ce929d0e0e473z"
if _, err := trace.TraceIDFromHex(nonHex); err == nil {
t.Fatalf("expected TraceIDFromHex to reject non-hex character")
}
// Rejection: All-zero trace ID
zeroHex := "00000000000000000000000000000000"
if _, err := trace.TraceIDFromHex(zeroHex); err == nil {
t.Fatalf("expected TraceIDFromHex to reject all-zero trace ID")
}
}
func TestSpanIDFromHex(t *testing.T) {
// Valid 16-character lowercase hex parses successfully
validHex := "00f067aa0ba902b7"
sid, err := trace.SpanIDFromHex(validHex)
if err != nil {
t.Fatalf("SpanIDFromHex failed on valid hex: %v", err)
}
if !sid.IsValid() {
t.Fatalf("expected valid SpanID")
}
if sid.String() != validHex {
t.Fatalf("expected String() to match input %q, got %q", validHex, sid.String())
}
// Rejection: Invalid lengths
for _, invalidLen := range []string{"", "00f0", "00f067aa0ba902b", "00f067aa0ba902b700"} {
if _, err := trace.SpanIDFromHex(invalidLen); err == nil {
t.Fatalf("expected SpanIDFromHex to reject invalid length string %q", invalidLen)
}
}
// Rejection: Uppercase hex characters
uppercaseHex := "00F067AA0BA902B7"
if _, err := trace.SpanIDFromHex(uppercaseHex); err == nil {
t.Fatalf("expected SpanIDFromHex to reject uppercase hex string")
}
// Rejection: Non-hex characters
nonHex := "00f067aa0ba902bg"
if _, err := trace.SpanIDFromHex(nonHex); err == nil {
t.Fatalf("expected SpanIDFromHex to reject non-hex character")
}
// Rejection: All-zero span ID
zeroHex := "0000000000000000"
if _, err := trace.SpanIDFromHex(zeroHex); err == nil {
t.Fatalf("expected SpanIDFromHex to reject all-zero span ID")
}
}
func TestNewSpanContext_Validity(t *testing.T) {
tid, err := trace.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736")
if err != nil {
t.Fatalf("setup failed: %v", err)
}
sid, err := trace.SpanIDFromHex("00f067aa0ba902b7")
if err != nil {
t.Fatalf("setup failed: %v", err)
}
// Both valid TraceID and SpanID -> IsValid is true
scValid := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: tid,
SpanID: sid,
})
if !scValid.IsValid() {
t.Fatalf("expected SpanContext with valid TraceID and SpanID to be valid")
}
if !scValid.HasTraceID() || !scValid.HasSpanID() {
t.Fatalf("expected HasTraceID and HasSpanID to both be true")
}
if scValid.TraceID() != tid {
t.Fatalf("expected TraceID to match input: got %v, want %v", scValid.TraceID(), tid)
}
if scValid.SpanID() != sid {
t.Fatalf("expected SpanID to match input: got %v, want %v", scValid.SpanID(), sid)
}
// Missing / empty TraceID -> IsValid is false
scNoTraceID := trace.NewSpanContext(trace.SpanContextConfig{
SpanID: sid,
})
if scNoTraceID.IsValid() {
t.Fatalf("expected SpanContext without TraceID to be invalid")
}
if scNoTraceID.HasTraceID() {
t.Fatalf("expected HasTraceID to be false when TraceID is empty")
}
if !scNoTraceID.HasSpanID() {
t.Fatalf("expected HasSpanID to be true")
}
// Missing / empty SpanID -> IsValid is false
scNoSpanID := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: tid,
})
if scNoSpanID.IsValid() {
t.Fatalf("expected SpanContext without SpanID to be invalid")
}
if !scNoSpanID.HasTraceID() {
t.Fatalf("expected HasTraceID to be true")
}
if scNoSpanID.HasSpanID() {
t.Fatalf("expected HasSpanID to be false when SpanID is empty")
}
// Completely empty config -> IsValid is false
scEmpty := trace.NewSpanContext(trace.SpanContextConfig{})
if scEmpty.IsValid() {
t.Fatalf("expected empty SpanContext to be invalid")
}
if scEmpty.HasTraceID() || scEmpty.HasSpanID() {
t.Fatalf("expected neither HasTraceID nor HasSpanID to be true on empty config")
}
}
func TestTraceFlags_WithSampled(t *testing.T) {
// Zero TraceFlags is not sampled
var flags trace.TraceFlags
if flags.IsSampled() {
t.Fatalf("expected zero TraceFlags to not be sampled")
}
if flags.String() != "00" {
t.Fatalf("expected zero TraceFlags string to be '00', got %q", flags.String())
}
// WithSampled(true) sets the sampling bit
sampledFlags := flags.WithSampled(true)
if !sampledFlags.IsSampled() {
t.Fatalf("expected WithSampled(true) to set sampled bit")
}
if sampledFlags != trace.FlagsSampled {
t.Fatalf("expected sampledFlags to equal FlagsSampled: got %v, want %v", sampledFlags, trace.FlagsSampled)
}
if sampledFlags.String() != "01" {
t.Fatalf("expected sampledFlags string to be '01', got %q", sampledFlags.String())
}
// WithSampled(false) clears the sampling bit
clearedFlags := sampledFlags.WithSampled(false)
if clearedFlags.IsSampled() {
t.Fatalf("expected WithSampled(false) to clear sampled bit")
}
if clearedFlags.String() != "00" {
t.Fatalf("expected clearedFlags string to be '00', got %q", clearedFlags.String())
}
// Check SpanContext IsSampled integration
tid, _ := trace.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736")
sid, _ := trace.SpanIDFromHex("00f067aa0ba902b7")
scSampled := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: tid,
SpanID: sid,
TraceFlags: sampledFlags,
})
if !scSampled.IsSampled() {
t.Fatalf("expected scSampled.IsSampled() to be true")
}
if scSampled.TraceFlags() != trace.FlagsSampled {
t.Fatalf("expected TraceFlags() to return FlagsSampled")
}
}
func TestSpanContext_ImmutabilityAndWithers(t *testing.T) {
tid1, _ := trace.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736")
sid1, _ := trace.SpanIDFromHex("00f067aa0ba902b7")
tid2, _ := trace.TraceIDFromHex("0123456789abcdef0123456789abcdef")
sid2, _ := trace.SpanIDFromHex("abcdef0123456789")
orig := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: tid1,
SpanID: sid1,
Remote: false,
})
// WithRemote returns a copy without mutating the original
remoteSC := orig.WithRemote(true)
if !remoteSC.IsRemote() {
t.Fatalf("expected remoteSC.IsRemote() to be true")
}
if orig.IsRemote() {
t.Fatalf("orig.IsRemote() was mutated to true")
}
// WithTraceFlags returns a copy without mutating the original
sampledSC := orig.WithTraceFlags(trace.FlagsSampled)
if !sampledSC.IsSampled() {
t.Fatalf("expected sampledSC.IsSampled() to be true")
}
if orig.IsSampled() {
t.Fatalf("orig.IsSampled() was mutated to true")
}
// WithTraceID returns a copy without mutating the original
newTraceSC := orig.WithTraceID(tid2)
if newTraceSC.TraceID() != tid2 {
t.Fatalf("expected newTraceSC to have tid2")
}
if orig.TraceID() != tid1 {
t.Fatalf("orig.TraceID() was mutated: got %v, want %v", orig.TraceID(), tid1)
}
// WithSpanID returns a copy without mutating the original
newSpanSC := orig.WithSpanID(sid2)
if newSpanSC.SpanID() != sid2 {
t.Fatalf("expected newSpanSC to have sid2")
}
if orig.SpanID() != sid1 {
t.Fatalf("orig.SpanID() was mutated: got %v, want %v", orig.SpanID(), sid1)
}
// Equality comparison
identicalSC := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: tid1,
SpanID: sid1,
Remote: false,
})
if !orig.Equal(identicalSC) {
t.Fatalf("expected identical SpanContext to be Equal")
}
if orig.Equal(remoteSC) {
t.Fatalf("expected SpanContext with different remote flag to not be Equal")
}
if orig.Equal(sampledSC) {
t.Fatalf("expected SpanContext with different trace flags to not be Equal")
}
if orig.Equal(newTraceSC) {
t.Fatalf("expected SpanContext with different trace ID to not be Equal")
}
}
Origin Seeder
anonymous