Runic.Workflow.CausalContext (Runic v0.1.0-alpha.7)

Copy Markdown View Source

Minimal immutable context for executing a runnable without the full workflow.

Built during the prepare phase and consumed during execute phase. Contains only what's needed for the specific node type being invoked.

Design Goals

  1. Minimal footprint - Only include data needed for execution
  2. Immutable - Safe to pass across process boundaries
  3. Self-contained - No workflow reference, all needed state captured
  4. Content-addressed - Uses causal ancestry rather than generation counters

Node-Specific Context Fields

Different node types populate different context fields:

  • Step: fan_out_context for mapped pipeline tracking
  • Condition/Conjunction: satisfied_conditions for gate logic
  • Accumulator: last_known_state for stateful operations
  • Join: join_context with satisfaction tracking
  • FanOut: fan_out_context with reduce tracking
  • FanIn: fan_in_context with readiness and sister values
  • All nodes: meta_context for graph-resolved meta expression values, run_context for external runtime values from context/1 expressions

Summary

Functions

Returns the after hooks from the context.

Builds a basic context with node hash, input fact, and ancestry depth.

Returns the before hooks from the context.

Returns whether this context has any meta context populated.

Returns whether this context has any run context populated.

Returns whether this context's node is mergeable (parallel-safe).

Returns the meta context map from the context.

Creates a new CausalContext with the given attributes.

Returns the run context map from the context.

Adds fan_in context for reduction coordination.

Adds fan_out context for mapped pipeline tracking.

Adds hooks to the context.

Adds join context for join coordination.

Sets the mergeable flag on the context.

Adds meta context for nodes with meta expression dependencies.

Adds run context for external runtime value injection.

Adds satisfied conditions for conjunction gates.

Adds state context for stateful nodes.

Types

t()

@type t() :: %Runic.Workflow.CausalContext{
  ancestry_depth: non_neg_integer(),
  fan_in_context: map() | nil,
  fan_out_context: map() | nil,
  hooks: {list(), list()},
  input_fact: Runic.Workflow.Fact.t() | nil,
  is_state_initialized: boolean(),
  join_context: map() | nil,
  last_known_state: term() | nil,
  mergeable: boolean(),
  meta_context: map(),
  node_hash: integer() | nil,
  run_context: map(),
  satisfied_conditions: MapSet.t() | nil
}

Functions

after_hooks(causal_context)

@spec after_hooks(t()) :: list()

Returns the after hooks from the context.

basic(node_hash, input_fact, ancestry_depth)

@spec basic(integer(), Runic.Workflow.Fact.t(), non_neg_integer()) :: t()

Builds a basic context with node hash, input fact, and ancestry depth.

before_hooks(causal_context)

@spec before_hooks(t()) :: list()

Returns the before hooks from the context.

has_meta_context?(causal_context)

@spec has_meta_context?(t()) :: boolean()

Returns whether this context has any meta context populated.

has_run_context?(causal_context)

@spec has_run_context?(t()) :: boolean()

Returns whether this context has any run context populated.

mergeable?(causal_context)

@spec mergeable?(t()) :: boolean()

Returns whether this context's node is mergeable (parallel-safe).

meta_context(causal_context)

@spec meta_context(t()) :: map()

Returns the meta context map from the context.

new(attrs \\ [])

@spec new(keyword()) :: t()

Creates a new CausalContext with the given attributes.

run_context(causal_context)

@spec run_context(t()) :: map()

Returns the run context map from the context.

with_fan_in_context(ctx, fan_in_context)

@spec with_fan_in_context(t(), map()) :: t()

Adds fan_in context for reduction coordination.

with_fan_out_context(ctx, fan_out_context)

@spec with_fan_out_context(t(), map()) :: t()

Adds fan_out context for mapped pipeline tracking.

with_hooks(ctx, arg)

@spec with_hooks(
  t(),
  {list(), list()}
) :: t()

Adds hooks to the context.

with_join_context(ctx, join_context)

@spec with_join_context(t(), map()) :: t()

Adds join context for join coordination.

with_mergeable(ctx, mergeable)

@spec with_mergeable(t(), boolean()) :: t()

Sets the mergeable flag on the context.

Components with mergeable: true have CRDT-like properties (commutative, idempotent, associative) and are safe for parallel merge without ordering guarantees.

with_meta_context(ctx, meta_context)

@spec with_meta_context(t(), map()) :: t()

Adds meta context for nodes with meta expression dependencies.

Meta context contains values prepared from :meta_ref edges during the prepare phase. These values are then available during execution without requiring workflow access.

Example

context = CausalContext.new(...)
|> CausalContext.with_meta_context(%{cart_state: %{total: 150, items: []}})

with_run_context(ctx, run_context)

@spec with_run_context(t(), map()) :: t()

Adds run context for external runtime value injection.

Run context contains runtime-scoped values (secrets, tenant IDs, database connections) resolved for a specific component during the prepare phase. Available during execution without requiring workflow access.

Example

context = CausalContext.new()
|> CausalContext.with_run_context(%{api_key: "sk-...", model: "gpt-4"})

with_satisfied_conditions(ctx, satisfied_conditions)

@spec with_satisfied_conditions(t(), MapSet.t()) :: t()

Adds satisfied conditions for conjunction gates.

with_state(ctx, last_known_state, is_initialized \\ true)

@spec with_state(t(), term(), boolean()) :: t()

Adds state context for stateful nodes.