# Code / Config - all tunables live in YAML, no magic numbers, no .env **Purpose + scope.** Governs where every configurable value lives. Binding for all Python code in this repository. Any new configurable parameter MUST follow this rule when deciding where it goes. The goal: one authoritative source per parameter, so regenerating any artifact with the same config is byte-identical, and changing a parameter never requires hunting constants across scripts. --- ## 1. The two YAML configs | File | Owns | Written by | |---|---|---| | `./out/config/lab_config.yaml` | The laboratory model: volumes (batches / wafers / coupons / tracks / cycles), the deposition matrix, physical-model coefficients, nominal test conditions, **the random seed 20260711** | Task 01, from the spec; regenerated only deliberately | | `./out/config/hw_prices.yaml` | Hardware cost parameters for extrapolation (RAM $/GB, NVMe $/TB, server base prices) | Task 10 seeds editable defaults; the operator may edit | Rules: - **Scripts READ these files; they never duplicate values from them.** Task 03 reads volumes, coefficients, and the seed from `lab_config.yaml` - it does not hardcode 588 coupons or seed 20260711. Task 10 reads prices from `hw_prices.yaml` - it does not inline dollar figures. - A parameter needed by more than one task lives in the YAML, never copy-pasted between scripts. - New tunables go into the appropriate YAML with a self-describing key; if neither file fits, propose a new config file in a docs/rules update first. ## 2. Spec-fixed constants - named, sourced, at the top Values fixed by the specs that are NOT operator-tunable (the 120-200 MB size gate, the 30-minute cell timeout, the 50k-row transaction batch, the 50 ms RSS sampling interval) are module-level named constants at the top of the owning script, each with a one-line comment naming the spec: ```python SIZE_GATE_MB = (120, 200) # abort bounds, spec 03 CELL_TIMEOUT_S = 30 * 60 # hard per-run timeout, spec 09 ``` A bare number inline in the logic (`if size > 209715200`) is forbidden. ## 3. The PostgreSQL DSN - one env var, never hardcoded, never logged The only external resource is the local PostgreSQL 16 instance. Its DSN: - Comes from the environment variable **`TRIBO_PG_DSN`**; default when unset: `postgresql://postgres@localhost:5432/tribo`. - Is read in ONE shared helper (e.g. `common/pg.py: get_dsn()`); scripts call the helper, never `os.environ` directly. - Is never hardcoded in a script, never committed in a config file, and never logged (a DSN may embed a password - see [obs-python-logging.md](obs-python-logging.md)). There are no other secrets in this project. There is no `.env` file; do not introduce one. ## 4. CLI flags - per-run choices only Command-line flags are for choices that vary per invocation, not for model parameters: `--log-level`, `--dry-run`, an output-root override, a `--limit` for smoke runs. A physical coefficient or a volume as a CLI flag is forbidden - it would silently fork the config out of `lab_config.yaml`. ## 5. Anti-patterns - **Hardcoding a value that exists in `lab_config.yaml`** (seed, volumes, coefficients) - the YAML is the single source; drift here breaks reproducibility silently. - **Adding a `.env` file or reading `os.environ` scattered through scripts** - the DSN goes through the one shared helper; nothing else lives in the environment. - **Inline magic numbers** for spec-fixed gates and timeouts - name them at the top with the spec reference. - **Dollar prices inlined in `extrapolate.py`** - they live in `hw_prices.yaml` so the operator can re-cost without touching code. - **A model parameter as a CLI flag** - per-run flags are for run mechanics, not for the lab model. - **Committing `./out/config/` generated files to git as if they were sources** - the YAML under `./out/` is a generated artifact; its source of truth is spec 01 (see [build-pipeline-tasks.md](build-pipeline-tasks.md)). ## 6. Related documents - [data-determinism.md](data-determinism.md) - the seed contract. - [build-pipeline-tasks.md](build-pipeline-tasks.md) - the `./out/` tree and what is git-ignored. - [obs-python-logging.md](obs-python-logging.md) - `--log-level` flag; DSN never logged.