# `Runic.Workflow.PolicyDriver`
[🔗](https://github.com/zblanco/runic/blob/main/lib/workflow/policy_driver.ex#L1)

Executes a `%Runnable{}` according to a `%SchedulerPolicy{}`, handling retries,
timeouts, backoff, fallbacks, and failure modes.

The PolicyDriver is the bridge between the scheduler's declared execution policy
and the actual invocation of a runnable's work function. It wraps `Invokable.execute/2`
with policy-driven retry loops, timeout enforcement, and fallback resolution.

## Event Emission

When `emit_events: true` is passed in options, `execute/3` returns
`{%Runnable{}, [event]}` instead of just `%Runnable{}`. Events are:

  * `%RunnableDispatched{}` — emitted at each execution attempt
  * `%RunnableCompleted{}` — emitted on successful completion
  * `%RunnableFailed{}` — emitted on permanent failure (retries exhausted)

# `execute`

```elixir
@spec execute(Runic.Workflow.Runnable.t(), Runic.Workflow.SchedulerPolicy.t()) ::
  Runic.Workflow.Runnable.t()
```

Execute a runnable according to the given scheduler policy.

# `execute`

```elixir
@spec execute(
  Runic.Workflow.Runnable.t(),
  Runic.Workflow.SchedulerPolicy.t(),
  keyword()
) ::
  Runic.Workflow.Runnable.t() | {Runic.Workflow.Runnable.t(), list()}
```

Execute a runnable according to the given scheduler policy with options.

## Options

  * `:deadline_at` - monotonic time deadline (used by Phase 3, plumbed now)
  * `:emit_events` - when `true`, returns `{%Runnable{}, [event]}` instead of `%Runnable{}`

---

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