Skip to content
CorePart 1 · Foundations — how SpanForge works

Chapter 1.5

Traces, spans, and the context propagation model

~15 min read

Traces and Spans: From Events to Structure

Event envelopes capture individual facts. Traces explain how those facts relate.

A trace represents the full lifecycle of a request. A span represents a unit of work within that lifecycle.

The earlier contract request produces a trace that can be represented as:

Trace: Contract Analysis Request
│
├── Span: Build Prompt
│   └── attributes: {template: "risk_summary_v2"}
│
├── Span: Retrieval Query
│   └── attributes: {index: "contracts_v1", top_k: 5}
│
├── Span: LLM Completion
│   └── attributes: {model: "gpt-4", prompt_tokens: 820, latency_ms: 1340}
│
├── Span: Guardrail Check
│   └── attributes: {policy: "hallucination_v1", result: "failed"}
│
└── Span: Response Formatting

Each span records timing and attributes. More importantly, each span is connected through a parent-child relationship, forming a structured execution tree.

Context propagation ensures this structure persists across boundaries. As execution moves between threads or services, trace identifiers are carried forward, preserving continuity.

When a span completes, it is deterministically converted into an event envelope. Every span produces exactly one envelope. This one-to-one mapping ensures that execution and recorded data remain perfectly aligned.

Traces provide structure. Envelopes provide persistence. Together, they form a complete, queryable representation of execution.