# `Wardrik.Ceiling`

A budget all of an org's agents share. Set ceilings in the org's `Wardrik.OrgSettings`:

    ceilings: %{
      "spending-cap" => [usd: 20.00, per: :day],
      "free-allowance" => [usd: 5.00, per: :total, on_exhausted: :deny],
      "watch" => [tokens: 2_000_000, per: :month, on_exhausted: :continue]
    }

A ceiling takes the same settings as `WardrikPolicy.Budget`, except `per: :turn`. It must set
`:usd`, `:tokens` or both. Wardrik counts what the org's model and tool calls spend in each
period.

Once the limit is reached, the next model call by any of the org's agents does what
`:on_exhausted` says:

  * `:ask` - the default. The call waits on a `ceiling_approval` interrupt. Only a scope allowed
    `ceiling.approve` on the org's ceiling resource, such as `acme/ceiling`, may approve it.
    Owners can. Approving adds the budget's `grant` for every agent in the org, for that period.
  * `:deny` - the call is refused.
  * `:continue` - the call runs.

Every ceiling emits `[:wardrik, :ceiling, :reached]` when its limit is reached.

A ceiling in dollars refuses models with no price, unless it's `:continue`. Subagents' model
calls count too, as part of the tool call that ran them.

# `t`

```elixir
@type t() :: %Wardrik.Ceiling{
  budget: WardrikPolicy.Budget.t(),
  name: String.t(),
  on_exhausted: :ask | :deny | :continue
}
```

# `new`

```elixir
@spec new(String.t(), keyword() | map()) :: {:ok, t()} | {:error, String.t()}
```

Builds the ceiling `name` from budget settings, as a keyword list or a string-keyed map.

# `spent`

```elixir
@spec spent(Wardrik.t(), String.t(), t()) :: map()
```

Returns what `org`'s agents have spent against `ceiling` in the current period.

    %{
      limit: %{usd: 20.0, tokens: nil},
      spent: %{usd: 3.5, tokens: 120_000},
      granted: %{},
      on_exhausted: :ask,
      per: :day,
      starts_over: ~D[2026-10-31]
    }

`:starts_over` is `nil` for a `per: :total` ceiling.

---

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