RUL-003 — Env config from the active env profile, read at call time — no hardcoding, no literal infra defaults

Ruling

Read env config with inline os.environ.get("X", default) at call time — never a bare os.environ["X"], never a hardcoded literal, and never an import-time constant when the value must be override-able at runtime.

INVERSE for REQUIRED infra endpoint keys (the keys that select which live infra you talk to — REDIS_HOST, REDIS_PORT, KG_ROUTING_URI, KG_URI, KG_DATABASE, MEMGRAPH_URI, CXP_GRPC_PORT, KG_GRPC_PORT): these carry NO default and RAISE when unset. A .get(KEY, default) on them (even "localhost" / "") is FORBIDDEN — an unset key must fail loudly, never silently connect to the wrong server (the classic bug: a default of the PRODUCTION Redis/graph). Route through the raising seams core.graph_factory.resolve_uri/resolve_kg_database and core.redis_factory.resolve_redis_host/resolve_redis_port.

Endpoints come from the active env profile (since the isolated-fleets cutover): ORCHESTRATA_ENV_PROFILE (default test) selects a committed, endpoint-only env/{dev,test,prod}.env, layered over a secrets-only .env by each entrypoint's _load_dotenv() (profile overlays with override=True). Never hardcode an Incus IP; if a container IP changes, only the relevant env/<profile>.env is edited. The suite is hard-pinned to env/test.env by tests/conftest.py (overlay + prod-subnet guard), so tests cannot land on the prod fleet (10.53.1.x) — the authoritative suite target is the isolated test fleet (10.53.2.x).

Evidence

Enforcement

Verification

scripts/code-review.py's BARE_OS_ENVIRON check flags os.environ["X"] subscript reads; its ConnectionStringChecker raises ENV_DEFAULT (ERROR) whenever an env-var read for a known infra key carries a hardcoded default; serialize_codebase_ast.py standards gates bare-env-access as a Key-Rule violation. The no-literal-default inverse is scanned by core.infra_env_rule.find_infra_env_defaults, enforced as the check_infra_env_defaults review check and as scripts/validate_ci.py Gate 12; standards rule 30d states the rule in the rulebase agents load.