# SPEC-008 — Configuration TOML config per deployment (`kroa.toml`, `ggg.toml` — both untracked; `config.toml` in the repo is the placeholder sample). Loaded by `FjerkroaBot.load_config`, hot-reloaded by a watchdog observer (defect D9 — reload race — is tracked in FDB-004 and will refine these requirements). ### CFG-01 — TOML config loads into a plain dict (coverage: test) `FjerkroaBot.load_config(path)` parses the TOML file and returns its top-level table as a dict; responders read raw keys from it. ### CFG-02 — Per-channel system prompt override (coverage: test) A responder bound to channel `X` uses `config["X"]` as its system prompt when that key exists, else `config["system"]`. One deployment can speak differently per channel. ### CFG-03 — Missing news file leaves the placeholder untouched (coverage: test) When `news` points to a non-existent file, the `{news}` placeholder stays literal in the system prompt (no crash, no empty substitution). ### CFG-04 — Config hot-reload applies on the event loop (coverage: test) The watchdog observer thread never mutates live config references itself: a detected change is loaded, then the swap of `bot.config` and all responder `.config` references is scheduled onto the event loop (`call_soon_threadsafe`), so no request ever reads a half-swapped config (D9). Before the loop runs (startup), the swap applies directly — there are no concurrent readers yet.