設定ライフサイクル
設定はオペレーターインターフェースであると同時にランタイム契約でもあります。明確な所有者を持つ状態として扱い、必要とするサブシステムにコピーされた緩い設定として扱わないでください。
正規の情報源は zeroclaw_config::schema::Config であり、config.toml から読み込まれます。ユーザー向けの設定サーフェス、生成される設定リファレンス、ゲートウェイの設定エディター、環境変数のオーバーライド、zeroclaw config set、zeroclaw config patch、クイックスタート、RPC の設定メソッドはすべて、この同じ型付きスキーマを経由します。
型付けされたスキーマを設定リファレンスに変換するビルド順序、追跡対象出力ルール、ドリフトチェックについては、生成ドキュメントパイプラインを参照してください。
何が何を所有するか
| Surface | 所有者 | 永続性の境界 | ランタイム適用境界 |
|---|---|---|---|
| Config schema | crates/zeroclaw-config/src/schema.rs と Configurable 派生 | コード、生成ドキュメントではない | 新しいバイナリビルド |
| 生成された参照 | cargo mdbook refs / markdown-schema | docs/book/src/reference/config.md(ビルド時) | ドキュメントのみ |
| ブートストラップの場所 | ZEROCLAW_CONFIG_DIR、ZEROCLAW_DATA_DIR、非推奨の ZEROCLAW_WORKSPACE | 環境のみ | Config が存在する前 |
| スキーマミラーのオーバーライド | ドットを __ に置き換えた ZEROCLAW_<lowercase_path> | インメモリのみ | 各 Config::load_or_init() |
| CLI設定の書き込み | zeroclaw config set、config patch、エイリアス、モデルヘルパー | save_dirty() を config.toml に | 現在のコマンドが新しいインメモリ値を使用しない限り、次回のロード/リロード |
| RPCとTUI構成の書き込み | zerocodeが使用するconfig/* RPCメソッド | save_dirty() を実行してから publish | 公開されたペアの更新は即座に反映されます。デーモンが管理するサブシステムは再読み込みが必要です。 |
| クイックスタート適用 | Web、CLI、および zerocode 共通の適用パス | 段階的な適用が完了し、設定のコミットが行われました(監視対象のサーフェス) | WebとRPCはデーモンのリロードを通知できます。スタンドアロンのCLIは次回のロード/リロード時に適用されます |
| ゲートウェイ設定の書き込み | Config API ハンドラーを persist_and_swap() 経由で処理 | save_dirty() を実行してから publish | |Published pair updates immediately を日本語に訳すと、次のようになります。 |
公開済みのペアの更新は即座に反映され、デーモンのサブシステムは再読み込み後に適用されます|
|デーモンの再読み込み|/admin/reload、RPC config/reload、またはプロセス内リロードチャネル|config.toml を再読み込みします|同じ PID でデーモンサブシステムを再作成します|
生成された設定リファレンスを手動で編集しないでください。フィールド、enum、alias セクション、secret マーカー、または説明が誤っている場合は、スキーマまたはジェネレーターを修正してリファレンスを再生成してください。
読み込み順序
設定の読み込みには、いくつかの明確なフェーズがあります:
- ブートストラップ環境変数からインストールルートを解決します。これは
Configが存在する前に行われるため、ブートストラップ名は大文字のまま維持され、スキーマミラー文法は使用されません。 config.tomlを読み込み、メモリ内でスキーマ移行を実行し、設定されたシークレットを復号し、不正な形式のセキュリティ上重要なセクションをセキュリティ低下として記録します。- スキーマミラーのオーバーライドをインメモリ設定に適用します。環境変数では、
__は.にマップされるため、ZEROCLAW_providers__models__openai__api_keyはproviders.models.openai.api_keyを対象とします。 - オペレーターがゲートウェイエディターからロックアウトされることなく、検証して警告します。
新規インストール時には、環境変数によるオーバーライドが適用される前にデフォルトが保存されます。これにより、環境変数から注入されたシークレットとローカルCIの値が新しいファイルに含まれないようになります。
環境変数のオーバーライドは保存されません
スキーマミラーの環境変数は、実行時に注入される値です。ロード時にメモリ上の Config に反映され、env_overridden_paths で追跡されるため、CLI、ダッシュボード、クイックスタートでオーバーライドマーカーを表示できます。
保存時には、暗号化の前に、これらのパスをオーバーライド前のディスク上の値またはデフォルト値へマスクして戻す必要があります。これはシークレットにおいて特に重要です。オペレーターが暗号化されたディスク上のAPIキーを持っており、同じパスに対して環境変数のオーバーライドを一時的に指定して起動した場合、無関係な設定の保存によって、実際の認証情報が環境変数の値やマスクされた表示用文字列で置き換えられてはなりません。
この不変条件を念頭に置いて、設定変更を確認してください:
ZEROCLAW_*スキーマミラー値は、ロード後の実行中プロセスに影響します。- これらは永続的な設定にはなりません。
- 保存パスでは、同じパスが意図的に編集された場合を除き、暗号化されたシークレットおよび外部シークレット参照を保持する必要があります。
資格情報の入力は型付けされたまま
認証情報に類似したランタイム値は、依然として設定値です。APIキー、OAuth トークン、エンドポイントURL、その他のプロバイダー/チャンネル認証情報は、ランタイムコンストラクターが受け取る前に、型付き設定スキーマ、設定シークレット処理、またはスキーマミラーの ZEROCLAW_* オーバーライドを経由する必要があります。
provider、channel、tool、transcription、TTS、memory、gateway のコンストラクター内に、アドホックな std::env::var("PROVIDER_API_KEY") の読み取りを追加しないでください。これにより Config の外部に 2 つ目の認証情報ソースが作成され、環境変数オーバーライドの可視性が迂回され、CLI、gateway、RPC/TUI、quickstart、reload の動作に不一致が生じる可能性があります。
ZeroClaw が連携ファミリー向けのネイティブ環境ブリッジを意図的にサポートする場合は、そのブリッジを連携境界で文書化し、構築前に同じ型付き設定値へマッピングしてください。それ以外の場合、ANTHROPIC_API_KEY、OPENROUTER_API_KEY、QDRANT_URL などのエコシステム標準のシェル名は、運用者が対応する ZEROCLAW_* スキーマミラー変数へブリッジする必要があります。環境変数を参照してください。
ダーティパスと増分書き込み
ほとんどの編集サーフェスは、完全な書き換えではなく Config::mark_dirty() と save_dirty() を使用します。save_dirty() は変更されたドット区切りパスのみを書き込み、可能な場合は dirty でないエントリとコメントを保持し、現在の schema_version をスタンプし、アトミックな一時ファイル置換を通じて書き込みます。
そのパスは、マップキーのセクションも担当します。モデルプロバイダー、MCP サーバー、スキルバンドル、ナレッジバンドルなどのエイリアスを作成する際は、エイリアスが保存と再読み込み後も維持されるよう、適切なセクションを dirty 状態にする必要があります。メモリ内のダッシュボード状態のみを更新する設定変更は不完全です。
設定の書き込みをレビューする際は、次の点を確認してください。
- 編集されたパスは永続化の前にダーティとしてマークされます。
- map-key の作成、名前変更、削除は、親セクションまたはナチュラルキーをダーティにします。
- secret および env で上書きされたパスは、その保存マスキング動作を維持します。
- 増分書き込み後も
schema_versionは最新の状態を維持します。 - 変更された値は
save_dirty()の後にリロードしても保持されます。
Full saves need load provenance
ヘッダー フル保存には読み込み元の来歴情報が必要
Config::save() は、メモリ上の値がその正確なファイルから読み込まれたものである場合(loaded_fromが設定されている場合、つまりload_or_initの既存ファイル分岐と新規初期化分岐の両方、および変更前に設定ファイルを読み直すローダーによって設定された場合)にのみ、既存のconfig.tomlを上書きします。したがって、デフォルトコンストラクタで生成されたConfig、プログラムで組み立てられたConfig、または保存先を変更されたConfigでは、運用者の設定が入力済みの既存ファイルを、ほぼ空のスナップショットで置き換えてしまうことはありません。
存在しないファイルの作成(初回実行時)は引き続き成功します。ファイルを読み込んでいない値は1回だけ作成でき、その後は再読み込みするか強制保存する必要があります。force_save() は、検証済みの意図的な上書きのための明示的な手段です。既存のファイルに上書きすることを前提に新しい Config を構築するコードパスをレビューする場合は、先に読み込むか、force_save() の呼び出しを正当化してください。
force_save() は読み込み元の検証(load-provenance check)のみをスキップします。保存先パスのチェックは引き続き適用されます。既存のファイルを置き換えるには、config_path に目的のパスを設定してください。親ディレクトリが空でないパスである必要があります。config.toml のような単なるファイル名は、実行時に解決された保存先がすでに存在する場合は拒否されます。これは、推測された保存先にあるファイルを上書きしてしまうことを防ぐ既存の安全対策を維持するためです。
保存済みと適用済み
保存が成功したことは、ファイルが変更されたことを意味します。すべてのランタイムコンポーネントが変更を反映したことを常に意味するわけではありません。
デーモンは長寿命のサブシステムグラフを所有します。ゲートウェイ、チャネルリスナー、スケジューラー、MQTT リスナー、セッション接続、メモリバックエンド、プロバイダーファクトリー、コスト接続などです。POST /admin/reload はデーモンループにシグナルを送り、デーモンループは config.toml を再読み込みして、同一プロセス内でこれらのサブシステムを再インスタンス化します。PID は変わりませんが、リスナーは一時的に再バインドされます。
Gateway の設定書き込みは persist_and_swap() を呼び出します。受理済みかつ直列化された設定コミットの内側でディスクに保存し、保存された設定を新しい公開ペアとして公開したうえで pending_reload を設定します。これにより、設定エディタは書き込みをただちに反映しますが、リロードバナーは、チャネル、プロバイダー、スケジューラー、その他のデーモン管理コンポーネントが以前のサブシステムインスタンスで動作し続けている可能性があることをオペレーターに伝えます。
スタンドアロンの zeroclaw gateway start にはデーモンスーパーバイザーがありません。シグナルを送る外部のデーモンループが存在しないため、そのリロードエンドポイントは再起動が必要であるというレスポンスを返します。
Published pair と writer のシリアライズ
監視対象プロセスは、正規の公開ペアを1組だけ保持します。すなわち Config とそのリビジョン、そして不透明な権限エポック(authority epoch)と検証済みシーケンスです。読み取り側は読み取り専用のライブハンドル(zeroclaw_config::live::LiveConfigHandle)を受け取り、設定とそのリビジョンを一つの単位として観測します。このハンドルは変更操作を公開せず、設定の第二のコピーも保持しません。
参加するすべての HTTP、RPC、TUI、Quickstart、ペアリング、チャネル ID の書き込み処理は、デーモン世代の LiveConfigAuthority(begin_config_commit)を経由して受け付けられます。コミットはプロセス全体の設定書き込みミューテックスを一度だけ取得し、その後、公開が完了するまで世代の設定書き込みリースを保持します。ミューテックスの待機中は、設定書き込みリースを保持しません。受け付け前の RPC Quickstart による予約など、別個のエージェントエイリアス予約は、依然として世代のドレイン対象としてカウントされる場合があります。不可逆フェーズ(永続化、その後、ディスク I/O の前に割り当てられたリビジョンでの公開)は保持された状態で実行されるため、キャンセルされたリクエストが、アトミックなファイル置換とその公開の間にディスパッチ済みのコミットを放棄することはありません。世代がクローズ中になると、コミットはフェイルクローズ(安全側に失敗)します。フルリロードでは、新しいエポックを持つ新しい権限が開始されます(シーケンスは同一エポック内でのみ比較されます)。
派生した受理済み認可ポリシーは、設定ペアとは別に独自の公開およびリビジョンカウンターを持つ。HTTP設定の書き込みは設定ペアより前にそのポリシーを公開し、RPC設定の書き込みはその後に公開する。これら既存の順序では、両方の公開に対する単一のアトミックな可視性境界は提供されず、ポリシーカウンターは ConfigRevision の連番ではない。
Other boundaries worth naming:
- 確定済みの公開処理は、後続の副作用が失敗しても巻き戻されません。Quickstart は、パーソナリティファイルのインストールが後で失敗しても、確定済みの設定を公開します。CLI は保存済みのエイリアスを報告し、Quickstart を再実行する代わりにワークスペースファイルの復旧を案内します。Web と RPC は、部分的な成功の後にリロードを通知しているにもかかわらず、拒否時と同じエラー結果を返し、確定済みであることを示す個別の結果を持っていません。
- config migrate エンドポイントは、ファイルを置き換える before に、完全にハイドレートされた候補(シークレットの復号、環境変数による上書きの適用、厳格な検証)を準備します。そのため、ハイドレートまたは検証できない候補は拒否され、元のファイルは変更されません。
model_routing_configとproxy_configツールは、独立して読み込んだディスク上のスナップショットを、設定コミットの受け付け処理や公開処理を経ずに保存しています。model_routing_config upsert_agentは dirty-path 永続化を使うため、無関係の値やコメントは保持されます。一方、そのほかのアクションとproxy_configは、依然として型付きスナップショット全体を書き込みます。これらの非参加型ライターは、同一パスへの同時編集を失わせたり、公開済みの読み取り側を古いまま残したりする可能性があります。participating writer 契約への移行は、別途対応が必要な作業として残っています。- 公開だけでは、実行中のサブシステムに設定は適用されません。アプリケーションの台帳には、既存の RPC モデルプロバイダーのリフレッシュによる確認応答が記録されます。その他のデーモン管理コンポーネントには、引き続き
/admin/reloadが必要です。新しいセキュリティオーバーレイとチャネル引き継ぎの動作は、ADR-012 によって引き続き制限されています。
アプリケーションの状態
GET /api/config/reload-status は pending_reload を保持し、ライブ設定の権威から application ビューを追加します。RPC config/status はオンボーディングの準備状況を保持し、同じビューを追加します。公開されるリビジョンには不透明なエポックとシーケンスが含まれます。各レコードは、実際に処理されたリビジョン、フィールド/キーの構成要素としてのセマンティックパス、およびターゲットインスタンスを識別します。ドットを含むマップキーは1つの構成要素のままです。
daemon ターゲットは queued_for_reload を、daemon_reload_required とともに報告します。既存かつ選択済みの RPC model-provider リフレッシュのみが、取得済みのセッション世代について applied_live を報告できます。そのレコードは、所有するコンシューマーが確認応答するまで pending となります。また、拒否されたインスタンス更新は rejected となります。スキーマ適用メタデータが示すのは既存のリフレッシュ機能を持つ可能性であり、実行中のインスタンスが値を採用したことの証拠ではありません。不明なパスには再読み込みが必要です。変更パスの抽出が利用できない場合、空のパスは change_scope_unavailable を伴う設定全体の再読み込み要件を意味します。
HTTP ビューにはデーモンのレコードのみが含まれます。RPC セッションのレコードには、さらに現在のセッション読み取り権限、エージェントセレクター、認証済みプリンシパルの所有権、接続の所有権、および現在のライブインカーネーションが必要です。管理者と共有オペレーターは、既存のプリンシパル所有権のバイパスを引き続き利用できます。設定値、認証情報、トランスクリプト、プロバイダーのエラーテキストがこれらのレコードに含まれることはありません。セッションを削除または置換すると、そのレコードは保護されたステータス読み取りの境界で失効します。古いコールバックがレコードを再作成したり、後継のセッションを確認応答したりすることはできません。
台帳が保持するのは、パスとターゲットごとに観測された最新の変更または試行のみです。永続的なイベント履歴や、すべてのサブシステムの一覧ではありません。保持量は record_limit で上限が定められ、truncated は削除(エビクション)が発生したことを示します。記録がないことは、アプリケーションの証拠にはなりません。無関係な編集によって、以前の確認応答が最新のリビジョンに付け替えられることはありません。完全リロード後に新しい authority が現れると、新しいエポックが始まり、記録されたライブ変更の確認応答はなくなります。pending_reload のクリアや正常な応答の返却が、アプリケーションの結果を変えることはありません。今回のスライスでは、ウォッチャーの配信やウォッチャーの健全性に関する主張は一切追加されません。
アクセスを再読み込み
ローカルリロードはループバックから許可されています。リモートリロードには両方が必要です:
gateway.allow_remote_admin = true- ペアリングが有効で、有効なペアリング済みベアラートークンがある状態
ペアリングが無効のときにリモート管理をオプトインすると、匿名のリモートリロードアクセスとして扱われるのではなく拒否されます。
セキュリティ上重要な不正な設定セクションは、オペレーターが明示的に劣化状態での提供を選択した場合にのみ、劣化を許容します。それ以外の場合、デフォルトへのリセットによるセキュリティ体制がファイルの意図よりも弱くなる可能性があるため、プロセスは提供を拒否します。
ロールバックと修復
Config書き込みはアトミックな一時ファイルの置き換えと、所有者のみの権限で行われます。既存ファイルを置き換える際、書き込み側は置き換え中に同じディレクトリに config.toml.bak を作成し、書き込みが成功した後に削除します。Gateway の書き込みでは、書き込み前のファイルもスナップショットとして保存し、新しいペアを公開する前に永続化が失敗した場合は、ベストエフォートで復元します。
保存されて適用された後の、有効だが望ましくない設定変更に対する一般的なトランザクションロールバックはありません。バックアップから以前の config.toml を復元し、CLI またはダッシュボードでフィールドを元に戻し、上記のランタイム境界に応じてリロードまたは再起動してください。
設定で可視のものが常にランタイムでサポートされているとは限らない
フィールドは、すべてのランタイムパスがそれを消費する前にスキーマ可視になり得ます。それは、ドキュメントとレビューノートが明確にそう述べている場合にのみ許容されます。
例えば、knowledge_bundles はスキーマ可視であり、config section API に現れます。そのようなサーフェスを追加または変更する PR は、設定のみを保存するのか、ランタイムの動作を配線するのか、あるいはその両方を完了するのかについて正確でなければなりません。
スキーマ上は可視だがまだ実行時には使用されていないフィールドに触れる PR をレビューする際は、実行時の配線が延期されているのか、対象外なのか、または同じ変更で完了しているのかを PR の説明に明記するよう求めてください。
レビュー担当者向けチェックリスト
設定スキーマ、環境変数、デフォルト、またはリロードの変更については、尋ねてください:
- 新しい値の信頼できる情報源は何ですか?
- これは重複した状態を作成していますか、それとも使用時に
Configから解決していますか? - 生成されたリファレンスは、手作業で維持された散文ではなくコードから来ていますか?
- env オーバーライドはロード時のみで、保存時にマスクされますか?
- CLI、gateway、RPC/TUI、および quickstart のサーフェスは、ドット区切りパスについて一致していますか?
- 認証情報は、アドホックなプロバイダー固有の env 読み取りではなく、型付き設定または文書化されたスキーマミラー ブリッジを通じて解決されますか?
- 保存は、単なる即座のインメモリレンダリングだけでなく、プロセスのリロード後も存続しますか?
- PRには、ユーザーがリロード、再起動、マイグレーション、または手動ロールバックを必要とするかどうかが記載されていますか?
- フィールドが設定でのみ可視の場合、PR はランタイムサポートを主張することを避けていますか?
ソースポインタ
- 設定スキーマと永続化:
crates/zeroclaw-config/src/schema.rs - Published pair storage and read-only handle:
crates/zeroclaw-config/src/live.rs - ライブ設定の権限、コミット、ライフサイクル:
crates/zeroclaw-runtime/src/live_config_authority.rs - 環境変数オーバーライドの構文:
crates/zeroclaw-config/src/env_overrides.rs - 設定 CLI コマンド:
src/main.rs - RPC および TUI の設定メソッド:
crates/zeroclaw-runtime/src/rpc/dispatch.rs - 共有クイックスタートの適用パス:
crates/zeroclaw-runtime/src/quickstart/mod.rs - Web Quickstart のリロードシグナル:
crates/zeroclaw-gateway/src/api_quickstart.rs - ゲートウェイ設定APIおよびリロードバナー:
crates/zeroclaw-gateway/src/api_config.rs - リロードエンドポイントとアクセスゲート:
crates/zeroclaw-gateway/src/lib.rs - Gateway Bearer 認証ヘルパー:
crates/zeroclaw-gateway/src/api.rs - 生成されたリファレンスパイプライン:
xtask/src/cmd/mdbook/refs.rs