Groq decommissioned llama-3.3-70b-versatile, which every agent shared via a
single hardcoded get_llm(). Each query returned a 404 that the API then
streamed to the browser as answer prose, so the UI decorated a provider
error with a "MODERATE CERTAINTY" evidence badge and a "grounded reply"
byline.
Model IDs are now centralised in llm/config.py, resolved per role from
ARIA_*_MODEL env vars with live defaults verified against Groq's model list
(generator openai/gpt-oss-120b, everything else openai/gpt-oss-20b). No
Space secrets are required — the defaults work as-is.
Provider failures get their own type and their own SSE `error` event that
carries no confidence, no evidence tier and no citations, and never travels
on the `token` channel the UI renders as an answer. An unreachable guardrail
no longer defaults to "in scope", and a judge that fails or returns
unparseable JSON yields confidence=null, shown as "Not adjudicated", instead
of a placeholder 0.5 on a real gauge.
A startup pref…