Gateway
再起動からの復旧
Gateway を再起動してもエージェントの状態は失われません。会話、トランスクリプト、 スケジュール済みジョブ、バックグラウンドタスクの記録、キューに入った送信メッセージはすべて ディスク上に保存され、ターンの途中で中断された作業は Gateway の復旧後に 自動的に検出され、再開されます。復旧は常に有効であり、 通常は手動介入を必要としません。復旧が繰り返し失敗する場合は回数が制限され、 調査または置換するまで、1 つのセッションが隔離されることがあります。
このページでは、再起動後も保持されるもの、中断された作業の検出方法、 自動再開の動作について説明します。
再起動後も保持されるもの
| 状態 | ストレージ | 再起動時の動作 |
|---|---|---|
| 会話履歴 | エージェントごとの SQLite データベース | 変更されず、保存されたトランスクリプトからセッションが続行される |
| 中断されたメインセッションのターン | エージェントごとの SQLite セッション行とトランスクリプト | 起動から数秒後に自動的に再開または調整される |
| サブエージェントの実行 | SQLite(共有状態データベース) | 起動時にレジストリが復元され、中断された実行が再開される |
| バックグラウンドタスク | SQLite(共有状態データベース) | 起動時に調整され、孤立した実行が復旧されるか、消失としてマークされる |
| キューに入った送信 | SQLite 配信キュー | 再起動後に処理され、未配信の返信が再試行される |
| スケジュール済み(cron)ジョブ | SQLite cron ストア | スケジュールが保持され、起動時にスケジューラが再設定される |
| 再起動後の続行 | SQLite 再起動センチネル | 再起動を要求したセッションに 1 回限りのフォローアップがディスパッチされる |
正常な再起動では最初に処理完了を待機する
要求された再起動(openclaw gateway restart、再起動を必要とする設定変更、
または Gateway の更新)では、進行中の作業は即座に終了されません。
Gateway は新しい作業の受け付けを停止し、アクティブなエージェントのターンと
バックグラウンドタスクが完了するまで、処理完了の待機時間(デフォルトでは 5 分)を上限として待機します。
そのため、ほとんどの再起動では何も中断されません。
処理完了の待機時間内に完了できない作業(または強制再起動やクラッシュによって 中断された実行)のみが中止されます。その前に、影響を受ける各セッションには 復旧マーカーが付けられます。
中断された作業の検出方法
ターンが完了しなかったセッションは、相互補完的な 3 つの仕組みによってマークされます。
- ターン受け付け時: 既存のメインセッションに対する通常のテキストターンでは、
Gateway はモデルまたは
before_agent_replyフックの実行前に、1 つの SQLite トランザクションで ユーザーメッセージを追加し、セッションを実行中としてマークし、 その復旧配信クレームを記録します。Control UI ではstarted応答を返す前にこれを行い、チャネルディスパッチでは準備済みターンが エージェント実行を引き継ぐときに行います。 コマンド、添付ファイル、ターンごとのオーバーライド、保留中の配信、以前の中止ヒント、 Plugin 所有のセッション、実行フックを持つターンでは、それぞれ専用の受け付け経路が維持されます。before_agent_replyフックがインストールされている場合、受け付け処理ではそのフェーズも記録されます。 復旧時に、呼び出しの途中で中断されたフックが再実行されることはありません。未処理のフックが 完了すると、そのチェックポイントに結果が記録されますが、そのフックがアクティブな間は、 復旧は引き続き安全側に失敗します。チェックポイントだけでは、再起動後に同じ Plugin コードと 設定が読み込まれたことを証明できないためです。処理済みテキストとサイレント結果は、 決定論的に確定できるよう個別にチェックポイントへ記録されます。 古いバージョンによって書き込まれた永続的な復旧クレームにはソース所有権マーカーがないため、 アップグレード中には同じ安全側に失敗するフックチェックが適用されます。 - シャットダウン時: 再起動前の処理完了待機中に、アクティブな実行を持つ すべてのセッションについて、実行を中止する前にセッションストアへ復旧マーカーが記録されます。
- 起動時: Gateway はセッションストアをスキャンし、実行中であると 引き続き記録されているものの、新しいプロセス内に稼働中の所有者が存在しないセッションを検出します。 これにより、シャットダウンコードが実行されなかったハードクラッシュや強制終了も検出されます。 古くなったトランスクリプトのロックファイルも同時に削除されます。
自動再開
起動から数秒後、Gateway はマークされた各セッションを再ディスパッチし、 以前のターンが再起動によって中断されたことと、既存のトランスクリプトから続行するよう指示する 合成システムメッセージをエージェントに送ります。最終返信がすでに生成済みで 未配信だった場合は、そのテキストも含まれるため、エージェントは作業をやり直さずに配信できます。
起動時の調整では、一時的な障害に対して指数バックオフを使用し、最大 3 回再試行します。 これとは別に、中断されたメインセッションの各サイクルには、課金対象となる自動ディスパッチ試行が 3 回までという永続的な上限があり、Gateway の再起動後も保持されます。OpenClaw はディスパッチ前に 試行回数を消費し、Gateway が受け付け前にリクエストを明示的に拒否した場合は回数を戻します。 ディスパッチ後の結果が不明な場合は、作業の再実行を避けるため、消費した回数を維持します。 すでにセッションを所有しているフォアグラウンド作業が完了するまでは、自動復旧は行われません。
永続的な上限を使い切ると、無限ループする代わりにセッションへトゥームストーンが設定されます。
失敗したセッションを調査し、/new または /reset を使用して
代替セッションを開始してください。openclaw doctor --fix は、トゥームストーンと競合する
古い中止フラグを修復できますが、その復旧サイクルを再び有効にすることはありません。
すべての再試行で 1 つの永続的なディスパッチ識別子が再利用されるため、 接続障害の結果が不明な場合でも、同じ復旧が二重に開始されることはありません。 完了した Control UI ターンおよび再開できない Control UI ターンにも、 有効期間が制限された永続的な冪等性トゥームストーンが保持されるため、 再接続した送信ボックスはリクエストを再実行せずにそれらを処理済みにできます。
メッセージツールのみを使用する返信では、2 つ目の永続的な相関情報が使用されます。 同じ会話への終端送信がチャネルに到達する前に、Gateway は正確なセッションと ソースターンに対する未解決の配信意図を記録します。プロバイダーから成功が確認されると、 永続的な配信済みレシートとして解決され、失敗が確認されるとクリアされます。 復旧処理はツールを再実行せず、配信済みレシートを使用して完了します。 クラッシュによってプロバイダー側の結果が不明になった場合は、 外部への作用を再実行せず、安全側に失敗します。
配信された返信は、そのソースメッセージ ID とともにトランスクリプトにも複製されます。 終端ミラーには個別のレシートキーが使用されるため、同じプロバイダー冪等性キーを持つ 進捗送信によって終端マーカーが隠されることはありません。古いターンの進捗送信やレシートで 現在のターンが完了扱いになることはありません。メッセージアクションの権限を復元できるのは、 永続的なチャネル受信クレームだけです。再開された実行では、リクエスターのアイデンティティや 同一チャネルまたはスレッドへの制限を含む、元のソース配信モードとソース相関情報が維持されます。 そのため、復旧中に再度再起動しても、同じレシートが引き続き信頼できる情報となります。 再構築可能なチャネル権限を持たないメッセージツールのみのターンは安全側に失敗し、 1 回限りの再送通知を受け取ります。
再開前に、Gateway はトランスクリプト末尾から安全に続行できることを確認します。 安全でない場合(たとえば、ターンが古い保留中の承認で終了している場合)、 セッションは無条件に再実行されません。代わりにエージェントが、最後のリクエストを再送するよう ユーザーに求める短い通知を投稿します。WebChat では、その通知がセッション履歴へ直接書き込まれるため、 再接続後も表示されます。
OpenClaw は、中断された読み取り専用の Code Mode
作業も再構築できます。Code Mode はこれらの実行を再起動安全としてマークし、
副作用のあるカタログツールや Plugin 名前空間を、実行前に拒否します。
wait 制御の時点で再起動が発生した場合、新しい Gateway は
トランスクリプトからターンを再構築し、モデルがそのフラグを省略またはクリアしても、
再構築された実行を強制的に再起動安全な状態に維持します。ホストは、
再起動後に Code Mode が無効化されている場合も含め、再構築されたターン全体を、
監査済みの読み取り専用コアツールと、再実行が明示的に安全な Plugin ツールに限定します。
副作用のある作業には、書き込みの重複を避けるため、再送通知による保護が引き続き適用されます。
サブエージェント
サブエージェントの実行は共有 SQLite 状態データベースに永続化されるため、 サブエージェントレジストリはプロセス終了後も保持されます。起動時にレジストリが復元され、 中断されたサブエージェントセッションは元のタスクコンテキストを使用して再開されます。 2 つの安全策が適用されます。
- 2 時間以上前に中断された実行は、再開されずに完了処理されます。 そのため、一晩停止していた Gateway が古い作業を復活させることはありません。
- 復旧に繰り返し失敗するセッションには、停止状態としてトゥームストーンが設定され、 復旧が無限ループするのを防ぎます。
バックグラウンドタスク
バックグラウンドタスクレジストリは SQLite を基盤とし、 起動時および定期的に調整されます。完了した実行によって記録された永続的な結果は復元され、 所有プロセスが消失した実行は、無期限に停止したままになるのではなく、 猶予期間後に消失としてマークされます。
エージェントが要求した再起動
エージェント自身が再起動を開始した場合(設定変更の適用、Gateway の更新、 または明示的な再起動要求)、プロセスの終了前に再起動センチネルが SQLite に書き込まれます。 起動後、Gateway は結果を元のチャットへ投稿し、1 回限りの続行ターンをディスパッチします。 これにより、エージェントは同じチャネルとスレッドで、停止した正確な位置から作業を再開します。
センチネルの型付き SQLite 列が再起動処理の信頼できる情報源であり、
その payload_json 値は再実行およびデバッグ用のシャドウにすぎません。
ランタイムはファイルへのフォールバックを使用せず、SQLite の状態を読み取り、書き込み、クリアします。
ストレージ移行期間中は、起動時および Doctor を通じて、範囲が制限された状態移行が実行され、
更新後に古いプロセスが残した検証済みの restart-sentinel.json が保持されます。
移行処理は型付き行を検証し、通常の再起動処理を続行する前にソースファイルを削除します。
安全策と可観測性
- クラッシュループ遮断器: 5 分以内に 3 回正常終了せずに起動すると遮断器が作動し、 次回起動時に自動起動される補助サービスを抑止します。これにより、クラッシュする Gateway が 問題を増幅するのを防ぎます。正常終了しなかった起動の時間枠が経過すると復旧します。
- メインセッションの試行上限: 中断されたサイクルごとに、 課金対象となる自動ディスパッチ試行は 3 回までです。上限を使い切ると、 調査および置換されるまで、そのセッションにトゥームストーンが設定されます。
- メトリクス: 復旧アクティビティは
Prometheus を通じて
openclaw_session_recovery_totalおよびopenclaw_session_recovery_age_secondsとしてエクスポートされます。 - ログ: 復旧に関する判断は
main-session-restart-recoveryおよびsubagent-interrupted-resumeサブシステムに記録されます。
再開されないもの
- 別の所有者がすでに処理するため、メインセッションの復旧対象外となるセッション: サブエージェントセッション(サブエージェント復旧)、cron セッション(スケジューラが スケジュールに従って再実行)、ACP 管理セッション(接続された IDE またはクライアントが 再開を所有)。
- トランスクリプト末尾から安全に続行できないセッション。 これらは暗黙的に再実行されず、前述の再送通知を受け取ります。
- 一度も受け付けられなかった作業。処理完了の待機時間中に届いたメッセージは、 終了中のプロセスへ暗黙的にキューイングされず、明示的な再起動エラーで拒否されます。
- スタンドアロンの埋め込みターンは、Gateway のライフサイクル所有者を共有しないため、
再起動後の復旧が保留中のメインセッションを引き継ぐことはできません。
Gateway を通じてターンを実行するか、そこで
/newまたは/resetを使用してリセットしてください。