# `Mead.Deck.Configuration`
[🔗](https://github.com/albertosca/mead/blob/main/lib/mead/deck/configuration.ex#L1)

Reads and validates `config :mead, :deck`.

Pure, like `Mead.MCP.Server.Configuration`: it starts nothing and reads no application
environment itself. Without a `:token` the deck endpoints are `:disabled`. Any other problem is
an error whose message names the setting and never contains the token or any other value.

The deck token is a separate secret from the MCP token. The struct keeps a SHA-256 digest of
it, and its `Inspect` omits even the digest.

## Settings

  * `:token` - the bearer token the deck presents to `POST /deck/ticket` (a non-empty string;
    required to enable the deck).
  * `:ticket_ttl_ms` - how long a ticket can be redeemed; defaults to 10 000.
  * `:permission_timeout_ms` - how long a permission request or a choice waits for an answer
    before it expires; defaults to 120 000.
  * `:heartbeat_ms` - the heartbeat interval, at most 30 000 because the deck treats 40 s of
    silence as a dead connection; defaults to 15 000.
  * `:resume_deadline_ms` - how long a fresh socket may wait before sending `session.resume`;
    defaults to 10 000.
  * `:queue_limit` - how many prompts may wait behind a running turn; defaults to 10.
  * `:idle_timeout_ms` - how long a socket may go without any frame from the client (text, ping or pong; the server pings with every heartbeat, so a live client answers by itself) before it is closed with 1001; it must be larger than `:heartbeat_ms`; defaults to 90 000.
  * `:event_log_limit` - how many events a session's log keeps; once an idle channel holds more, the oldest are dropped (the latest permission policy is always kept); defaults to 10 000.
  * `:default_policy_level` - `:ask_always`, `:ask_for_risky` or `:allow_all`; defaults to
    `:ask_for_risky`.

# `policy_level`

```elixir
@type policy_level() :: :ask_always | :ask_for_risky | :allow_all
```

# `t`

```elixir
@type t() :: %Mead.Deck.Configuration{
  default_policy_level: policy_level(),
  event_log_limit: pos_integer(),
  heartbeat_ms: pos_integer(),
  idle_timeout_ms: pos_integer(),
  permission_timeout_ms: pos_integer(),
  queue_limit: pos_integer(),
  resume_deadline_ms: pos_integer(),
  ticket_ttl_ms: pos_integer(),
  token_digest: binary()
}
```

# `load`

```elixir
@spec load(term()) :: :disabled | {:ok, t()} | {:error, String.t()}
```

# `token_matches?`

```elixir
@spec token_matches?(t(), term()) :: boolean()
```

Whether `presented` is the configured token, compared in constant time.

---

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