Skip to content

[Enhancement]: Seed isolated scope stacks from external parent context #444

Description

@bbednarski9

Affected area

  • Rust core runtime
  • Python binding
  • Node.js binding
  • Go binding
  • C FFI
  • Adaptive runtime
  • Observability or exporters
  • Framework integrations

Proposed target release: 0.7

Problem or opportunity

Relay can create an empty isolated scope stack or capture and restore an existing local stack, but a process cannot seed a new isolated stack from an externally supplied parent context.

This leaves a correlation gap when one instrumented process invokes another process or remote workflow. The receiving process may know the causal parent identifier or distributed trace context, but it cannot install that relationship as the root of its local Relay scope stack. Events therefore appear as a separate trace or require application-specific reconstruction.

Relay should provide the local context API. The application remains responsible for authenticated transport of the context. Relay should not introduce IPC, a cross-instance registry, or a leader process.

Proposed enhancement

Add a transport-neutral external-parent context and an API for creating and temporarily installing an isolated scope stack rooted beneath it.

The contract should support:

  • An external parent scope identifier.
  • An optional parent name.
  • Optional standard distributed trace context when available.
  • Scoped installation with deterministic restoration.
  • Concurrent and nested isolation.
  • Validation that treats externally supplied identifiers as untrusted correlation data rather than mutable local handles.
  • Equivalent behavior through supported language bindings.

Existing scope-stack creation and binding APIs remain unchanged. Native ABI v1 compatibility must be preserved through an additive, feature-detected surface or a future ABI version.

Runtime contract and binding impact

Rust should define the canonical contract. Python, Node.js, Go, C FFI, the adaptive runtime, and the native plugin SDK should expose equivalent create, bind, and restore behavior where those surfaces support scope stacks.

Exporters should preserve the external parent relationship without requiring Relay instances to communicate.

Alternatives considered

  • Passing a parent to every individual event is error-prone and does not establish a scoped execution context.
  • Using only provider tool-call IDs or JSON-RPC IDs does not establish distributed trace parentage.
  • A shared Relay service or cross-instance registry would make IPC, deployment topology, availability, and trust Relay concerns.
  • Automatic trust of inbound headers would cross an application security boundary.

Acceptance criteria

  • A receiving process can create an isolated Relay scope stack from an explicit external parent context.
  • Tool, LLM, agent, and custom scopes emitted within that stack retain the supplied causal parent relationship.
  • Nested and concurrent external contexts remain isolated and restore the previous stack on exit and failure.
  • Invalid or incomplete contexts fail predictably without contaminating the current stack.
  • A two-process test produces one coherent exported trace tree without direct communication between Relay instances.
  • Existing scope APIs, bindings, and native ABI v1 consumers continue to work.
  • Documentation defines the application responsibility for transport, authentication, and trust.

Metadata

Metadata

Assignees

Labels

Fields

No fields configured for Enhancement.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions