# `SquidMesh.AttemptStore`
[🔗](https://github.com/ccarvalho-eng/squid_mesh/blob/main/lib/squid_mesh/attempt_store.ex#L1)

Durable store for step-attempt history.

Attempts are recorded separately from step runs so retry policy and
observability can reason about attempt numbers, failure history, and the
latest known attempt state.

# `attempt_attrs`

```elixir
@type attempt_attrs() :: %{optional(:error) =&gt; map() | nil}
```

# `stale_error`

```elixir
@type stale_error() :: {:stale_attempt, String.t()}
```

# `attempt_count`

```elixir
@spec attempt_count(module(), Ecto.UUID.t()) :: non_neg_integer()
```

Returns how many attempts have been recorded for a step run.

# `begin_attempt`

```elixir
@spec begin_attempt(module(), Ecto.UUID.t()) ::
  {:ok, SquidMesh.Persistence.StepAttempt.t()} | {:error, Ecto.Changeset.t()}
```

Allocates the next attempt number for a step run and persists it as running.

# `complete_attempt`

```elixir
@spec complete_attempt(module(), Ecto.UUID.t()) ::
  {:ok, SquidMesh.Persistence.StepAttempt.t()}
  | {:error, :not_found | stale_error()}
```

Marks one attempt as completed.

# `fail_attempt`

```elixir
@spec fail_attempt(module(), Ecto.UUID.t(), map()) ::
  {:ok, SquidMesh.Persistence.StepAttempt.t()}
  | {:error, :not_found | stale_error()}
```

Marks one attempt as failed and stores the normalized error payload.

# `latest_attempt`

```elixir
@spec latest_attempt(module(), Ecto.UUID.t()) ::
  SquidMesh.Persistence.StepAttempt.t() | nil
```

Returns the latest recorded attempt for a step run.

# `next_attempt_number`

```elixir
@spec next_attempt_number(module(), Ecto.UUID.t()) :: pos_integer()
```

Returns the next available attempt number for a step run.

# `record_attempt`

```elixir
@spec record_attempt(
  module(),
  Ecto.UUID.t(),
  pos_integer(),
  String.t(),
  attempt_attrs()
) ::
  {:ok, SquidMesh.Persistence.StepAttempt.t()} | {:error, Ecto.Changeset.t()}
```

Records one step attempt with optional failure details.

---

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