70e4938c07
`hermes config set FEISHU_HOME_CHANNEL oc_x` wrote the top level of config.yaml while the platform setup flows and /sethome write the same name to .env via save_env_value, so two writers fed two readers: the gateway bridges the yaml copy into the environment only when .env lacks the name, one-shot CLI readers never bridge, and the two copies diverged silently (#111848). Only credential-shaped names were routed to .env because `_is_env_config_key` is the provider-credential predicate. Follow-up to KoNit-K's cherry-picked fix (#111850), which routed the `setup_hidden_env` suffix family: the predicate now lives in the topical sibling `hermes_cli/config_env_routing.py` and covers every bare name Hermes itself registers as an environment variable (OPTIONAL_ENV_VARS, _EXTRA_ENV_KEYS — "env var names written to .env" — plus the setup-hidden suffixes for plugin adapters nobody enumerated), so `*_ALLOWED_USERS`, `WHATSAPP_MODE`, `MATRIX_PASSWORD` and the rest of the adapter-saved family take the same file. `set` and `unset` also drop a stale same-named top-level config.yaml copy so the reporter's drift cannot come back, and `get` resolves .env first then that copy — the gateway's own read order. Provider credentials keep the credential_lifecycle rotation path. Docs: environment-variables.md tip, hermes_cli/AGENTS.md config rule.