Skip to content

otel: allow propagated or same-trace ambient Workflow parent #99

Closed

Description

@zhongkechen

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:

  1. Workflow is a direct child of the remote context reconstructed from
    _X_AMZN_TRACE_ID.Parent.
  2. Workflow is 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 Root as the canonical trace ID;
  • allow Workflow to use either the reconstructed remote parent or the current
    valid same-trace ambient span;
  • allow Invocation to 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 Workflow and Invocation; 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

Activity

  1. zhongkechen commented on Aug 21, 2026

    @zhongkechen
    ContributorAuthor

    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.

  2. changed the title [-]otel: adopt backend-parented Workflow topology[/-] [+]otel: allow propagated or same-trace ambient Workflow parent[/+] on Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions