Skip to content

設定システム

源码版本rust-v0.145.0

codex の設定 (config) は単一ファイルの読み込みではなく、多層の重ね合わせだ:config.toml は system / user / project / cloud bundle / session flags の複数の出所から来て、precedence に従い effective config にマージされ、さらに ConfigRequirements で制約検査される。config crate が層叠とマージを担い、codex-homeCODEX_HOME の解決とグローバル AGENTS.md の読み込みを提供し、core/src/config/mod.rs がマージ結果を Config に詰めて Agent メインループに渡し、core/src/config_lock.rs が lockfile で再現可能実行を保証する。cli/src/login.rs が auth.json を書き、ログイン状態も設定層の一部だ。

責務

  1. codex home の特定:find_codex_homeCODEX_HOME を読み、未設定なら ~/.codex にフォールバックする(codex-rs/core/src/config/mod.rs:4440-4442)。
  2. 多層読み込み:load_config_layers_state が system / managed / cloud bundle / user / project / session flags の各層を順に読み込み、ConfigLayerStack を産出する(codex-rs/config/src/loader/mod.rs:116-168)。
  3. effective config のマージ:ConfigLayerStack::effective_config が precedence の低い順に TOML を merge する(codex-rs/config/src/state.rs:483-492)。
  4. 実行時 Config の組み立て:ConfigBuilder が codex_home、cli_overrides、harness_overrides、cloud bundle をまとめて build().await する(codex-rs/core/src/config/mod.rs:1258-1297)。
  5. ログイン状態の書き込み:login_with_chatgpt / run_login_with_api_key がログインフローを走らせた後、クレデンシャルを auth.json に落とす(codex-rs/cli/src/login.rs:137-165)。

設計動機

単一ファイル config.toml はシンプルだが、企業デプロイは多ソース重ね合わせを要求する:MDM が押し下ろした強制ポリシーはユーザが変えられず、プロジェクトの .codex/config.toml はユーザ全体を上書きし、CLI flag はさらにプロジェクト設定を压さなければならない。codex は各層を ConfigLayerEntry に抽象し、ConfigLayerSource::precedence が返す数字でマージ順序を決める——Session flags(30)は Project(25)を压し、Project は User(20)を压し、User は System(10)を压し、System は MDM(0)を压す。新ソースの追加は enum variant を増やして数字を返すだけでよく、マージロジックは触らなくてよい。cloud bundle は後に追加された層で、ChatGPT バックエンドから enterprise-managed config と requirements を引き、load_config_layers_state の中で CloudConfigBundleLayers::from_bundle で普通の layer に変換して stack に詰め込み、ローカル TOML と同じマージパスを通る。config_lock.rs は再現性のためにある:マージ結果の ConfigToml + codex version を ConfigLockfileToml にシリアライズし、再再生時に validate_config_lock_replay が expected と actual を比較し、version かフィールドが不一致ならエラーにする。これで同じ prompt が異なるマシンで異なる結果になるのを避ける。

主要ファイル

codex-rs/config/src/config_layer_source.rs:6-49ConfigLayerSource enum と precedence()。8 種の出所とマージ順序を定義。codex-rs/config/src/loader/mod.rs:116-168load_config_layers_state。system / managed / cloud bundle / user / project の各層を順に stack に詰める。codex-rs/config/src/state.rs:483-492effective_config。precedence の低い順に merge_toml_valuescodex-rs/core/src/config/mod.rs:614-673Config 構造体。実行時に受け取る「最終設定」オブジェクト。model_provider、permissions、enforce_residency などを含む。codex-rs/core/src/config/mod.rs:1258-1297ConfigBuilder。codex_home、cli_overrides、harness_overrides、cloud bundle を組み立てて build().awaitcodex-rs/core/src/config/mod.rs:1721-1728Config::load_with_cli_overrides。最もよく使う入口。codex-rs/core/src/config_lock.rs:38-74config_lockfilevalidate_config_lock_replay。ロックファイル生成と再再生検証。codex-rs/codex-home/src/instructions/mod.rs:14-68CodexHomeUserInstructionsProvider~/.codex/AGENTS.md からグローバルユーザ指示を読み込む。

ConfigLayerSource は 8 種の出所を enum に圧縮し、precedence の数字がマージ順序を決める:

rust
// config/src/config_layer_source.rs:6-48 — 来源 + 优先级
pub enum ConfigLayerSource {
    Mdm { domain: String, key: String },            // 0
    System { file: AbsolutePathBuf },               // 10
    EnterpriseManaged { id: String, name: String }, // 15
    User { file: AbsolutePathBuf, profile: Option<String> }, // 20 或 21
    Project { dot_codex_folder: AbsolutePathBuf },  // 25
    SessionFlags,                                     // 30
    LegacyManagedConfigTomlFromFile { .. },          // 40
    LegacyManagedConfigTomlFromMdm,                  // 50
}

impl ConfigLayerSource {
    pub fn precedence(&self) -> i16 {
        match self {
            ConfigLayerSource::Mdm { .. } => 0,
            ConfigLayerSource::System { .. } => 10,
            ConfigLayerSource::SessionFlags => 30,
            // ...
        }
    }
}

effective_config は precedence の低い順に逐次 merge し、後に書いたものが先に書いたものを上書きする:

rust
// config/src/state.rs:483-492 — 合并层叠
pub fn effective_config(&self) -> TomlValue {
    let mut merged = TomlValue::Table(toml::map::Map::new());
    for layer in self.get_layers(
        ConfigLayerStackOrdering::LowestPrecedenceFirst,
        /*include_disabled*/ false,
    ) {
        merge_toml_values(&mut merged, &layer.config);
    }
    merged
}

config_lock は当時のマージ結果を锁し、次回再再生時に TOML フィールドの差分を比較する:

rust
// core/src/config_lock.rs:46-74 — 锁文件重放校验
pub(crate) fn validate_config_lock_replay(
    expected_lock: &ConfigLockfileToml,
    actual_lock: &ConfigLockfileToml,
    options: ConfigLockReplayOptions,
) -> io::Result<()> {
    validate_config_lock_metadata_shape(expected_lock)?;
    validate_config_lock_metadata_shape(actual_lock)?;
    if !options.allow_codex_version_mismatch
        && expected_lock.codex_version != actual_lock.codex_version
    {
        return Err(config_lock_error(format!(
            "config lock Codex version mismatch: lock was generated by {}, current version is {}; ...",
            expected_lock.codex_version, actual_lock.codex_version
        )));
    }
    // ...继续 TOML 字段对比,不一致时用 similar 算 diff 报错
}

データフロー

境界と失敗

  • CODEX_HOME は必ずディレクトリ:環境変数が設定されていても存在しないかディレクトリでなければ直接エラーになり、黙って ~/.codex にフォールバックしない(codex-rs/core/src/config/mod.rs:4436-4442)。
  • 無効な設定は致命的ではない:Config::load_default_with_cli_overrides はユーザ設定ファイルのパース失敗時にデフォルト + cli overrides にフォールバックし、CLI が起動できることを保証する(codex-rs/core/src/config/mod.rs:1731-1740)。
  • config_lock の version 不一致はデフォルトでエラー:codex version が不一致なら再再生を拒否し、明示的に debug.config_lockfile.allow_codex_version_mismatch=true を設定した場合だけ通す(codex-rs/core/src/config_lock.rs:54-61)。
  • AGENTS.md の優先度:同ディレクトリで AGENTS.override.mdAGENTS.md より優先し、最初の非空ファイルだけを読み、重ね合わせの曖昧さを避ける(codex-rs/codex-home/src/instructions/mod.rs:26-67)。
  • cloud bundle は企業アカウントのみ取得:cloud_config_eligible_authuses_codex_backend かつ plan が Business/Enterprise/Edu であることを要求する(codex-rs/cloud-config/src/service.rs:47-54)。

まとめ

設定システムは多ソース(system / user / project / cloud / session flags)を precedence() の数字で Config にマージし、cloud bundle はローカル TOML と同じ merge_toml_values パスを通る。ログイン状態は auth.json に書かれ、Model ProviderAuthManager が読む。ConfigLockfileToml がマージ結果を锁して再現性を保証する。クラウドタスクが使う enterprise ポリシーは Cloud Tasks パス内の cloud-config サービスが定期的にリフレッシュし、ローカル cache に落ちた後にここで effective config に読み込まれる。