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

The deck's view of one session: one process per session that owns the event sequence, the
event log, the prompt queue and the turn that runs.

A socket (`Mead.Deck.Socket`) is only a translator between frames and calls on this process, so
a deck that reconnects, or a second device, finds the same state. Every sequenced event is
written to the log before it is sent to anyone: a deck can only have seen what a later replay
can repeat, and a log that cannot be written stops the channel instead of sending an event the
server could not stand behind.

## Turns

`prompt.send` is idempotent on `client_message_id`: a repeated id gets its original
`prompt.accepted` again and starts nothing. A new prompt is accepted, queued behind at most
`queue_limit` others (a prompt over the limit is dropped without any event), and the queue runs
one turn at a time through `Mead.submit_turn/3` in a task under `Mead.TurnSupervisor`. When a
turn ends, its text arrives as a `text.delta` (unless it was already streamed), and
`metric.updated` reports the session's token totals from the ledger. A turn that ends in an
error emits `turn.failed`; one that succeeds with an empty or invalid answer emits neither text
nor failure.

## Permissions

Every turn the channel starts carries `Mead.Deck.Interaction`, so the router asks the channel
before each tool call. The policy level decides: `allow_all` emits `permission.requested` and,
at once, `permission.resolved` with `decided_by_policy`; `ask_for_risky` lets a `:read` call run
silently; anything else emits `permission.requested`, pauses the turn clock
(`Mead.Session.Server.pause_clock/1`) and waits for the first valid `permission.respond` or for
the deadline, which resolves as `expired`. A later answer gets the existing `permission.resolved`
sent again to the answering socket alone. A request left open by a channel that died is resolved
as `expired` when the next channel starts, before it serves anyone. The details of a request come
from the model's arguments and are never logged.

`allow_always` answers allow the call and remember the tool (`"<server>__<tool>"`): the
`permission.resolved` carries `remember`, and from then on the same tool is allowed at once with
`decided_by_rule`, whatever the level but `allow_all`, which keeps `decided_by_policy`. The rules
are rebuilt from the log, and `permission.forget` with the tool name removes one
(`permission.forgotten`).

The channel monitors the session and stops with it. It is registered in `Mead.Registry` as
`{:deck, session_id}`.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `client_message`

```elixir
@spec client_message(GenServer.server(), pid(), Mead.Deck.Events.client_message()) ::
  :ok
```

Hands a validated client message from `socket` to the channel; unattached sockets are ignored.

# `policy_level`

```elixir
@spec policy_level(GenServer.server()) :: Mead.Deck.Configuration.policy_level()
```

The current permission policy level.

# `resume`

```elixir
@spec resume(GenServer.server(), pid(), non_neg_integer(), String.t() | nil) :: :ok
```

Attaches `socket` (a pid that will receive `{:deck_event, binary}` messages), sends it the
snapshot, and replays every sequenced event after `last_sequence`. All inside one call, so no
live event can reach the socket before its snapshot.

# `start_link`

---

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