コンテンツにスキップ

OpenClawのプロセス管理を最適化:安定した実行環境の構築

バックグラウンドで実行したプロセスがいつの間にか「ゾンビ」になっていたり、タイムアウトしたはずなのにリソースを食いつぶしていたりすること、ありますよね。プロセスのライフサイクル管理は、一見シンプルに見えて実は非常に奥が深く、油断するとすぐに制御不能になってしまいます。

今回は、PTY(仮想端末)とプロセスの監視(Supervision)をより安全で予測可能なものにするための設計と実装についてお伝えします。場当たり的なプロセスの一致確認ではなく、確実な所有権とクリーンアップを実現するための改善案です。

私たちは、以下のような多岐にわたる長時間実行コマンドに対して、信頼できる単一のライフサイクルを必要としています。

  • exec によるフォアグラウンド実行
  • exec によるバックグラウンド実行
  • process のフォローアップアクション(poll, log, send-keys, paste, submit, kill, remove)
  • CLI agent ランナーのサブプロセス

目標は単に PTY をサポートすることではありません。不安定なプロセスマッチングのヒューリスティックを排除し、予測可能な所有権、キャンセル、タイムアウト、そしてクリーンアップを実現することです。

  • 実装は src/process/supervisor 内に留め、内部的なものとします。
  • このために新しいパッケージを作成しないでください。
  • 実用的な範囲で、現在の挙動との互換性を維持します。
  • ターミナルのリプレイや tmux スタイルのセッション永続化までスコープを広げないでください。

3. このブランチで実装された内容

Section titled “3. このブランチで実装された内容”

すでに存在する Supervisor のベースライン

