# `WardrikDaemon.Config`

Reads `config.yaml` as the daemon starts.

    org: acme
    base_url: https://agents.acme.example
    defaults:
      model: anthropic:claude-haiku-4-5
    http:
      port: 4747

## Keys

  * `org` - the deployment's org. `default` unless set.
  * `orgs` - other orgs to run agents for. See `WardrikDaemon.Config.Orgs`.
  * `base_url` - where people and services reach the deployment. The HTTP API's URL unless set.
  * `defaults` - what every agent gets where its definition says nothing.
  * `models` - prices for models the catalog lacks, by model spec, in dollars per million tokens:
    `input`, `output`, `cache_read` and `cache_write`, or `priced_as` another model, each with an
    optional `markup`. See `Wardrik.Setup.price/2`.
  * `mcp` - MCP servers agents may call. See `WardrikDaemon.Config.MCP`.
  * `oauth` - providers people connect accounts with. See `WardrikDaemon.Config.OAuth`.
  * `channels` - chat apps agents are reached through. See `WardrikDaemon.Config.Channels`.
  * `notify` - where agents' notices go. See `WardrikDaemon.Config.Notify`.
  * `workspace` - `shared`: file trees agents beyond their owners may mount, each with `read`
    and `write` lists of resource patterns.
  * `brave` - `api_key`, the key `web_search` searches with.
  * `vault` - `keys`, a list of the vault's keys.
  * `http` - `port` (`4747`), `ip` (`WARDRIK_HTTP_IP`, else `127.0.0.1`) and `trusted_workers`
    (`false`).
  * `storage` - `postgres: {url: ...}` keeps everything in Postgres. The node's disk unless set.

`tools`, `tokens`, `cluster` and `ssh` aren't supported yet, and are skipped with a warning. Any
other key is an error.

## Secrets

`${NAME}` in any string is replaced with:

  1. the environment variable `NAME`, or one the env file sets, or else
  2. the deployment's secret `NAME` in the vault, which `wardrik vault put NAME` seals.

`vault`, `http` and `storage` are read before the vault opens, so they take the environment
alone. A `${NAME}` nothing sets is an error.

# `t`

```elixir
@type t() :: %WardrikDaemon.Config{
  base_url: String.t() | nil,
  brave: String.t() | nil,
  channels: keyword(),
  defaults: map(),
  ip: :inet.ip_address(),
  keys: [String.t()],
  mcp: keyword(),
  notify: keyword(),
  oauth: keyword(),
  org: String.t(),
  orgs: %{required(String.t()) =&gt; WardrikDaemon.Config.Orgs.entry()},
  port: :inet.port_number(),
  prices: %{required(String.t()) =&gt; keyword()},
  storage: {:postgres, String.t()} | nil,
  trusted_workers: boolean(),
  warnings: [String.t()],
  workspace: keyword()
}
```

# `vault`

```elixir
@type vault() :: (String.t() -&gt; {:ok, String.t()} | :error)
```

Looks up the deployment's secret `name` in the vault. Returns `:error` if it isn't there.

# `base_url`

```elixir
@spec base_url(t()) :: String.t()
```

Returns where people and services reach the deployment: `base_url`, or `url/1` if it isn't set.

# `bootstrap`

```elixir
@spec bootstrap(WardrikDaemon.Dirs.t(), %{required(String.t()) =&gt; String.t()}) ::
  {:ok,
   %{
     keys: [String.t()],
     port: :inet.port_number(),
     ip: :inet.ip_address(),
     storage: {:postgres, String.t()} | nil
   }}
  | {:error, String.t()}
```

Reads what's needed before the vault opens: the vault's keys, where HTTP listens, and `storage`. Fills in `${NAME}` from `env` alone.

# `read`

```elixir
@spec read(
  WardrikDaemon.Dirs.t(),
  %{required(String.t()) =&gt; String.t()},
  vault() | nil
) ::
  {:ok, t()} | {:error, String.t()}
```

Reads `config.yaml` in the config directory.

Fills in `${NAME}` from `env`, then from `vault`. A missing file reads as the defaults. Returns
`{:error, reason}`, naming the file and key, if it doesn't read.

# `sealable`

```elixir
@spec sealable(WardrikDaemon.Dirs.t()) :: [String.t()]
```

Returns the `${NAME}`s `config.yaml` names outside `vault`, `http` and `storage`. The vault may hold these.

# `url`

```elixir
@spec url(t()) :: String.t()
```

Returns the HTTP API's URL. An API bound to `0.0.0.0` is reached at `127.0.0.1`.

---

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