ランタイムの状態と永続化
ZeroClaw のインストールルートは1つですが、モノリシックな「ワークスペースデータベース」は1つではありません。状態の各領域には、それぞれ異なる所有者、リロード動作、永続性があります。変更によって状態を追加する、状態を移動する、設定をキャッシュする、リロードに影響する、またはセッション/メモリ/ログ/コストの動作を変更する場合は、このマップを使用してください。
単一の信頼できる情報源のルールは引き続き適用されます。ある事実がすでに1つのサーフェスに存在する場合、それを別の保存フィールドにコピーしないでください。新しい状態は、このテーブルが所有するサーフェスを特定した場合にのみ保存するか、使用時に正規の所有者から解決してください。
インストールレイアウト
通常のインストールでは、<install> は解決済みの設定ディレクトリです(デフォルトは ~/.zeroclaw/。Homebrew および明示的な --config-dir によるインストールでは移動できます)。現在のレイアウトは次のとおりです:
<install>/
├── config.toml # canonical user config
├── .secret_key # key for encrypted secrets
├── data/ # instance-wide runtime data
│ ├── sessions/
│ │ ├── sessions.db # default chat/session backend
│ │ └── acp-sessions.db # ACP protocol sessions
│ ├── cron/jobs.db # scheduled job state
│ ├── sop/runs.db # optional durable SOP run state
│ ├── control_plane.db # task supervision records
│ ├── state/
│ │ ├── runtime-trace.jsonl # persisted logs
│ │ └── costs.jsonl # cost ledger
│ ├── devices.db # paired-device metadata
│ └── memory/ # shared instance memory stores
├── shared/ # shared resources, such as skill bundles
└── agents/<alias>/workspace/ # per-agent filesystem sandbox and identity
レガシーの <install>/workspace/ という名前は移行中も引き続き受け付けられますが、新しいランタイム状態は <install>/data/、<install>/shared/、およびエージェントごとのワークスペースの観点で記述してください。
状態マップ
| Surface | 正規ソース | 永続パス | インメモリ所有者 | リロード/同時実行の境界 | 注釈 |
|---|---|---|---|---|---|
| 設定値 | config.toml から読み込まれた zeroclaw-config::Config | <install>/config.toml | daemon Arc<RwLock<Config>> とサブシステムごとの解決済みビュー | /admin/reload は設定を再読み込みし、daemon サブシステムを再インスタンス化します。設定の直接書き込みでは、スキーマ検証と dirty-path チェックが使用されます。RPC 側の設定変更ではさらに、読み取り・変更・フラッシュのセクション全体を RpcContext::config_write_lock で直列化します(tokio mutex を先に、parking_lot RwLock を後に取得し、.await または lock().await をまたいで parking_lot ガードを保持することはありません)。gateway の HTTP 設定変更でも同様に、読み取り・変更・スワップのセクション全体を AppState::config_write_lock で直列化します(ロック順序は同じです) | キャッシュがリロード時に明示的に再構築される場合を除き、設定から導出された事実を長寿命の構造体にキャッシュしないでください。 |
| 設定保存の永続性 | save() / save_dirty() の zeroclaw-config におけるアトミック書き込みパス | <install>/config.toml と保持された config.toml.bak | 設定値と同じ | 書き込みは、一時ファイル、置換前のディレクトリ同期、アトミックな名前変更、置換後のディレクトリ同期を経て行われます | Ok(()) は置換が可視になったことを示すのであって、rename の永続性が証明されたことを示すものではありません。置換前に失敗した場合は、ディスク上の設定と実行中の設定を変更しないまま中止されますが、rename 後のディレクトリ同期に失敗しても、警告がログに記録され、config.toml.bak が保持された状態で Ok(()) が返されます。このような保存の直後にクラッシュすると、ディレクトリエントリが以前のファイルを再び指す可能性があります。呼び出し元は Ok を、より強い永続性保証として扱ってはならず、復旧時には保持された .bak を参照できます。 |
| 暗号化されたシークレット | Config のシークレットフィールドと .secret_key | <install>/config.toml、<install>/.secret_key | zeroclaw-config の secret-store ヘルパー | リロードで変更された設定が検出されますが、.secret_key を失うと暗号化された設定シークレットが復元不能になります | 決して復号された値をログ、ドキュメント、PR本文、またはランタイムメタデータにコピーしないでください。 |
| エージェントのファイルシステムアイデンティティ | エージェントごとのワークスペースファイル | <install>/agents/<alias>/workspace/ | 実効的な SecurityPolicy とエージェントプロンプトの構築 | エージェント起動時に遅延作成されます。ワークスペースへのアクセスは設定から評価されます | これはファイルシステムサンドボックスであり、プロバイダー/チャンネル/ツールの設定ソースオブトゥルースではありません。 |
| 共有スキルバンドル | 設定済みのスキルバンドルエントリと解決済みのバンドルディレクトリ | <install>/shared/skills/<bundle>/(デフォルト) | スキルの読み込み / プロンプトの拡充 | リロードと新しいエージェントの起動で設定とファイルシステムの変更を監視します | バンドルエイリアスとディレクトリ解決は設定から取得されます。ファイルはバンドルの内容です。 |
| 会話メモリ | zeroclaw-memory バックエンドがエージェントごとに選択されました | SQLite/Postgres/Lucid/Qdrant/Markdown バックエンドの格納場所。SQLite 共有ストアは data/memory/ 配下に配置されます | Arc<dyn Memory>(エージェントスコープのアダプターでラップ) | バックエンドの選択は、エージェントがデータを書き込んだ後はロックされます。同じバックエンドでのクロスエージェント・リコールはオプトインです | メモリ行はエージェントスコープです。コピーしたプロンプト/セッションキャッシュでメモリの所有権を置き換えないでください。 |
| チャットとチャンネルのセッション | [channels].session_backend および SessionBackend | デフォルトは data/sessions/sessions.db;レガシー/明示的な JSONL では data/sessions/*.jsonl を使用します | zeroclaw-infra バックエンドハンドルは現在、チャネル、ゲートウェイ、RPC、セッションツールによって個別に構築されています | SQLite バックエンドは WAL を使用します。SessionActorQueue はセッションごとのアクティブなターンを直列化します。JSONL の変更処理はプロセスローカルな sessions ディレクトリのロックを共有します | Chat/Code セッションでは統合バックエンド契約を使用します。ACP プロトコルセッションでは別のストアを使用します。プロセス単位のバックエンド所有権は、まだ一元管理されていません。 |
| ACP セッション | ACP プロトコル セッションストア | data/sessions/acp-sessions.db | AcpSessionStore はデーモン起動時と RPC コンテキストで開かれます | チャットセッションとは別の、WALバックアップ付きSQLiteストア | ACP session/load および session/resume は、チャットセッションのバックエンドではなく、このプロトコルストアに対して動作します。 |
| ライブ RPC/TUI セッション | RPC SessionStore | none by itself | crates/zeroclaw-runtime/src/rpc/session.rs のインメモリマップ | プロセスローカル。セッション履歴はチャットまたはACPバックエンドを通じてのみ永続化されます | ライブセッションハンドル、アップロード、キャンセルトークン、オーナー、およびオーバーライドはランタイム状態です。 |
| Cron ジョブ | 宣言的設定メンバーシップと cron SQLite ストア | data/cron/jobs.db | zeroclaw-runtime::cron スケジューラー/ストア | 読み取りパスでは jobs.db を作成しません。スケジューラが期限/ロックの状態を管理します | 宣言的ジョブは設定からリコンサイルされ、実行メタデータとロックはcron DBに存在します。 |
| SOP の実行 | SopEngine と SopRunStore | デフォルトでは None。永続 SQLite の初期化に成功した場合は data/sop/runs.db | SOPエンジンのアクティブ/完了済み実行キャッシュ | 永続ストアはアドミッション要求と永続化されたリビジョンを管理し、エンジンは起動時にアクティブ状態と終端状態を復元します | ストアの初期化に失敗すると、警告をログに記録してメモリにフォールバックします。メモリ上の監査レコードは、実行ライフサイクルの正本ではありません。 |
| バックグラウンドタスクの監視 | 永続タスクのコントロール プレーン | data/control_plane.db | コントロールプレーンハンドル、タスクプロデューサー、およびリーパー | オーナー PID/ブート ID は以前のブート時の孤立プロセスを識別します。ハートビートタイムアウトはハートビートを送信するプロデューサーにのみ適用されます | 現在の delegate/subagent プロデューサーはベストエフォートの行を登録しますが、heartbeat、parent、route、principal フィールドは未設定のままです。Goal API は存在しますが、エンドツーエンドの goal 実行はまだ結線されていません。 |
| バックグラウンド委任結果 | デリゲート結果レコード | <workspace>/delegate_results/<task-id>.json | デリゲートツールのキャンセルレジストリと実行中のフューチャー | 再起動後も結果ファイルは保持されますが、ライブキャンセルハンドルは保持されません | 読み取りはファイルを優先し、ファイルがまだ running を示している場合に限り、lost または timed_out の監視状態を上書きします。結果の書き込みとコントロールプレーンの書き込みは独立しており、乖離する可能性があります。 |
| ランタイムログ | zeroclaw-log イベントスキーマとサブスクライバーレイヤー | 永続化が有効な場合の data/state/runtime-trace.jsonl | broadcastフック、JSONLライター、/api/logsリーダー、Observerブリッジ | ローリング/フル/なしの永続化は設定で制御されます。JSONL が無効になっている場合でも、ダッシュボードの SSE はイベントを受信します | ログは証拠とオブザーバビリティであり、ユーザー設定やセッション状態のソースではありません。 |
| コスト台帳 | CostTracker に加えてレート設定 | data/state/costs.jsonl | プロセスグローバルな CostTracker | リロードは CostConfig をホットスワップします。コスト追跡が有効になった場合、トラッカーはオンデマンドで構築されます | 既存のレコードは記録された価格を保持します。レートの編集はリロード後の将来のリクエストに影響します。 |
| ゲートウェイ ペアリングトークン | gateway.paired_tokens の PairingGuard | 設定内のトークンハッシュ | ペアリングガード | Reloadは設定からguardを再構築します | 有効なベアラートークンは設定状態であり、devices.db の行ではありません。 |
| ペアリング済みデバイスのメタデータ | トークンハッシュをキーとするデバイスレジストリの行 | data/devices.db | DeviceRegistryキャッシュとSQLite | レジストリはメタデータを正規のペアトークンセットと照合します | このDBはペアリングされたデバイスを表示・管理可能にします。有効なトークンを生成するものではありません。 |
| ヘルスとコンポーネントのステータス | サブシステムの実行がコンポーネントの状態を報告します | sop_executeツールによってトリガーされます(zeroclaw sop run CLI コマンドではありません)。 | ゲートウェイのヘルス/ステータス状態 | プロセスローカル。デーモンの再起動またはリロード時にリセット/再構築されます | /health、/api/health、/api/status は現在の観測値であり、永続的な設定ではありません。 |
| キュー、デバウンサー、ウォッチドッグ | zeroclaw-infra プロセスユーティリティ | 呼び出し元が結果を別の場所に保存しない限り、なし | インメモリのキュー/デバウンサー/ウォッチドッグ | プロセスローカル。シリアライズ、統合、またはストールの検出に使用されます | これらは調整状態として扱ってください。これらが保護するドメインデータのみを永続化し、キュー自体は永続化しないでください。 |
リロードして再起動
POST /admin/reload はデーモンにプロセス内リロードシグナルを送信します。外側のデーモンループはディスクから設定を再読み込みし、デーモンを再実行して、新しい設定からゲートウェイ、チャネル、ハートビート、スケジューラ、MQTT、セッション、メモリ、コストの各配線を新規に作成します。PID は変わりませんが、リスナーは一時的に再バインドされます。
完全なプロセス再起動は、ライブRPCセッション、ヘルススナップショット、アクターキュー、および一時的なツールレシートキーなどのプロセスローカル状態もローテーションします。永続ストアは上の表に従って再起動後も存続します。
セッションバックエンドの移行
SQLite セッションバックエンドを選択すると、バックエンドハンドルの構築時にレガシーな data/sessions/*.jsonl ファイルがインポートされます。インポーターは、プロセスローカルの JSONL 変更ロックを保持したまま各ソースをプライベートな .jsonl.importing 世代に移動し、1 つの SQLite トランザクションでメッセージ、メタデータ、ソースに紐付けられたインポートレシートを書き込み、その後ロールバック用にソースを .jsonl.migrated として保持します。
レシートは、ソースファイル名、セッションキー、SHA-256ダイジェスト、バイト長を紐付けます。レシートトランザクションが開始する前に、インポーターはステージ済みソースファイルを同期し、Unixではライブからステージ済みへのディレクトリ名変更も同期します。移行トランザクションでは、インポートコミットに完全なSQLite同期を使用してから、通常のランタイム設定に戻します。アーカイブへの引き渡しでも、ステージ済みソースを削除する前に、Unixでディレクトリメタデータを同期します。バックエンドの構築では、ソースファイルをスキャンする前に、永続化されたレシートからプロセスローカルの非アクティブ状態を復元します。インポートレシートがコミットされるとすぐに、そのセッションディレクトリに対するJSONLの変更は、アーカイブへの引き渡しや後続ファイルが失敗した場合でも非アクティブなままになります。次回の構築では、そのレシートと照合してステージ済みソースを検証し、重複メッセージを挿入せずに引き渡しを完了できます。空または空白のみのJSONLファイルは、メッセージ数0のSQLiteセッションとして保持されます。有効なメッセージがない空でないソースは、引き続きフェイルクローズします。
ソースをインポートせずに SQLite バックエンドを構築しても、JSONL ミューテーションは無効化されません。そのため、永続的なインポートレシートが存在しない場合、インプロセスのリロードによって JSONL に戻る可能性があります。
レシートのないソースは、同じセッションキーの既存の SQLite メッセージやメタデータにマージされません。そのコミット前チェックに失敗した場合、ステージ済みソースは稼働中の JSONL パスに復元されます。互換性のないレシート、ステージ済みソース、またはアーカイブがあると、バックエンドの構築はエラーを返します。各プロセスのエントリーポイントは現在、そのエラーによってサブシステムを停止するか、永続化を無効にするかを個別に判断します。プロセスレベルの所有権と起動ポリシーは、移行契約とは別です。
バックアップと復元
通常の単一インスタンスのインストールでは、<install> ディレクトリ全体をバックアップしてください。最低限、以下を含めてください:
config.toml- 暗号化されたシークレットを使用する場合は
.secret_key data/memory/data/sessions/- ランタイムサーフェスを通じて cron ジョブが構成されている場合は
data/cron/jobs.db - 永続的なSOP実行が有効な場合は
data/sop/runs.db data/control_plane.db(監視対象タスクの履歴が重要な場合)- コスト履歴が重要な場合は
data/state/costs.jsonl - インシデントレビューでログが必要な場合は
data/state/runtime-trace.jsonl - ペアリング済みデバイスのメタデータ用の
data/devices.db
同じインストールルートに対して2つのデーモンを実行しないでください。いくつかのストアはシングルライターモデルのSQLiteを使用しており、プロセスローカルのキャッシュは1つのデーモンがそのインスタンスを所有していると想定しています。
ソースポインタ
- 設定、install-root、および data-dir の解決:
crates/zeroclaw-config/src/schema.rs - セッションバックエンド:
crates/zeroclaw-infra/src/session_sqlite.rs、crates/zeroclaw-infra/src/session_store.rs - ACP セッションストア:
crates/zeroclaw-infra/src/acp_session_store.rs - RPC ライブセッション:
crates/zeroclaw-runtime/src/rpc/session.rs - Cron の永続化:
crates/zeroclaw-runtime/src/cron/store.rs - SOPの永続化:
crates/zeroclaw-runtime/src/sop/store/ - バックグラウンドタスクとゴール監視:
crates/zeroclaw-runtime/src/control_plane/ - バックグラウンド委任の結果:
crates/zeroclaw-runtime/src/tools/delegate.rs - ログ:
crates/zeroclaw-log/ - コスト台帳:
crates/zeroclaw-config/src/cost/tracker.rs - ペアリングガード:
crates/zeroclaw-config/src/pairing.rs - デバイスレジストリ:
crates/zeroclaw-gateway/src/api_pairing.rs - リロードエンドポイント:
crates/zeroclaw-gateway/src/lib.rs