AppView — clean explicit threading. Config::load() already has load_from(path), so: 1. Config::load(override_path: Option<&Path>) delegates to load_from with path resolution 2. load_config_or_exit takes the override 3. Each command's execute() takes the override 4. main.rs passes cli.config_dir through, no more set_var
CLI — OnceLock in config.rs. data_dir() is called from 10+ functions across config/session/identity/commands, so threading a parameter would cascade everywhere. OnceLock is set once at startup, read anywhere — typed, safe, explicit, no set_var.
Tests keep using OPAKE_DATA_DIR env var behind the mutex (test harness in utils.rs). The env var remains a fallback in data_dir() after the OnceLock check.
Two different fixes for the same pattern:
AppView — clean explicit threading. Config::load() already has load_from(path), so: 1. Config::load(override_path: Option<&Path>) delegates to load_from with path resolution 2. load_config_or_exit takes the override 3. Each command's execute() takes the override 4. main.rs passes cli.config_dir through, no more set_var
CLI — OnceLock in config.rs. data_dir() is called from 10+ functions across config/session/identity/commands, so threading a parameter would cascade everywhere. OnceLock is set once at startup, read anywhere — typed, safe, explicit, no set_var.
Tests keep using OPAKE_DATA_DIR env var behind the mutex (test harness in utils.rs). The env var remains a fallback in data_dir() after the OnceLock check.