# `Jido.Runic.ActionNode`
[🔗](https://github.com/agentjido/jido_runic/blob/v1.0.0/lib/jido/runic/action_node.ex#L1)

A Runic workflow node that wraps a Jido Action module.

ActionNode preserves the full identity and semantics of a Jido Action within
a Runic workflow graph. Unlike wrapping an action as a bare `Runic.Workflow.Step`,
ActionNode retains:

- **Stable identity**: Content-addressed hash based on `{action_mod, params}` — not
  an anonymous function reference — so hashes are stable across recompiles.
- **Schema introspection**: Input/output schemas derived from the action module's
  NimbleOptions schema, exposed via the `Runic.Component` protocol.
- **Full Jido execution semantics**: Execution delegates to `Jido.Exec.run/4`, which
  provides parameter validation, lifecycle hooks, output validation, retries,
  compensation, and telemetry.

## Usage

    alias Jido.Runic.ActionNode

    node = ActionNode.new(MyApp.Actions.ValidateOrder, %{strict: true}, name: :validate)

    workflow =
      Runic.Workflow.new(name: :pipeline)
      |> Runic.Workflow.add(node)

    workflow
    |> Runic.Workflow.react_until_satisfied(%{order_id: "123"})
    |> Runic.Workflow.raw_productions()

## Execution

During Runic's three-phase execution cycle:

1. **Prepare** — Extracts the input fact and builds a `%Runnable{}` with causal context.
2. **Execute** — Merges the fact's value into the node's params and calls
   `Jido.Exec.run/4`. Timeout defaults to `0` (inline execution) so that
   Runic's scheduler owns concurrency and timeout control.
3. **Apply** — The completed Runnable carries event structs and deferred hook
   reducers that `Runic.Workflow.apply_runnable/2` folds back into the graph.

# `t`

```elixir
@type t() :: %Jido.Runic.ActionNode{
  action_mod: module(),
  context: map(),
  exec_opts: keyword(),
  executor: :local | {:child, atom()} | {:child, atom(), term()},
  hash: integer(),
  inputs: keyword(),
  name: atom(),
  outputs: keyword(),
  params: map()
}
```

# `action_metadata`

```elixir
@spec action_metadata(t()) :: map() | nil
```

Returns the action module's metadata map if available.

# `new`

```elixir
@spec new(module(), map(), keyword()) :: t()
```

Creates a new ActionNode wrapping the given Jido Action module.

## Options

- `:name` — Node name used for graph lookups. Defaults to the action module's
  last segment, underscored (e.g., `MyApp.Actions.ValidateOrder` → `:validate_order`).
- `:context` — Jido execution context map passed to `Jido.Exec.run/4`. Default `%{}`.
- `:timeout` — Override the Exec timeout. Default `0` (inline, no spawned task) so
  Runic's scheduler owns concurrency and time budgeting.
- `:executor` — `:local` (default) or `{:child, tag}` / `{:child, tag, spec}` to
  delegate execution; validated at construction time for safety.
- Any other options are forwarded to `Jido.Exec.run/4` as exec opts.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
