ADR 0060 · Router config resolves through the settings layer; caliban.toml discovery retired
- Status: accepted
- Date: 2026-09-20
- Amends: 0038 (the "
caliban.tomldiscovery uses the CLAUDE.md walk algorithm" decision) - Author: john.ford2002@gmail.com
Context
ADR 0038 wired the model router from a caliban.toml
file that the binary located by an independent discovery chain: CLI --config
flag → CALIBAN_ROUTER_CONFIG env var → walk up from the cwd to the git root or
$HOME → ~/.config/caliban/caliban.toml. This predated caliban's unified
settings layer (.caliban/settings.toml, ADR 0026), which resolves every
other configuration key through one precedence chain (Cli > Local > Project > User > Managed) with per-key provenance surfaced by caliban config print.
The result was two parallel configuration mechanisms that never met: router
config had its own file, its own search algorithm, and no provenance, while
everything else lived in settings. #540 took the first step — it taught the
binary to prefer a settings-layer [router] section over discovery — but kept
the discovery chain as a fallback and did not mirror per-provider
[provider.X] blocks (custom api_key_env / base_url) into settings, so a
settings-sourced router could not point at a proxy or a keyless local endpoint.
Keeping both mechanisms is a standing tax: two code paths, two places to look, a walk-up that silently reaches outside the workspace, and router config that is invisible to the provenance tooling every other key enjoys.
Decision
Router config resolves through the settings layer, with an explicit file override — and nothing else.
-
Precedence.
--config <PATH>/CALIBAN_ROUTER_CONFIG(a standalonecaliban.toml) is the highest-precedence source and, when set, overrides the settings[router]section. Otherwise the settings-layer[router]value is used (flowing through the normal settings precedence and provenance). Otherwise the binary uses its single-provider fallback. -
Discovery removed. The walk-up and
~/.config/caliban/caliban.tomlsteps are deleted. A bare repo-rootcaliban.tomlis no longer picked up implicitly. The router crate's file module keeps only explicit loading (load_router_config_file(explicit)); when no explicit path is given it returnsNonerather than searching. -
Per-provider blocks in settings. The settings
[router]value carries optional[router.provider.X]blocks, typed binary-side viacaliban_model_router::router_and_providers_from_value. This reaches parity with a standalonecaliban.toml's top-level[provider.X]blocks, so a settings-sourced router can setapi_key_env/base_urlper provider. -
Migration.
caliban config import-router [--from <PATH>] [--dry-run]reads a legacycaliban.toml, relocates its top-level[provider.X]blocks under[router.provider.X], validates the result exactly as the runtime will load it, and merges it into<workspace>/.caliban/settings.toml[router](preserving other settings keys). At startup, a still-present but now-orphanedcaliban.tomlabove the cwd triggers a one-time warning pointing at this command, so a discovered-yesterday config never vanishes silently. -
caliban router debugresolves config the same way a real run does (explicit file, else settings[router]), not via the deleted discovery path.
The settings crate stays free of a dependency on the router schema: it carries
router as an opaque value and the binary types it at wiring time, as
established by #540.
Consequences
- Breaking. A repo-root or
~/.config/caliban/caliban.tomlthat was auto-discovered before is now ignored unless migrated into settings or passed via--config. The startup warning andcaliban config import-routermake the migration one command; the change is called out in the changelog. - One configuration model. Router config gains settings provenance
(
caliban config printshows its source scope) and drops a bespoke search algorithm and its four tests. - The
--configflag becomes an explicit, highest-precedence override rather than the top of a multi-step search — matching the intuition that an explicit CLI flag beats a config file. caliban_common::paths::walk_up_for_fileis still used, now only to detect an orphanedcaliban.tomlfor the deprecation warning, not to load it.
This supersedes ADR 0038's "caliban.toml discovery uses the CLAUDE.md walk
algorithm" decision; the rest of ADR 0038 (fallback, hedging, breakers,
capability filtering, effort levels, binary wiring) stands.