# `Rheo.Backend.Capabilities`
[🔗](https://github.com/thanos/rheo/blob/v1.0.0/lib/rheo/backend/capabilities.ex#L1)

Typed backend capability declaration (ADR 023).

A backend declares two kinds of facts:

  * **guarantees** — semantic promises Rheo makes through this backend. The
    conformance suite gates correctness tests on them.
  * **mechanisms** — how the backend implements or optimizes delivery. They
    select optional conformance cases and runtime optimizations, never
    correctness.

`at_least_once` and `lease_fencing` are Rheo product invariants: they default
to `true` and may not be declared `false`.

## Guarantees

| Key | Meaning |
|---|---|
| `:durable` | Events and delivery state survive a backend process restart |
| `:distributed` | Several BEAM nodes may fetch from the same group concurrently |
| `:at_least_once` | Always `true` |
| `:lease_fencing` | Always `true` |
| `:partitions` | Multi-partition streams with per-partition sequences |
| `:contiguous_frontier` | `Rheo.lag/3` reports a contiguous ACK frontier |
| `:replay` | `Rheo.replay/3` and `Rheo.reset_group/3` are supported |

See the [building your own backend](building-your-own-backend.html) guide for a
per-backend comparison (Redis / Postgres yes; ETS / SQLite / Mnesia v0.11 no).

## Mechanisms

| Key | Meaning |
|---|---|
| `:atomic_compare_and_set` | Claims use a native atomic compare-and-set |
| `:ordered_range_scan` | Sequence ranges are read with an ordered scan |
| `:secondary_indexes` | Payload / metadata filters use secondary indexes |
| `:batch_writes` | `append_batch` is a single backend write |
| `:notifications` | The backend can signal new events (for example `NOTIFY`) |
| `:change_feed` | The backend exposes a change feed |
| `:native_consumer_groups` | The backend owns consumer-group state (Redis Streams) |
| `:native_pending_list` | Pending deliveries are backend-native (`XPENDING`) |
| `:native_reclaim` | Expired claims are reclaimed natively (`XAUTOCLAIM`) |
| `:blocking_reads` | Fetch can block until work arrives (`XREADGROUP BLOCK`) |
| `:native_group_lag` | Lag comes from the backend (`XINFO GROUPS`) |

## Examples

    iex> caps = Rheo.Backend.Capabilities.new(durable: true, partitions: true, batch_writes: true)
    iex> {caps.guarantees.durable, caps.guarantees.at_least_once, caps.mechanisms.batch_writes}
    {true, true, true}

    iex> Rheo.Backend.Capabilities.guarantee?(Rheo.Backend.Capabilities.new([]), :durable)
    false

    iex> Rheo.Backend.Capabilities.new(durable: "yes")
    ** (ArgumentError) capability :durable must be a boolean, got: "yes"

    iex> Rheo.Backend.Capabilities.new(lease_fencing: false)
    ** (ArgumentError) capability :lease_fencing is a Rheo invariant and cannot be false

# `flags`

```elixir
@type flags() :: %{required(atom()) =&gt; boolean()}
```

Raw boolean map passed to `new/1` before defaults are filled.

# `t`

```elixir
@type t() :: %Rheo.Backend.Capabilities{guarantees: flags(), mechanisms: flags()}
```

Declared guarantees and mechanisms; every known key is present.

# `guarantee?`

```elixir
@spec guarantee?(t(), atom()) :: boolean()
```

Whether the backend declares guarantee `key`.

# `guarantee_keys`

```elixir
@spec guarantee_keys() :: [atom()]
```

Known guarantee keys.

# `mechanism?`

```elixir
@spec mechanism?(t(), atom()) :: boolean()
```

Whether the backend declares mechanism `key`.

# `mechanism_keys`

```elixir
@spec mechanism_keys() :: [atom()]
```

Known mechanism keys.

# `new`

```elixir
@spec new(keyword() | map()) :: t()
```

Builds a validated declaration.

## Arguments

  * `flags` — keyword list or map of known keys to booleans. Omitted keys are
    `false`, except the invariants, which are `true`.

## Errors

Raises `ArgumentError` on an unknown key, a non-boolean value, or an
invariant declared `false`.

---

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