# Einheiten: backend/config.py
stand: UNBEKANNT

## backend/config.py::_load_env
beschreibung: Lädt KEY=VALUE-Zeilen aus einer .env-Datei in os.environ, wobei die Datei bereits gesetzte Umgebungsvariablen überschreibt.
fakten:
- Liest die .env-Datei UTF-8-codiert ein.
  beleg: "text = path.read_text(encoding=\"utf-8\")"
- Bricht den Ladevorgang still ab, wenn die Datei nicht lesbar ist.
  beleg: "except OSError:"
- Überspringt Leerzeilen, Kommentarzeilen und Zeilen ohne Gleichheitszeichen.
  beleg: "if not line or line.startswith(\"#\") or \"=\" not in line:"
- Entfernt umgebende Anführungszeichen aus den Werten.
  beleg: "value = value.strip().strip('\"').strip(\"'\")"
- Schreibt jeden gültigen Schlüssel in os.environ (Datei gewinnt gegen vererbte Env).
  beleg: "os.environ[key] = value"
kanten:

## backend/config.py::DEFAULT_PROVIDER
beschreibung: Stellt sicher, dass DEFAULT_PROVIDER aus der Umgebung gesetzt ist, und bricht den Start sonst mit einer RuntimeError ab.
fakten:
- Liest DEFAULT_PROVIDER aus der Umgebung mit leerem Default.
  beleg: "DEFAULT_PROVIDER = os.getenv(\"DEFAULT_PROVIDER\", \"\")"
- Bricht den Start ab, wenn DEFAULT_PROVIDER nicht gesetzt ist.
  beleg: "if not DEFAULT_PROVIDER:"
- Die Fehlermeldung nennt `minimax` als konkreten Beispielwert.
  beleg: "DEFAULT_PROVIDER=minimax)\""
kanten:

## backend/config.py::PROVIDERS
beschreibung: Stellt die unabhängigen Provider-Stacks (claude, minimax, lokal) mit Rollen-Modellen, CLI-Aufrufen und Authentifizierungs-Umgebungsvariablen bereit.
fakten:
- Mehrere voneinander unabhängige Provider-Stacks sind in einem Dict zusammengefasst.
  beleg: "PROVIDERS = {"
- Der `lokal`-Stack prüft Ollama-Erreichbarkeit über eine HTTP-URL.
  beleg: "\"check_url\": \"http://localhost:11434/api/tags\","
- Der `minimax`-Stack nutzt den ENV-Key `MINIMAX_API_KEY` zur Authentifizierung.
  beleg: "\"env_key\": \"MINIMAX_API_KEY\","
- Der `claude`-Stack nutzt OAuth-Authentifizierung statt eines API-Keys.
  beleg: "\"env_key\": None,  # auth via CLAUDE_CODE_OAUTH_TOKEN"
kanten:
- wird-genutzt-von: backend/config.py::resolve_role

## backend/config.py::ROLE_ROUTING
beschreibung: Bildet die vier Agent-Rollen quick/judge/guide/fast auf optionale prozessweite Override-Provider aus Umgebungsvariablen ab.
fakten:
- Vier Agent-Rollen können prozessweit auf einen anderen Provider-Stack umgeleitet werden.
  beleg: "\"quick\": os.getenv(\"ROLE_QUICK\", \"\"),"
- Fehlende Env-Variablen ergeben einen leeren Override-String.
  beleg: "os.getenv(\"ROLE_QUICK\", \"\"),"
kanten:
- wird-genutzt-von: backend/config.py::resolve_role

## backend/config.py::resolve_role
beschreibung: Liefert für eine Rolle das konkrete (provider, model)-Paar, wobei ein per Env gesetzter Rollen-Override Vorrang hat und sonst der Lauf-Provider genutzt wird.
fakten:
- Ein gesetzter Rollen-Override aus ROLE_ROUTING hat Vorrang vor dem Lauf-Provider.
  beleg: "target = ROLE_ROUTING.get(role, \"\") or run_provider"
- Die Syntax "provider:model" erlaubt es, ein bestimmtes Modell zu pinnen.
  beleg: "provider, _, model = target.partition(\":\")"
- Unbekannte Provider fallen auf den Lauf-Provider zurück.
  beleg: "if provider not in PROVIDERS:"
- Fehlt eine explizite Modellangabe, wird das Rollen-Default des Stacks genutzt.
  beleg: "model = PROVIDERS.get(provider, {}).get(role, \"\")"
kanten:
- nutzt: backend/config.py::ROLE_ROUTING
- nutzt: backend/config.py::PROVIDERS

## backend/config.py::TIMEOUTS
beschreibung: Definiert pro Agent-Schritt ein (Basis, pro-Block)-Timeout-Paar, das unabhängig vom Provider gilt.
fakten:
- Jeder Agent-Schritt hat individuelle Timeout-Werte als (Basis, pro-Block)-Tupel.
  beleg: "\"research_mapping\": (600, 3),  # n = pre-merged entries"
- Die Judge-Caps wurden am 2026-07-04 reduziert.
  beleg: "# Judge caps tightened 2026-07-04: judge p50 is 6–72 s;"
- Der `writer` skaliert mit 60 s pro Sektion.
  beleg: "\"writer\":        (450, 60),   # per section"
- QA/Repair-Wellen (`qa_judge`) skalieren nicht mit n.
  beleg: "\"qa_judge\":      (600, 0),"
kanten:
- wird-genutzt-von: backend/config.py::_apply_param_overrides

## backend/config.py::_apply_param_overrides
beschreibung: Liest ein JSON-Override-Dict aus der Umgebungsvariable CREATOR_PARAMS und überschreibt damit numerische Tuning-Konstanten dieses Moduls zur Prozess-Startzeit.
fakten:
- Bricht die Override-Anwendung still ab, wenn CREATOR_PARAMS nicht gesetzt ist.
  beleg: "if not raw:"
- Weist ungültiges JSON in CREATOR_PARAMS mit SystemExit zurück.
  beleg: "except ValueError:"
- Timeout-Overrides werden über das Präfix `TIMEOUT_` in TIMEOUTS eingespielt.
  beleg: "if key.startswith(\"TIMEOUT_\"):"
- Unbekannte Schlüssel oder boolesche Werte werden mit SystemExit abgewiesen.
  beleg: "isinstance(g[key], bool):"
- Numerische Overrides behalten den ursprünglichen Typ des Ziels.
  beleg: "g[key] = type(g[key])(val)"
kanten:
- nutzt: backend/config.py::TIMEOUTS
