再起動後も保持されるもの
| 状態 | ストレージ | 再起動時の動作 |
|---|---|---|
| 会話履歴 | エージェントごとのSQLiteデータベース | 変更されず、保存済みトランスクリプトからセッションが継続される |
| メインセッションの中断ターン | エージェントごとのSQLiteセッション行とトランスクリプト | 起動から数秒後に自動的に再開される |
| サブエージェントの実行 | SQLite(共有状態データベース) | 起動時にレジストリが復元され、中断された実行が再開される |
| バックグラウンドタスク | SQLite(共有状態データベース) | 起動時に整合され、孤立した実行が復旧されるか、消失としてマークされる |
| キュー内の送信待ち配信 | SQLite配信キュー | 再起動後に処理され、未配信の応答が再試行される |
| スケジュール済み(cron)ジョブ | SQLite cronストア | スケジュールが保持され、起動時にスケジューラーが再設定される |
| 再起動後の継続処理 | SQLite再起動センチネル | 再起動を要求したセッションへ1回限りのフォローアップがディスパッチされる |
正常な再起動では最初に処理を完了させる
要求された再起動(openclaw gateway restart、再起動が必要な設定変更、
またはGatewayの更新)では、実行中の処理を即座に終了しません。Gatewayは新しい処理の
受け付けを停止し、アクティブなエージェントターンとバックグラウンドタスクが完了するまで、
ドレイン予算(デフォルトでは5分)の範囲内で待機します。そのため、ほとんどの再起動では
何も中断されません。
ドレイン予算内に完了できない処理(または強制再起動やクラッシュによって中断された実行)
だけが中止されます。その前に、影響を受ける各セッションに復旧マークが付けられます。
中断された処理の検出方法
ターンが完了しなかったセッションは、相互補完的な3つの仕組みによってマークされます。- Control UIでの受け付け時: 既存のメインセッションにおける通常のテキストターンでは、
Gatewayはユーザーメッセージを追加し、セッションを実行中としてマークし、
トランスクリプト専用の配信要求を1つのSQLiteトランザクション内に記録してから、
started確認応答を返します。 コマンド、添付ファイル、ターンごとのオーバーライド、保留中の配信、以前の中止ヒント、 Plugin所有のセッション、および実行フックを伴うターンでは、それぞれ専用の受け付け経路が維持されます。 - シャットダウン時: 再起動のドレイン中、アクティブな実行があるすべてのセッションでは、 実行を中止する前に、セッションストア内に復旧マーカーが記録されます。
- 起動時: Gatewayはセッションストアをスキャンし、実行中であると記録されているものの、 新しいプロセス内に有効な所有者が存在しないセッションを検出します。これにより、 シャットダウンコードが実行されなかったハードクラッシュや強制終了も検出できます。 古くなったトランスクリプトのロックファイルも同時に削除されます。
自動再開
起動から数秒後、Gatewayはマークされた各セッションを再ディスパッチし、以前のターンが 再起動によって中断されたことと、既存のトランスクリプトから続行するよう伝える合成システム メッセージをエージェントに送ります。最終応答がすでに生成されていたものの未配信だった場合は、 そのテキストが含まれるため、エージェントは処理をやり直す代わりにその応答を配信できます。 復旧は指数バックオフを使用して最大3回再試行されます。すべての再試行で1つの永続的な ディスパッチ識別子が再利用されるため、結果が不明確な接続障害によって同じ復旧が 二重に開始されることはありません。完了済みおよび再開不能なControl UIターンにも、 有効期間が制限された永続的な冪等性トゥームストーンが保持されるため、再接続した送信ボックスは リクエストを再実行せずにそれらを処理済みにできます。 再開する前に、Gatewayはトランスクリプト末尾から安全に続行できるか確認します。 安全でない場合(たとえば、ターンが古い保留中の承認で終了している場合)、 セッションが無条件に再実行されることはありません。代わりに、エージェントは最後のリクエストを 再送するよう求める短い通知をユーザーに投稿します。WebChatでは、この通知がセッション履歴に 直接書き込まれるため、再接続後も表示されます。 OpenClawは、中断された読み取り専用のCode Mode処理も再構築できます。 Code Modeはこれらの実行を再起動安全としてマークし、副作用を伴うカタログツールやPlugin名前空間を 実行前に拒否します。再起動がwait制御時に発生した場合、新しいGatewayは
トランスクリプトからターンを再構築し、モデルがそのフラグを省略または解除しても、
再構築された実行を強制的に再起動安全に保ちます。ホストは、再起動後にCode Modeが無効化された場合も含め、
再構築されたターン全体を、監査済みの読み取り専用コアツールと、明示的に再実行安全なPluginツールのみに
制限します。副作用を伴う処理では、重複書き込みの危険を冒す代わりに、再送通知による保護が維持されます。
サブエージェント
サブエージェントの実行は共有SQLite状態データベースに永続化されるため、サブエージェント レジストリはプロセス終了後も保持されます。起動時にレジストリが復元され、中断された サブエージェントセッションは元のタスクコンテキストとともに再開されます。 次の2つの安全策が適用されます。- 2時間より前に中断された実行は、再開される代わりに完了処理されます。これにより、 一晩停止していたGatewayが古い処理を復活させることはありません。
- 復旧に繰り返し失敗するセッションは、行き詰まりとしてトゥームストーン化されるため、 復旧が無限にループすることはありません。
バックグラウンドタスク
バックグラウンドタスクレジストリはSQLiteを基盤とし、 起動時および定期的な間隔で整合されます。完了した実行によって記録された永続的な結果は復旧され、 所有プロセスが消失した実行は、永遠に停止したままになる代わりに、猶予期間後に消失としてマークされます。エージェントが要求した再起動
エージェント自体が再起動を開始する場合(設定変更の適用、Gatewayの更新、または明示的な再起動要求)、 プロセスが終了する前に再起動センチネルがSQLiteへ書き込まれます。起動後、Gatewayは結果を 発信元のチャットへ投稿し、1回限りの継続ターンをディスパッチします。これにより、エージェントは 同じチャンネルとスレッドで、中断した箇所から正確に処理を再開します。安全策と可観測性
- クラッシュループブレーカー: 5分以内に正常終了ではない起動が3回発生するとブレーカーが作動し、 次回の起動時に自動起動する補助サービスを抑止します。これにより、クラッシュするGatewayが 自身の障害を増幅することを防ぎます。正常終了ではない起動の時間枠が解消されると復旧します。
- メトリクス: 復旧アクティビティは
Prometheusを通じて
openclaw_session_recovery_totalおよびopenclaw_session_recovery_age_secondsとしてエクスポートされます。 - ログ: 復旧に関する判断は
main-session-restart-recoveryおよびsubagent-interrupted-resumeサブシステムのログに記録されます。
再開されないもの
- 別の所有者がすでに処理しているため、メインセッションの復旧対象から除外されるセッション: サブエージェントセッション(サブエージェント復旧)、cronセッション(スケジューラーが スケジュールどおりに再実行)、およびACP管理セッション(接続されたIDEまたはクライアントが 再開を所有)。
- トランスクリプト末尾から安全に続行できないセッション。この場合、暗黙的に再実行される代わりに、 前述の再送通知が送られます。
- 受け付けられなかった処理: ドレイン期間中に到着したメッセージは、終了中のプロセスに 暗黙的にキューイングされる代わりに、明示的な再起動エラーで拒否されます。