# `Chimeway.Dispatch.Executor`
[🔗](https://github.com/jonlunsford/chimeway/blob/v1.0.0/lib/chimeway/dispatch/executor.ex#L1)

Shared adapter execution for sync and Oban worker dispatch paths.

## Phase 14 contract changes (D-05)

`classify/1` now returns a 3-tuple `{outcome, error_class, detail}` so
`:temporary | :permanent | :bounced` classification is preserved end-to-end:

    adapter.deliver -> classify -> Deliveries.record_attempt(error_class:)
                                -> attempt row .error_class column
                                -> trace explanation
                                -> Oban worker {:ok | {:error, _}} return

`run_delivery/1` passes `error_class` into `Deliveries.record_attempt/2`. The
return shape is unchanged for sync consumers (`{:ok, %{delivery, attempt}}` |
`{:error, step, reason, changes}` | `{:error, term()}`). Plan 14-05's Oban
worker reads the recorded attempt's `outcome` + `error_class` to decide its
Oban return value (retry vs terminal vs success).

# `run_delivery`

```elixir
@spec run_delivery(Chimeway.Delivery.t()) ::
  {:ok,
   %{delivery: Chimeway.Delivery.t(), attempt: Chimeway.DeliveryAttempt.t()}}
  | {:error, atom(), term(), map()}
  | {:error, term()}
```

---

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