Section titled “すでに存在する Supervisor のベースライン”
  • Supervisor モジュールは src/process/supervisor/* に配置されています。
  • Exec ランタイムと CLI ランナーは、すでに Supervisor の spawn と wait を経由するようにルーティングされています。
  • Registry のファイナライゼーションは冪等(Idempotent)です。
  1. 明示的な PTY コマンドのコントラクト
  • SpawnInput が src/process/supervisor/types.ts でタグ付き共用体(Discriminated Union)になりました。
  • PTY の実行には、汎用的な argv を再利用するのではなく、 ptyCommand が必須となります。
  • Supervisor は src/process/supervisor/supervisor.ts 内で argv を join して PTY コマンド文字列を再構築しなくなりました。
  • Exec ランタイムは src/agents/bash-tools.exec-runtime.ts で ptyCommand を直接渡すようになっています。
  1. プロセスレイヤーの型結合の解除
  • Supervisor の型が agent から SessionStdin をインポートしなくなりました。
  • プロセスローカルの stdin コントラクトは src/process/supervisor/types.ts (ManagedRunStdin) に定義されています。
  • 各 Adapter はプロセスレベルの型にのみ依存するようになりました:
    • src/process/supervisor/adapters/child.ts
    • src/process/supervisor/adapters/pty.ts
  1. プロセスツールのライフサイクル所有権の改善
  • src/agents/bash-tools.process.ts は、まず Supervisor を通じてキャンセルをリクエストするようになりました。
  • process kill/remove は、Supervisor で見つからない場合に process-tree によるフォールバック停止を使用します。
  • remove は、停止リクエストの直後に実行中のセッションエントリを削除することで、決定論的な削除挙動を維持します。
  1. Watchdog デフォルト設定の一元化
  • src/agents/cli-watchdog-defaults.ts に共有のデフォルト設定を追加しました。
  • src/agents/cli-backends.ts がこの共有デフォルトを使用します。
  • src/agents/cli-runner/reliability.ts も同じ共有デフォルトを使用します。
  1. 不要なヘルパーのクリーンアップ
  • src/agents/bash-tools.shared.ts から、使用されていない killSession ヘルパーパスを削除しました。
  1. Supervisor パスの直接テストの追加
  • Supervisor のキャンセルを経由した kill と remove のルーティングをカバーするため、 src/agents/bash-tools.process.supervisor.test.ts を追加しました。
  1. 信頼性のギャップの修正完了
  • src/agents/bash-tools.process.ts は、Supervisor でのルックアップに失敗した際、実際の OS レベルのプロセス停止にフォールバックするようになりました。
  • src/process/supervisor/adapters/child.ts は、デフォルトのキャンセル/タイムアウト時の kill パスに process-tree 停止セマンティクスを使用するようになりました。
  • src/process/kill-tree.ts に共有の process-tree ユーティリティを追加しました。
  1. PTY コントラクトの境界ケースのカバー
  • ptyCommand のそのままの転送と、空コマンドの拒否を確認するため、 src/process/supervisor/supervisor.pty-command.test.ts を追加しました。
  • child adapter のキャンセルにおける process-tree kill 挙動を確認するため、 src/process/supervisor/adapters/child.test.ts を追加しました。

今回のパスで必要だった 2 つの信頼性に関するギャップは解消されました:

  • process kill/remove は、Supervisor で見つからない場合に実際の OS レベルの停止フォールバックを持つようになりました。
  • child のキャンセル/タイムアウトは、デフォルトの kill パスで process-tree kill セマンティクスを使用します。
  • 両方の挙動に対してリグレッションテストが追加されました。

再起動時の挙動は、明示的に「メモリ内のライフサイクルのみ」と定義されています。

  • reconcileOrphans() は、設計通り src/process/supervisor/supervisor.ts で no-op(何もしない)のままです。
  • プロセスの再起動後、アクティブな実行状態は復元されません。
  • これは、不完全な永続化によるリスクを避けるため、今回の実装パスにおける意図的な境界線です。

メンテナンスのためのフォローアップ

Section titled “メンテナンスのためのフォローアップ”
  1. src/agents/bash-tools.exec-runtime.ts の runExecProcess は依然として多くの責任を抱えています。今後のフォローアップで、役割を絞ったヘルパーに分割することをお勧めします。

必要な信頼性とコントラクト項目に関する実装パスは完了しました。

完了済み:

  • process kill/remove の実際の停止へのフォールバック
  • child adapter のデフォルト kill パスにおける process-tree キャンセル
  • フォールバック kill と child adapter の kill パスのリグレッションテスト
  • 明示的な ptyCommand 下での PTY コマンド境界ケーステスト
  • reconcileOrphans() を設計通り no-op とした、明示的なメモリ内再起動境界の確立

オプションのフォローアップ:

  • 挙動を変えずに runExecProcess を役割ごとのヘルパーに分割
  • src/process/supervisor/types.ts: タグ付きの spawn input とプロセスローカルの stdin コントラクトで更新。
  • src/process/supervisor/supervisor.ts: 明示的な ptyCommand を使用するように更新。
  • src/process/supervisor/adapters/child.ts および src/process/supervisor/adapters/pty.ts: agent の型から切り離されました。
  • src/process/supervisor/registry.ts: 冪等な finalize は変更なく維持。
  • src/agents/bash-tools.exec-runtime.ts: PTY コマンドを明示的に渡し、フォールバックパスを維持するように更新。
  • src/agents/bash-tools.process.ts: Supervisor 経由でキャンセルし、実際の process-tree 停止にフォールバックするように更新。
  • src/agents/bash-tools.shared.ts: 直接的な kill ヘルパーパスを削除。
  • src/agents/cli-watchdog-defaults.ts: 共有ベースラインとして追加。
  • src/agents/cli-backends.ts および src/agents/cli-runner/reliability.ts: 同じデフォルト設定を使用するように変更。

ユニットテスト:

Terminal window
pnpm vitest src/process/supervisor/registry.test.ts
pnpm vitest src/process/supervisor/supervisor.test.ts
pnpm vitest src/process/supervisor/supervisor.pty-command.test.ts
pnpm vitest src/process/supervisor/adapters/child.test.ts
pnpm vitest src/agents/cli-backends.test.ts
pnpm vitest src/agents/bash-tools.exec.pty-cleanup.test.ts
pnpm vitest src/agents/bash-tools.process.poll-timeout.test.ts
pnpm vitest src/agents/bash-tools.process.supervisor.test.ts
pnpm vitest src/process/exec.test.ts

E2E ターゲット:

Terminal window
pnpm vitest src/agents/cli-runner.test.ts
pnpm vitest run src/agents/bash-tools.exec.pty-fallback.test.ts src/agents/bash-tools.exec.background-abort.test.ts src/agents/bash-tools.process.send-keys.test.ts

型チェックに関する注意:

  • このリポジトリでは pnpm build(およびフル lint/docs ゲート用の pnpm check)を使用してください。pnpm tsgo に言及している古いノートは廃止されています。
  • Exec 環境のハードニング(要塞化)挙動は変更されません。
  • 承認および許可リスト(allowlist)のフローは変更されません。
  • 出力のサニタイズおよび出力制限は変更されません。
  • PTY adapter は、強制終了時やリスナー破棄時の wait settlement を引き続き保証します。
  1. Supervisor が管理対象の実行におけるライフサイクル所有者であること。
  2. PTY の spawn が、argv の再構築を行わない明示的なコマンドコントラクトを使用していること。
  3. プロセスレイヤーが、Supervisor の stdin コントラクトにおいて agent レイヤーへの型の依存を持っていないこと。
  4. Watchdog のデフォルト設定が一元化されていること。
  5. 対象となるユニットテストおよび E2E テストがすべてパスすること。
  6. 再起動時の耐久性の境界が、明示的にドキュメント化されているか、完全に実装されていること。

このブランチにより、より一貫性があり安全な監視体制が整いました:

  • 明示的な PTY コマンドコントラクトの導入
  • プロセスレイヤーのクリーンな階層化
  • プロセス操作における Supervisor 主導のキャンセルパス
  • Supervisor で見つからない場合の実際のフォールバック停止処理
  • child 実行のデフォルト kill パスにおける process-tree キャンセル
  • Watchdog デフォルト設定の統合
  • 明示的なメモリ内再起動境界(今回のパスでは再起動をまたぐ孤立プロセスの調整は行わない)

困ったときは AI Setup Assistant に聞いてみてくださいね!

OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。