# `Dsxir.Settings`

Three-layer settings stack: globals (`:persistent_term`), per-process scope
(process dict), per-call opts (passed as args).

  * `configure/1` writes globals. Call once at boot.
  * `context/2` pushes a scoped frame for the duration of `fun.()`.
  * `snapshot/0` captures the current globals+stack; `run/2` replays them in a worker.
  * `resolve/2` looks up a key: stack top-down, then globals, then the provided default.

`tenant_*` keys and `:lm` tuples whose config carries a non-nil `:api_key` are rejected
by `configure/1` with a `Logger.warning`. `tenant_*` keys nested inside `:metadata` are
stripped from the map with a `Logger.warning`; non-tenant keys in the same map pass through
unchanged. Per-request tenant data flows through `context/2`.
The `:lm` field has shape `nil | {impl_module :: module(), config :: keyword()}` (see
`Dsxir.LM`); credentials live in the config keyword list, not at the top level.

# `t`

```elixir
@type t() :: %Dsxir.Settings{
  adapter: nil | module(),
  cache: boolean(),
  call_plugs: list(),
  callbacks: list(),
  lm: nil | {module(), keyword()},
  metadata: map()
}
```

# `configure`

```elixir
@spec configure(Enumerable.t()) :: :ok
```

Install globals into `:persistent_term`. Merges with whatever is currently stored;
unknown keys raise `Dsxir.Errors.Invalid.Configuration`. `tenant_*` keys and `:lm`
tuples whose config carries a non-nil `:api_key` are dropped with a warning.
`tenant_*` keys nested inside `:metadata` are stripped from the map (other keys preserved).

# `context`

```elixir
@spec context(Enumerable.t(), (-&gt; any())) :: any()
```

Push a scoped frame for the duration of `fun.()`. Restored via `try/after`.

# `default_globals`

```elixir
@spec default_globals() :: map()
```

Architectural defaults installed at application boot.

# `resolve`

```elixir
@spec resolve(atom(), term()) :: term()
```

Walk the stack top-down, then globals, then return the default.

# `run`

```elixir
@spec run(%{globals: map(), stack: [map()]}, (-&gt; any())) :: any()
```

Replay a snapshot in the calling process for the duration of `fun.()`.

Writes globals into `:persistent_term` only when the snapshot's globals differ
from the live globals — `:persistent_term.put/2` triggers a system-wide GC of
every process holding references and is designed for write-once-read-many data,
so fan-out workers (e.g. `Dsxir.Predictor.Parallel`) replaying the same
snapshot must not pay that cost N times. The scope stack is always restored on
exit; globals are not. Intended for short-lived worker processes that have no
prior globals worth preserving. Do not use to "temporarily" swap globals in a
long-lived process.

# `snapshot`

```elixir
@spec snapshot() :: %{globals: map(), stack: [map()]}
```

Snapshot the live globals and scope stack for replay in another process.

---

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