# `Skuld.Comp.ISentinel`
[🔗](https://github.com/mccraigmccraig/skuld/blob/main/lib/skuld/comp/i_sentinel.ex#L1)

Protocol for handling sentinel values in run/run! and generic sentinel inspection.

Sentinels are control flow values (Suspend, Throw, etc.) that bypass normal
computation flow. This protocol allows generic handling without coupling to
specific sentinel types.

## Sentinel Categories

Sentinels fall into two categories:

- **Suspend sentinels** (`suspend?/1` returns true): ExternalSuspend, InternalSuspend
  These represent suspended computations that can be resumed.

- **Error sentinels** (`error?/1` returns true): Throw, Cancelled
  These represent error conditions that propagate up the call stack.

Plain values have `sentinel?/1`, `suspend?/1`, and `error?/1` all return false.

# `t`

```elixir
@type t() :: term()
```

All the types that implement this protocol.

# `error?`

```elixir
@spec error?(t()) :: boolean()
```

Is this an error sentinel (Throw, Cancelled)?

# `run`

```elixir
@spec run(t(), Skuld.Comp.Types.env()) ::
  {Skuld.Comp.Types.result(), Skuld.Comp.Types.env()}
```

Complete a computation result - invoke leave_scope or bypass for sentinels

# `run!`

```elixir
@spec run!(t()) :: term()
```

Extract value or raise for sentinel types

# `sentinel?`

```elixir
@spec sentinel?(t()) :: boolean()
```

Is this a sentinel value? Returns false for plain values.

# `serializable_payload`

```elixir
@spec serializable_payload(t()) :: map()
```

Get the serializable payload (struct fields minus :resume). Used for logging/serialization.

# `suspend?`

```elixir
@spec suspend?(t()) :: boolean()
```

Is this a suspend sentinel (ExternalSuspend, InternalSuspend)?

---

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