Skip to content

Configuration Register

Verified against the code · 4996d1ceb770fb4545edebc5fd140792bfb23830 · 2026-10-20

956 D1b-4 (2026-10-20): 1 finding(s) fixed — the residual env reads now match the test_env_read_guard baseline (4 files/7 reads: run.py PORT/WORKERS, server.py LICENSE_KEY/LICENSE_FILE/PYTEST_CURRENT_TEST, the setup_router passthrough, the eidos_loader EIDOS_FILE presence check), the exempt iam/config.py and infra/log_config.py readers are named, and run.py's own WORKERS fallback is noted. Re-verified against main 4996d1ce.

backend/infra/config.py is the canonical owner of environment-derived configuration. It replaced two predecessors that the audit flagged: the 0-importer decoy server_config.py, and the narrower runtime_config.py (trin 0.8) — both retired into it at trin 2.2.

One default per variable

The register fixes the audit's divergent-default findings (owner decisions #555):

  • BASE_URL → http://localhost:8080 (an empty default silently produced relative reset/invite links; the register's own validate() surface warns when a primary runs localhost).
  • Session DB → <backend>/sessions.db (the former split — api/sessions.db for auth vs infra/sessions.db for notifications — meant the two subsystems read different session stores on an unset env).
  • DOMAINS_FILE → <backend>/domains.json (was three separately-computed path expressions).

Sole reader, sole parser, sole default

  • Sole env reader. Application config is read only here (the guard also exempts iam/config.py for IAM_ENABLED and infra/log_config.py for LOG_FORMAT/LOG_LEVEL); the env-read guard (test_env_read_guard, baseline 3 files / 6 reads) freezes the residual reads outside them: run.py PORT and WORKERS (the container entrypoint's uvicorn launch), server.py LICENSE_KEY, LICENSE_FILE and PYTEST_CURRENT_TEST (license gate and test detection), and the api/setup_router.py subprocess env passthrough. The legacy data-file path comes from eidos_file() (default /data/data.eidos; #935 S4b): persistence/eidos_loader.py only checks it exists, never reads it (#935 S5a), and the /info and admin sizing reports name it.
  • Sole domains parser. load_domains() / domain_maps() is the single domains.json reader (server, metrics and reports consume it).
  • Sole WORKERS default. workers_default() (4) is the one source for the compose generator; targets override per-flow (the new-customer flow pins 2). run.py reads WORKERS itself at launch with its own "4" fallback.

Re-liftable

snapshot() returns an immutable EidosConfig built once from the environment — shaped so eidos-core's DomainContract can be constructed from it unchanged at re-lift. The register imports only the stdlib (no import server), so it sits at the bottom of the dependency graph.