# `Runic.Runner`
[🔗](https://github.com/zblanco/runic/blob/main/lib/runic/runner.ex#L1)

Built-in workflow execution infrastructure.

Provides supervision, persistence, registry, and lifecycle management
for running workflows as managed processes.

## Starting a Runner

    {:ok, _pid} = Runic.Runner.start_link(name: MyApp.Runner)

## Store Ownership

If no `:store` is configured, the Runner starts its built-in ETS store as
part of the supervision tree. This preserves the zero-configuration,
in-memory execution path.

If `:store` is configured explicitly, the Runner assumes that store's
supervision and lifecycle are managed elsewhere. This applies to custom
adapters and to built-in stores when you want to own their startup in your
application's supervision tree.

For adapters backed by an externally supervised dependency such as an Ecto
repo:

    {:ok, _pid} =
      Runic.Runner.start_link(
        name: MyApp.Runner,
        store: MyApp.SQLiteStore,
        store_opts: [repo: MyApp.Repo]
      )

To use the built-in ETS store explicitly, start it before the Runner:

    children = [
      {Runic.Runner.Store.ETS, runner_name: MyApp.Runner},
      {Runic.Runner, name: MyApp.Runner, store: Runic.Runner.Store.ETS}
    ]

## Running Workflows

    {:ok, pid} = Runic.Runner.start_workflow(MyApp.Runner, :my_workflow, workflow)
    :ok = Runic.Runner.run(MyApp.Runner, :my_workflow, input)
    {:ok, results} = Runic.Runner.get_results(MyApp.Runner, :my_workflow)

    # Structured results using output port contracts
    {:ok, %{total: value}} = Runic.Runner.get_results(MyApp.Runner, :my_workflow, [])

    # Select specific components
    {:ok, %{price: p}} = Runic.Runner.get_results(MyApp.Runner, :id, components: [:price])

# `checkpoint`

Triggers an explicit checkpoint for a running workflow.

Persists the current workflow state to the store regardless of
the configured checkpoint strategy. Useful with `checkpoint_strategy: :manual`.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `get_results`

Returns the raw productions from a running workflow.

For structured results using port contracts, use `get_results/3`.

# `get_results`

Returns structured results from a running workflow.

## Options

  - `:components` — list of component names to extract. When `nil` (default),
    uses the workflow's output port contract.
  - `:facts` — when `true`, returns `%Fact{}` structs. Default `false`.
  - `:all` — when `true`, returns all produced values as lists. Default `false`.

## Examples

    # Use output port contract
    {:ok, %{total: 42.50}} = Runner.get_results(runner, :order_pipeline, [])

    # Explicit component selection
    {:ok, %{price: 42.50}} = Runner.get_results(runner, :order_pipeline, components: [:price])

    # All values as facts
    {:ok, %{total: [%Fact{}, ...]}} = Runner.get_results(runner, :id, facts: true, all: true)

# `get_store`

Returns the `{store_module, store_state}` tuple for this runner.

The store state is initialized lazily on first access and cached in persistent_term.

# `get_workflow`

Returns the full workflow struct from a running workflow.

# `list_workflows`

Lists all active workflow IDs managed by this runner.

# `lookup`

Looks up the PID of a running workflow by ID.

Returns `pid` or `nil`.

# `resume`

Resumes a workflow from persisted state.

Loads the workflow log from the store, rebuilds the workflow via
`Workflow.from_log/1`, and starts a new Worker.

## Options

  - `:rehydration` — Controls how fact values are loaded during recovery.
    - `:full` (default) — All fact values are loaded into memory.
    - `:hybrid` — Uses lean replay to create `FactRef` vertices, classifies
      hot/cold facts, then resolves only hot values from the fact store.
      Requires a store that implements `save_fact/3` and `load_fact/2`.
    - `:lazy` — All facts stay as `FactRef` structs, resolved on demand
      during dispatch. Maximum memory savings, but requires resolution
      before any fact value can be used.

# `run`

Feeds input to a running workflow.

## Options

- `:run_context` - A map of external values keyed by component name, made available
  to components that use `context/1` expressions. Supports a `:_global` key for
  values available to all components.

# `start_link`

# `start_workflow`

Starts a new workflow under this runner.

Returns `{:ok, pid}` or `{:error, {:already_started, pid}}`.

# `stop`

Stops a running workflow.

Options:
  - `persist: true` (default) — saves final state to the store before stopping
  - `persist: false` — stops without saving

# `via`

Returns the via tuple for addressing a worker through the registry.

---

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