Repository navigation
Description
Summary
Revise the shared OpenTelemetry topology to reflect the context actually
available to JavaScript, Python, and Java SDK plugins.
When _X_AMZN_TRACE_ID contains a valid Root and Parent, Root defines the
canonical execution trace. Parent is the immediate remote span context
delivered to the Lambda runtime, but it is not guaranteed to identify the
durable backend server span directly. Lambda service/runtime spans can exist
between the durable backend attempt and the context exposed to the function.
The execution-scoped Workflow span must join the canonical trace, but either
of these parent edges is valid:
Workflowis a direct child of the remote context reconstructed from
_X_AMZN_TRACE_ID.Parent.Workflowis a child of the current valid ambient span when that span has
the same trace ID as_X_AMZN_TRACE_ID.Root.
Auto-instrumentation layers commonly create the second shape by extracting the
runtime header and starting a local handler span before the durable SDK runs.
OpenTelemetry SpanContext does not contain parent or ancestor pointers, so an
SDK cannot traverse from that ambient span to the propagated remote span.
Same-trace membership is the portable validation available to implementations.
Parent selection
With a valid Root and Parent:
- reuse
Rootas the canonical trace ID; - allow
Workflowto use either the reconstructed remote parent or the current
valid same-trace ambient span; - allow
Invocationto use the current valid same-trace ambient span, with the
reconstructed remote parent as fallback; - reject ambient context from another trace; and
- do not require the selected Workflow parent to be named
Durable Execution Attempt #1.
The SDK is not required to prove that a same-trace ambient span is a descendant
of the reconstructed remote parent because the OpenTelemetry API does not
expose the necessary ancestry.
When no valid remote Parent can be constructed:
- use the deterministic synthetic execution root;
- make it the common parent of
WorkflowandInvocation; and - ignore unrelated ambient context.
Sampling
Parent resolution and sampling resolution remain independent:
_X_AMZN_TRACE_ID state |
Canonical trace ID | Workflow parent | Sampling |
|---|---|---|---|
Valid Root, Parent, Sampled=1 |
Reuse Root |
Remote Parent or same-trace ambient span |
Preserve sampled |
Valid Root, Parent, Sampled=0 |
Reuse Root |
Remote Parent or same-trace ambient span |
Preserve not-sampled |
Valid Root, Parent, no valid Sampled |
Reuse Root |
Remote Parent or same-trace ambient span |
Do not invent an authoritative decision; selected-parent and configured sampler behavior applies |
Valid Root, missing or invalid Parent, explicit Sampled |
Reuse Root |
Synthetic execution root | Preserve the explicit decision |
Valid Root, missing or invalid Parent, no valid Sampled |
Reuse Root |
Synthetic execution root | Configured root sampler decides |
Missing or invalid Root |
Derive a stable trace ID from execution data | Synthetic execution root | Configured root sampler decides |
Only Sampled=0 and Sampled=1 are authoritative upstream decisions. If an
implementation selects an ambient parent, it uses the sampling state already
established for that span.
Valid hierarchies
Direct propagated-parent shape:
Propagated remote parent
├── Workflow
├── Same-trace ambient Lambda span
│ └── Invocation
└── Invocation [when no valid same-trace ambient span exists]
Ambient-parent shape:
Propagated remote parent
└── Same-trace ambient Lambda span
├── Workflow
└── Invocation
Synthetic fallback:
Synthetic execution root
├── Workflow
└── Invocation
Operation placement and links remain unchanged:
Execution plugin view
Workflow
└── Operation span
└── link -> current Invocation
Invocation plugin view
Invocation
└── Operation segment
├── link -> Workflow
└── continuation/replay link -> initial logical operation span
Conformance changes
- Replace the requirement that a returned Workflow parent be named
Durable Execution Attempt #1. - Accept a same-trace non-durable infrastructure span as the resolved Workflow
parent. - Continue allowing the parent document to be absent from the retrieved
backend subset, while requiring a non-null parent ID in normal propagated
mode. - Do not require the execution-scoped Workflow interval to be temporally
contained by a local ambient invocation span. - Retain the single canonical trace, synthetic fallback, sampling, deterministic
ID, and continuation-link assertions. - Cover ADOT, community language auto-instrumentation layers, and
collector-only/application-owned providers.
Related
- JavaScript SDK: otel: join Workflow to propagated trace and restore operation links aws-durable-execution-sdk-js#854
- Java SDK: otel: join Workflow to propagated trace and restore operation links aws-durable-execution-sdk-java#644
- Python SDK: otel: join Workflow to propagated trace and restore operation links aws-durable-execution-sdk-python#674
- Cross-language documentation: otel: document propagated or same-trace ambient Workflow parent aws-durable-execution-docs#257
Activity
zhongkechen commentedon Aug 21, 2026
Related implementation and documentation issues:
Suggested order: finalize the language-neutral contract here, implement the three SDK changes against it, validate them together with the OTel suite, then merge the documentation update.
[-]otel: adopt backend-parented Workflow topology[/-][+]otel: allow propagated or same-trace ambient Workflow parent[/+]fix(otel): export synthetic execution root in fallback traces (#935)
fix(sdk): export stable synthetic roots before suspension (#966)