Module: Smith::Attribution

Defined in:
lib/smith/attribution.rb

Overview

Ambient execution attribution: an immutable, thread-local description of where execution currently is (run identity, transition, fan-out branch, optimizer round). Workflow execution scopes install it; observability consumers (traces, events, usage recording) read it, so emitted facts carry correlation without any consumer knowing about the workflow.

Attribution values are opaque identifiers, never content: the trace content policy does not treat them as payload. execution_key defaults to the workflow's persistence key during persisted runs; hosts running non-persisted workflows can seed an outer scope explicitly:

Smith::Attribution.with(execution_key: "host-run-42") { workflow.run! }

Installation inside workflow internals is a plain assignment (Attribution.install) because restoration there is owned by the surrounding ThreadContextSnapshot, which tracks the attribution thread key alongside the other per-step thread state.

Defined Under Namespace

Classes: Context

Constant Summary collapse

THREAD_KEY =
:smith_attribution
EMPTY =
Context.new(
  execution_key: nil, transition: nil, from: nil, to: nil, branch_key: nil, round: nil, workflow: nil
)

Class Method Summary collapse

Class Method Details

.ambientObject



65
66
67
# File 'lib/smith/attribution.rb', line 65

def ambient
  current || EMPTY
end

.carrying(context, &block) ⇒ Object

Cross-thread propagation: installs a context captured on another thread (or nil, clearing any stale value on a pooled thread) for the duration of the block.

Raises:

  • (ArgumentError)


92
93
94
95
96
# File 'lib/smith/attribution.rb', line 92

def carrying(context, &block)
  raise ArgumentError, "block required" unless block

  swap(context, &block)
end

.currentObject



61
62
63
# File 'lib/smith/attribution.rb', line 61

def current
  Thread.current[THREAD_KEY]
end

.current_fieldsObject

The compacted attribution fields, for merging into emitted payloads.



70
71
72
73
# File 'lib/smith/attribution.rb', line 70

def current_fields
  context = current
  context ? context.to_fields : {}
end

.install(context) ⇒ Object

Plain installation with no restoration: callers own restoration, either through ThreadContextSnapshot (workflow internals) or an enclosing #with / #carrying block.



78
79
80
# File 'lib/smith/attribution.rb', line 78

def install(context)
  Thread.current[THREAD_KEY] = context
end

.with(**overrides, &block) ⇒ Object

Host-facing scope: overlays the ambient attribution for the block.

Raises:

  • (ArgumentError)


83
84
85
86
87
# File 'lib/smith/attribution.rb', line 83

def with(**overrides, &block)
  raise ArgumentError, "block required" unless block

  swap(ambient.merge(**overrides), &block)
end