The previous commit made config strict so a WRONG key fails at load. That guards typos; it says nothing about keys that are spelled correctly, parse cleanly, and are read by nobody. Four of those: `context.per_model_overrides` was the worst, because config.yaml shipped a worked example for it -- follow that example and the model's effective window does not move. It is now typed (ContextOverride, not a bare dict, so a typo INSIDE an override is an error too) and read by poller.ModelRow.effective_context_window. Both keys fall back independently, compared with `is not None` rather than `or`: an override of 0 reserve tokens must mean zero, and present-but-falsy defaults are a trap evals/tasks.yaml deliberately tests models on. `logging.log_path` named "router.log", which nothing ever wrote -- the dispatcher prints to stderr and systemd hands that to the journal. Deleted, with a note in config.yaml saying where the logs actually are. `tiers` is documented as labels "for logging/dashboards" and reached neither. /health is the dashboard surface, so it reports them now. `objective.quality_tolerance: 0` is a fifth of the same family, arriving from the other direction: the validator accepts [0, 1) and `band()` divided by it, so a legitimate setting -- "never trade quality for cost" -- turned every request into a 500 on a config that had loaded cleanly. 0 now means no band: strict quality ordering, cost breaking only exact ties. And `python config.py`, the setup step documented in README.md and CLAUDE.md, printed cfg.weights -- replaced by cfg.objective some commits ago. It said "Config loaded OK" and then died with AttributeError, which is a bad look for the one command whose entire job is to prove the config is fine. The summary is now a function so a test pins the attribute names against the next rename. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WSkcSD2Jzkxo1Kw27ecfXJ
12 KiB
12 KiB