* tests/integration/meta/env/test_dotenv_generator.py picks up a
module-level `STATIC_READS` tuple on every dynamic handler module
under utils/env/handlers/, in addition to PASSTHROUGH_STATIC_KEYS
and GHA_STATIC_KEYS. So a handler that pulls its fallback from
`ctx.static[KEY]` (e.g. infinito_outer_network_mtu) can declare
the key it reads without flipping the drift detector.
* utils/env/handlers/infinito_outer_network_mtu.py exports
`STATIC_READS = (KEY,)` accordingly and marks the two live system
reads (`/proc/net/route`, `/sys/class/net/<iface>/mtu`) with
`# nocheck: cache-read` since the cached-read lint forbids
uncached `Path.read_text` calls inside utils/.
* utils/env/loader.py marks the `INFINITO_ENV_LOADED` sentinel with
`# nocheck: env-loader-internal-guard` so the registry-drift lint
does not treat the idempotency flag as a missing config key.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Direct `infinito <subcmd>` calls from an interactive shell skipped the
bash env loader (`scripts/meta/env/load.sh`) and crashed on any module
that strict-reads an INFINITO_* key without a Python-side default —
the trigger was `infinito contributing update repository` raising
`KeyError: 'INFINITO_WORKER_FETCH'` from `resolve_max_fetch_workers`,
which only exists in `.env` because it is computed dynamically by
`make dotenv` (INFINITO_WORKER_CPU * 20).
Adds `utils.env.loader.load_dotenv_once()`: walks up from a start
path until it finds `.env`, parses it via the existing
`parse_static_env`, and injects each key with `os.environ.setdefault`.
Idempotent via `INFINITO_ENV_LOADED=1` to mirror the bash loader so
make-dispatched calls (which already set the flag) skip the work.
`cli/__main__.py` calls it once right after the sys.path bootstrap and
before importing `cli.core.app`, so every subcommand and transitive
import sees the defaults. Caller-set env vars still win — only
unset keys are filled.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>