仕様書/実装計画書をもとに、計画を見出し単位のステップへ分解し、各ステップで「テスト作成→レビュー→収束ならコミット」「実装→レビュー→収束ならコミット」(必要なら「ドキュメント修正→レビュー→収束ならコミット」)を自律反復する。ユーザーから自律進行(止まらず最後まで進める・ステップを自動で回す等)の明示的な指示があったときだけ使う。単に計画に沿って実装してほしいだけの依頼(自律進行の指示を伴わない)では使わない。レビューは codex-review-loop、コミットは commit に委譲し、仕様整合(参照の記法・用語規約)はエージェントが直接確認する。
codex-watchdog
codex:codex-rescueエージェントを起動する各スキル(codex-review-loop・codex-consult等)が共有する、ハング防止付きの起動・監視・再試行契約の正本。内部専用でユーザーが直接使うものではない。
含まれるファイル(2)
- SKILL.md37.9 KB
- watchdog.sh11.4 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Codex Watchdog(codex:codex-rescue 起動の共通基盤)
codex:codex-rescue エージェントをバックグラウンドで起動する各スキルが共有する契約。codex を
安全に起動し、応答/失敗/ハングを区別し、インフラ障害を適切に再試行するところまでを担う。
このスキルの範囲外(呼び出し元スキルが個別に定める):
- タスク指示文に含めるべき内容(目的・出力契約など)
- エージェント応答の合否判定(何をもって有効な結果とみなすか)
- 失敗ラウンドの再試行上限・最終的に諦めて報告する条件
- 実行モード(read-only/
--write)の既定値
これらを定めた上位スキルが、以下の手順を自スキルの起動手順として適用する。ただし EPERM の 起動コマンドが呼び出し側の規約違反(起動コマンドの既知の不備パターン)に一致した場合に失敗ラウンドへ算入しない ことは、この一点に限り本スキル自身が既定を定める(下記EPERM は呼び出し側の失敗と推定する 参照。この一致は不備の存在を確定するのみで、それがEPERMの直接原因であることまでは要求しない。 再試行の実行自体は上位スキルの反復手順に従う)。
無プロンプト運用(前提)
呼び出し元スキルが発行するコマンドは、すべて settings.json の permissions.allow に
登録済みの単一コマンドに限る:
- codex 起動: settings.json に登録済みの companion 起動 glob(
node <実パス>/codex-companion.mjs …形。正確なパターンは settings.json が正)。呼び出し元エージェント内部で実行する - watchdog 起動:
Bash(bash .claude/skills/codex-watchdog/watchdog.sh*)(watchdog.sh の単一起動。 先頭を相対パスに固定しbash -c注入を防ぐ。末尾ワイルドカードが STALL/WALL/STATE_ROOT/GRACE/RUNID の各引数を覆うので settings.json の追加は不要)
複合コマンド(A && B、until …; do …; done)やインラインのループは許可パターンに一致せず毎回
プロンプトを出す。必要なロジックは許可登録済みスクリプト(watchdog.sh)に寄せる。
RUNID(相関トークン)の生成とマーカー埋め込み
【同時起動対応】RUNID をタスク指示文の最先頭に埋め込む: このラウンドごとに呼び出し元が一意
トークン RUNID(英数・_・- のみ。. は正規表現メタ文字なので使わない。12桁程度。例: タイム
スタンプ接頭+乱数で衝突回避)を生成し、タスク指示文(companion の -- 以降)の最先頭行に
TASK-RUNID: <RUNID> という固定マーカー行を必ず置く。RUNID はモデルが文字列として直接決める。
生成にシェルコマンドを使わない: $(date …)/$RANDOM 等のコマンド置換・パラメータ展開を含む
コマンドは glob 許可リストに一致せず、許可プロンプトを誘発して自律進行を止めうる。一意性はモデルが任意の英数トークン(会話の進行で重複
しない値)を綴ることで足り、Bash 実行は不要。companion はプロンプト冒頭をジョブメタ(task-*.json
の summary)に保存するので、watchdog は TASK-RUNID: <RUNID> マーカーを境界付き(RUNID
直後がトークン文字でないこと)で照合し、自ラウンドのジョブログを内容で一意特定できる(時刻・
起動順に依存する基準ではなくなるため、同一リポジトリで複数セッションを同時に回してもログの
取り違えが起きない)。RUNID はコード差分には入らずマーカー行に限るので「作業過程参照の混入」観点
には抵触しない。RUNID にバックティック・$・. 等の禁止/メタ文字を含めない。
RUNID を生成しマーカー行を確定させるのは、この契約を適用している呼び出し元(このスキルを実行
している側のエージェント自身)に限る。codex:codex-rescue サブエージェントに RUNID を生成させ
ない: codex:codex-rescue を起動する Agent 呼び出しの prompt には、呼び出し元が確定済み
の TASK-RUNID: <RUNID> マーカー行をリテラル文字列としてそのまま含め、加えて次の指示を
(禁止記号を含めない形で)明記する——「あなたは RUNID を生成しない。上記の TASK-RUNID マーカー
行を一字一句変更せず、companion への task 引数(-- より後ろのタスク指示文)の最先頭行として
そのまま転記せよ。マーカー行以降のタスク指示文も要約・言い換えせず渡された内容をそのまま使う」。
codex 起動の作法(誤起動防止)
起動コマンドの標準形: node "<companion の絶対パス>" task --cwd="<対象リポジトリの絶対パス。 スラッシュ区切り>" -- "<タスク指示文>"。以下の各要素は呼び出し元がこの手順を適用する時点で確定
させ、codex:codex-rescue エージェントには確定済みの値を渡すだけにする(推測・探索させない)。
このエージェントの許可リストには find・Glob 等の検索コマンドが無いため、探索させると許可
プロンプトを誘発して無プロンプト運用が崩れる。起動コマンドはシェルの中間変数(PowerShell の
$variable 等)を経由させず、確定済みの値を node 呼び出しへ直接埋め込んで組み立てる(中間変数を
経由した組み立てで値が argv まで正しく届かなかった事例がある)。
- companion スクリプトの絶対パス: プラグインのインストール場所(バージョンディレクトリを含む)
にあり環境で変わるため、相対パス(
codex-companion.mjsのみ)や記憶・推測による絶対パスを渡さない (相対パスはサンドボックスの作業ディレクトリ解決に絡んで失敗しうる。誤った推測パスはMODULE_NOT_FOUNDで即失敗する——いずれも companion・codex 側の障害ではなく呼び出し元の起動 コマンド組み立てミスであり、実パスを事前確定して渡せば避けられる)。 --cwd=<パス>(taskの直後・--より前。省略禁止。値は=で1トークンに連結し、スペース 区切りの別トークンにしない):--cwdを省略すると companion は自分自身のプロセス cwd(サブ エージェントの Bash cwd に依存し、対象リポジトリと一致するとは限らない)を使って状態を解決する。 対象リポジトリと異なる cwd で解決されると、対象リポジトリの通常の状態ディレクトリとは別のディレ クトリが対象になり、そのディレクトリがまだ作成されていなければ新規作成が発生してサンドボックスの 新規ディレクトリ作成制限に当たり EPERM になりうる(既に作成済みのディレクトリが対象なら問題 は起きない)。--cwd <パス>とスペースで区切る2トークン形自体は companion の解析上有効だが、 この形で値が呼び出し元のシェル層から node まで正しく届かなかった事例が実測で確認されている(その 場合に何が代わりに渡っているのか、内部のどの経路で起きるかは未確認)。パスは必ずスラッシュ区切り (例:/repoのようなスラッシュ区切りの絶対パス)で渡す——バックスラッシュ区切りだとサンドボックスが 不正パスに誤解決しプロセス生成前にエラー267で失敗する。--(オプション終端):task --cwd=<パス>の後に置く。タスク指示文は--より後ろの単一 引数としてそのまま渡す。companion 側の解析経路によっては、--が無いとタスク指示文中の-C、-m、--write、--model、--cwd、--backgroundなどオプションらしいトークンが companion 自身のオプションと誤認識されることがある(標準形の argv 構成では通常この経路に入らないが、--を書けばどの経路でも確実に位置引数として扱われる)。--を省略したコマンドを実行した場合はその ラウンドを失敗として扱い、同じエージェントを継続せず新規エージェントで再実行する。- スレッド継続(前回の codex スレッドを継いで実行させること。使うかどうかは呼び出し元スキルが
定める): 起動コマンドへのオプション付与は
codex:codex-rescueが行うので、呼び出し元は継ぐか 継がないかを指示文に言葉で書く。継ぐスレッドをIDで指定する手段は無く、companion は最後に終局した task ジョブのスレッド(失敗で終わったジョブも候補に入る)を継ぐ(継ぐ相手が意図したラウンドかを 確かめる手順は呼び出し元スキルが定める)。 前のスレッドが見つからないとき・実行中の task が残っているときは companion がスレッドを解決できず エラーを返す。このエラーは継げないことだけを意味し、codex 側の障害ではない(扱いは呼び出し元スキルが 定める)。ジョブが終局する前にTaskStopで外から終わらせた場合はジョブ記録が実行中のまま残り ——終端状態は companion 自身のプロセスが書き、実行中のまま残った記録を回収する仕組みは無い—— そのセッションでは以後スレッド継続がこのエラーになり続ける(ジョブが終局した後にエージェントだけをTaskStopした場合は記録が終端状態なので継続できる)。codex:codex-rescueはタスク指示文が前の作業の続きに 見えると自分の判断でスレッドを継ぐので、継がせたくない回は新規スレッドで起動せよと指示文に 明記する(黙って継続されるのを防ぐ)。 - モデルは既定値を使い、
--より前に-m/--modelを付けない(呼び出し元が明示的にモデルを 要求した場合のみ、その要求に従う)。 - 検証(
docs/conventions/verification.md)が要るなら codex とは 別に自前シェルで行い、検証ツールのコマンドを companion の実行オプションとして渡さない。
失敗は症状のラベルでなく原因で仕分ける
stall・no-start・wall-cap・Turn failed.・EPERM などの症状ラベルだけで機構障害と決めつけない。
これらのラベルは観測された症状(ログが進まない・ジョブログが現れない・所定時間内に終局しない・
状態ログ書き込みが拒否される等)を機械的に示すだけで、原因まで確定させるものではない。原因は次の
いずれかでありうる: (a) Codex/companion 側が実際に応答不能・処理停止している(真の機構障害)、
(b) 呼び出し側の起動コマンド組み立てミス(相対パス・誤ったパス推測・-- 省略・RUNID 不一致等)に
よりジョブが実質的に開始していない、またはエージェントが誤ったコマンドを実行し続けている。
エージェントの報告・ジョブログから、この2区分のどちらに該当するかを確認し呼び出し元スキルへ
伝える(症状のラベルだけで機構障害と決めつけない)。この切り分けを踏まえて、(b)を通常の失敗
ラウンドの連続回数上限から除外するかどうか・除外する場合の再試行上限の有無は、上記のとおり
呼び出し元スキルが定める(このスキルは切り分けの基準のみを提供し、再試行上限の
方針は決めない)。ただし EPERM に限っては、下記EPERM は呼び出し側の失敗と推定するのとおり
このスキル自身が除外を既定とする(範囲外の例外)。
【厳守】「組み立てミスではなく機構側の一過性の問題」のような否定的な原因判断は、その仮説を直接
検証してからしか結論しない。「前ラウンドと同じ形式のコマンドだった」「過去にも同種のエラーで
再試行が通った実績がある」は状況証拠であって検証ではなく、これだけを根拠に機構側要因と結論しては
ならない。とくに EPERM を含む失敗で「呼び出し側の起動コマンド組み立てミスではない」と結論するには、
ジョブログのエラー本文を確認するだけでは足りない(エラーの種別が分かっても組み立てミスの有無は
分からない)。その回の起動コマンドが実際にこのスキルの規約(--cwd=<パス> の1トークン形・スラッシュ
区切り・-- の位置・RUNID 転記・中間変数を経由しない組み立て等)に一致しているかを本文と照合して
確認したうえで結論する。何も確認せず原因を断定してはならない。原因が確認できなければ「未検証」と
明記して呼び出し元スキルへ報告する(この場合の扱いも上記のとおり呼び出し元スキルが定める)。
EPERM は呼び出し側の失敗と推定する(既定と手順)
EPERM は、Codex/companion 自体の障害の兆候としては扱わず、呼び出し側の起動コマンド組み立て
ミス(--cwd 省略・--cwd のスペース区切り2トークン形・シェルの中間変数経由・相対パス・誤った
パス推測・バックスラッシュ区切りパス。上記codex 起動の作法に列挙した各項目)に由来すると
推定する。EPERM が出た場合、上記の失敗は症状のラベルでなく原因で仕分けるの一般規則(「原因不明なら未検証と明記し、扱いは呼び出し元スキルに委ねる」)へいきなり
流すことを禁止し、以下を必ず実施する。
- 原因確認を省略して「原因不明」に倒すことを禁止する。「まだ確認していない」「前ラウンドと 同じ形式だった」「過去に再試行が通った実績がある」は確認の代わりにならない。EPERM が出た当該 ラウンドのジョブログ本文(存在する場合)と、実際に組み立てられた起動コマンドを必ず確認し、 下記の起動コマンドの既知の不備パターンの各項目と1つずつ照合する。ジョブ状態ログの書き込み自体がサンドボックス 制限で拒否されジョブログが存在しない/参照できない場合(下記サンドボックス規約参照)は、 ジョブログの代わりにエージェントの報告に含まれる実際の起動コマンドと生のエラー出力を用いて 同じ照合を行う(ログ不在を理由に照合そのものを省略しない)。
- 起動コマンドの既知の不備パターンのいずれかに一致した場合: その回の起動コマンド自体が規約に
違反した無効な試行だったと確定する。この不備が今回のEPERMの直接原因であることまでの証明は
要求しない(サンドボックス内部の挙動までは通常確認できないため)——規約違反のある起動コマンド
での試行は、それ自体がCodex/companionの応答可否を判定する有効な試行になっていない、という理由
で失敗ラウンドにカウントしない。無対策のまま同じ形で再試行することを禁止
する: 次のラウンドのタスク指示文に、今回特定した具体的な不備そのものを名指しした禁止文を
追加してから新規 RUNID で再試行する(例:「シェルの中間変数を経由させるな。作業ディレクトリ
指定は空白区切りの2トークンではなく等号による1トークン連結にせよ」のように、一般論の「標準形
で起動せよ」ではなく当該ラウンドで実際に踏んだ不備そのものを、禁止記号(バックティック・ドル
記号等。下記禁止記号規約と差し戻し参照)を含めない言葉で明記する)。この非算入に、EPERM
固有の追加の回数上限は設けない(通るまで再試行するのが本ルールの目的であり、対策を講じた
うえでの再試行が再発したことを理由に通常の失敗ラウンド扱いへ倒すことは、形を変えた「原因確認
せず停止する」の再導入になり、この規律の目的に反する)。ただし呼び出し元スキルが全ての失敗
種別に一律に定める再試行上限(例:
codex-consultの1回限りの再試行)は、この非算入の対象で あっても適用される(EPERM だからといって呼び出し元スキル自身の反復方針を上書きしない。この 「回数上限を設けない」は、EPERM 固有の追加制限を課さないという意味に限る)。 - 起動コマンドの既知の不備パターンのいずれにも一致しない場合に限り、上記一般規則(未検証と明記し呼び出し元 スキルへ判断を委ねる)を適用する。この場合は起動コマンドの既知の不備パターンのいずれにも該当しない未知の パターンである旨を、呼び出し元スキルへの報告に明記する(呼び出し元スキルがユーザーへどう 伝えるかは自スキルの報告手順に従う)。
起動コマンドの既知の不備パターン(チェックリスト)
呼び出し側の起動コマンド組み立てミスを示す既知の不備パターン。
いずれか一項目でも実際の起動コマンドに現れていれば「一致」とする: --cwd が省略されて
いる/--cwd がスペース区切りの2トークン形になっている/シェルの中間変数を経由して値を
組み立てている/パスが相対パスまたは誤った推測パスである/パスがスラッシュ区切りでない/
-- が省略されている/RUNID がタスク指示文冒頭のマーカーと一致しない。
禁止記号規約と差し戻し
- プロンプト本文にバックティック(
`)・$・$(...)・ヒアドキュメント<<を書かない (許可拒否の主因)。companion は task 引数をダブルクォートで囲むことがあり、その中のバック ティックや$はシェルのコマンド置換と解釈される。Claude Code の許可マッチャはコマンド置換を 埋め込みコマンドとして分割判定するため、settings.json の companion の起動許可 glob に一致せず コマンド全体が拒否される。コード参照は「」や素の語で書き、file:lineもバックティックで 囲まない。コマンド置換やドル記号を含むコードを扱わせたいときも、記号そのものを本文に書かず 言葉で表す(例「コマンド置換(ドル記号と丸括弧)」)。実際の記号や挙動は対象ファイルを直接読ませて 確認させる。 - 禁止記号を含む本文は codex-rescue に差し戻させる(入力ミスの早期検出): エージェントへの
指示に「
--以降のタスク指示文に$・バッククォート・$(...)・ヒアドキュメント<<などの 禁止記号が含まれていたら、companion を起動せず、どの禁止記号が含まれるかを明示して応答し 差し戻せ(拒否される起動を試みる前に、規約違反として呼び出し側へ返す)」を必ず含める。差し戻された 側は記号を言葉に言い換えて新規エージェントで再依頼する。 - 許可拒否は安全側チェックの正常動作として扱う(許可リストを緩めるのではなく、拒否されない
コマンドへ指示を寄せる): エージェントの報告から拒否された正確なコマンドと理由を確認し、原因
(バックティック・
$等)を除いた指示にして新しいエージェントで再実行する。同一コマンドが 2回連続で拒否されたらループせず停止し、拒否コマンドと理由をユーザーへ報告する(許可リストを 緩めるかはユーザーの判断)。
サンドボックス規約
【厳守】サンドボックスを無効化するな: 「dangerouslyDisableSandbox を使うな。サンドボックス
外で codex を実行するな」を必ずエージェントへの指示に明記する。codex companion が状態書き込みで
サンドボックス制限(EPERM 等)に当たっても、サンドボックスを切って回避してはならない。大半の
ラウンドはサンドボックス内で完走できる(=無効化は不要)。サンドボックス制限でどうしても完走
できない場合はそれを失敗として報告し、勝手にサンドボックス外実行へ切り替えない。settings.json
への sandbox.allowWrite 追加も禁止。
read-only 実行を指示しても、companion の task モードはジョブ状態ログ
(~/.claude/plugins/data/.../jobs/task-*.log)を codex 起動前に無条件で書く。この書き込みは
サンドボックス外で --write の有無と無関係に EPERM になりうる。つまり read-only は「リポジトリを
編集させない」効果はあるがEPERM(サンドボックス外の状態ログ書き込み)の対策にはならない。EPERM が
出た場合はサンドボックスを切らず失敗として扱う。
この EPERM の主要な既知原因は --cwd の省略で、対策はcodex 起動の作法が定める標準形での起動である。--cwd を
正しく渡した上でなお EPERM が出た場合は、上記失敗は症状のラベルでなく原因で仕分けるの手順に
従う。
起動と監視
- 呼び出し元は
codex:codex-rescueエージェント(Agentツール、subagent_type: "codex:codex-rescue")を必ずrun_in_background: trueで起動する。フォア グラウンド呼び出しは上限時間も打ち切り手段も無く、codex がハングすると呼び出し側ごと無限に 止まる。バックグラウンド化して初めて締切 watchdog とTaskStopで締め切れる。 TaskOutputをこのエージェントに使わない。ローカルエージェントに対する戻り値は会話 トランスクリプト(JSONL)全体で、コンテキストを溢れさせる。結果取得にも完了待ちにも使わない。- バックグラウンドエージェントの完了通知・ブロック待ちは単独で信用しない(取りこぼし/ハングの 既知問題)。watchdog の起動が定めるジョブログ監視を併用して終了/ハングを判定する。
- codex 自身にタイムアウトは無い(
codex execに--timeout等のフラグ無し)。締切は必ず 呼び出し側(外部)で握る。codex を直接timeoutで包む案は、timeout/gtimeoutが無い環境が あること・サンドボックス由来の EPERM がエージェント経由か否かに無関係で残ることから、利点が出ない。 - watchdog とエージェントを起動した直後、
ScheduleWakeupで300秒以下の1回のハートビートを 張ってから、それ以上何もせずターンを終える(手元での sleep・繰り返しポーリングはしない)。 完了/失敗/stall/wall-cap の一次検知はエージェント応答か watchdog のバックグラウンド出力の通知 ——いずれか先に届いた方——であり、ハートビートより先に届けばそのまま完了の判定へ進んでよい (張ったハートビートは空振りしてよく、無害)。ハートビートは、通知取りこぼし時の回復経路と、 長時間待機中の進捗報告(数分を超える待ちは経過とETAを都度報告する運用)を兼ねる。 - ハートビートが先に発火した場合: まず watchdog のバックグラウンド出力を読み
OUTCOME行の 有無を確認する。出ていれば(通知だけが取りこぼされた状態なので)そのまま完了の判定を 適用する。まだ出ていなければ、起動時刻からの経過秒数を現在時刻で取り直して算出する。経過がWALL_CAP_SECSを明確に超えてなおOUTCOMEが無ければ watchdog 自身が失われた異常とみなし、 完了の判定の失敗経路(エージェントと watchdog をTaskStopし新規 RUNID で再試行)を適用する。 そうでなければ経過 とETA見込みを一言報告し、300秒以下で都度再計算した delaySeconds を次のハートビートに設定して 張り直しターンを終える。
エージェント内部の実行契約(companion 呼び出しをバックグラウンド化しない)
**「codex の task フォワードをフォアグラウンド(同期)で実行し、その結果(codex の応答)をそのまま
返り値にせよ。task をバックグラウンドジョブにする(run_in_background/&)な」**を、
codex:codex-rescue エージェントへのタスク指示文に必ず明記する。理由: codex:codex-rescue
サブエージェントの役割は task フォワードのみで、status/result/cancel はスコープ外=呼べない。
したがって「ジョブをバックグラウンド化して後から status/result で回収」は不可能で、バックグラウンド化
すると結果を取り戻せず「実行中です…出力は …/tasks/<id>.output」とだけ返して早期復帰してしまう
(このスキルが存在する直接の動機となった失敗パターン——エージェントの外側は run_in_background: true
で起動しつつ、エージェントの内側の companion 呼び出しは同期にする、という二層の区別を混同すると
再発する)。task をフォアグラウンドで走らせれば codex 応答が出るまでブロックし、それが返り値になる。
タスク指示文には、加えて次も明記する:
(a) task を同期実行する、
(b) codex の応答を必ず含めて返す、
(c) status/result のポーリングを試みるな(スコープ外)、
(d) 結果を返さずにターンを終えるな、
(e) codex が完走しなかった場合(EPERM・タイムアウト・バックグラウンド化・起動失敗等)は失敗を
明示し、確認できていないのに完了したかのように結論するな(未完走を完了に見せかけるな)、
(f) codex が完走しなかった場合にタスク内容を自分で代行するな(Codex 未完走時の自己代行禁止)、
(g) コマンドが許可で拒否された場合は、試みた正確なコマンド文字列と拒否理由を構造化して報告せよ
(呼び出し側が原因を除いて再指示できるようにするため)、
(h) タスク指示文の最先頭にある TASK-RUNID: <トークン> マーカー行は、受け取った文字列を一字
一句変更せず companion への task 引数の最先頭行として転記せよ。独自の RUNID を生成する・値を
書き換える・マーカー行を要約/省略することを禁止する(watchdog が自ラウンドのジョブログを取り
違え、ハング検知が機能しなくなる直接原因になる)。
Codex 未完走時の自己代行禁止
codex が完走しなかった場合、依頼されたタスクの内容(レビュー・相談・調査・確認等)を自分
自身のツール呼び出し(Bash・rg・git diff・git status 等)で代行して答えることを禁止する。
「念のため自分で確認した」「上記確認は本エージェントが直接実施した」のような注記を添えても、
代行した内容を返す時点で契約違反である。この場合に返してよいのは、試みた起動コマンドと実際に
発生したエラー(症状・分かれば原因)のみで、タスク内容そのものへの回答・分析・確認結果を一切
含めない。
watchdog の起動
エージェントより先に、コミット済みスクリプト watchdog.sh を run_in_background: true の
Bash で1つ起動する(リポジトリルートから相対で
bash .claude/skills/codex-watchdog/watchdog.sh [STALL_SECS] [WALL_CAP_SECS] [STATE_ROOT] [STARTUP_GRACE_SECS] [RUNID])。
第5引数 RUNID にこのラウンドのトークンを必ず渡す(上記で生成し、タスク指示文の最先頭
TASK-RUNID: <RUNID> に埋めたものと同じ値)。RUNID を渡すと watchdog はそのトークンを含む
ジョブログだけを自ラウンドとして選ぶので、同一リポジトリで複数セッションを同時に回しても互いの
ログを誤掴みしない。既定値は STALL_SECS=420・WALL_CAP_SECS=1200・STARTUP_GRACE_SECS=240。
【厳禁】失敗(stall/no-start/wall-cap)を理由に閾値を引き上げて再起動するな: 呼び出し元スキルが
タスクの性質(想定処理時間)に応じてこれらの値を、レビュー・相談のこの起動を始める最初のラウンドで
一度だけ決めるのは構わない(codex-review-loop の反復ラウンド・codex-consult の1回きりの
再試行のいずれも対象)。しかし、あるラウンドが stall/no-start/wall-cap で終局した後、前ラウンドより
大きい値の STALL_SECS/WALL_CAP_SECS/STARTUP_GRACE_SECS を渡して次ラウンドを再起動することは
禁止する。「もう少し待てば終わるはず」という憶測でタイムアウトを伸ばす行為は、上記の失敗は症状のラベルでなく原因で仕分けるの切り分けを経ずに機構障害の可能性を握り潰す。失敗が起きたら閾値を
いじらず、原因を切り分けた上で前ラウンドと同じ閾値のまま新規エージェント・新規 RUNID で再試行
する(原因が呼び出し側の起動コマンド組み立てミスであれば、直すべきは閾値ではなく起動コマンドそのもの)。
それでも閾値自体を見直したくなったら、それは失敗直後の場当たり的な引き上げとは切り離した別の
判断として、見直したい理由を明記した上でユーザーに諮る。
watchdog はログの更新時刻と終了行を見張り、次の終局でだけ終了する:
- 失敗(
exit 2): companion ログにTurn failed. - 正常終了(
exit 0): companion ログにTurn completed.またはFinal output - stall/ハング(
exit 3): ログの更新時刻がSTALL_SECS前進しない(ヒューリスティック。WALL_CAP_SECSがハード保証) - no-start/wall-cap(
exit 4):STARTUP_GRACE_SECS以内にこのラウンドのジョブログが一つも 現れない、またはWALL_CAP_SECS超過しても終局に達しない(再試行優先のヒューリスティック。 誤判定の代償は呼び出し側の再試行のみ)
watchdog は終了前に LOG=<選択したログのパス> と OUTCOME=<code> <理由> を標準出力に出力する。
呼び出し元はそのバックグラウンド出力ファイルを読めば、どのログを結果回収に使うかを推測せず確定できる。
完了の判定(機械的な部分)
エージェント応答か watchdog 通知の先に来た方で分岐する:
- エージェントが応答を返す → 呼び出し元スキルの合否判定基準で採用可否を決める(この基準自体は
呼び出し元の責務)。watchdog を
TaskStop。 - watchdog
OUTCOME=0(正常終了)なのにエージェント応答が来ない(通知取りこぼし) → watchdog 正常終了なのにエージェント応答が来ない場合のとおり扱う。 - watchdog
OUTCOMEが 2/3/4(失敗/stall/no-start/wall-cap)、または エージェントの失敗報告・ 「実行中です…」早期復帰 → エージェントと watchdog をTaskStopし、新規にcodex:codex-rescueを起動してやり直す(タスク指示文で「taskをフォアグラウンド同期実行・バックグラウンド化禁止・ 失敗は明示」を強調し、新しい RUNID を発行する)。no-start も即この経路で再試行する。この失敗が 機構障害由来の失敗ラウンドとしてカウントされるかは、上記失敗は症状のラベルでなく原因で仕分ける のとおり原因を確認してから決める(no-start・stall・wall-cap のラベルだけで機構障害と決めつけない)。 再試行時は前ラウンドのオーファンが残りうるが、結果の主チャネルはエージェント応答で、誤選択は 再検証/再試行に縮退し誤った修正には至らない。遅延結果を待つ運用は採らない: watchdog は起動 猶予で既に終了しており、その後 wall-cap まで監視する手段が無いため、待つと通知欠落時に元の サイレント停止が再発する。 - バックグラウンド化された codex ジョブはオーファン化しうる(
status/result/cancel不可)。 累積して問題化したらユーザーへ通知し、掃除はユーザーの手動操作/再起動に委ねる。
失敗ラウンドの再試行上限・何回で諦めてユーザーへ報告するかは呼び出し元スキルが定める(この スキルは機構のみを提供する)。
watchdog 正常終了なのにエージェント応答が来ない場合(フォールバック)
watchdog OUTCOME=0(正常終了)なのにエージェント応答が来ない(通知取りこぼし) → watchdog の
バックグラウンド出力ファイルを読み、LOG= が指すログから Final output 節をアンカー付き
(companion 自身のログ行 ^\[<ISO timestamp>\] … にアンカーする。アンカーが無いと codex の
Running command: … "Turn completed" エコーや本文中の同文字列に誤一致して偽終了する)で抽出して
参考にする。エージェントを TaskStop。このフォールバックのログ走査ではラウンド同一性が
保証されない(RUNID 未一致時はオーファン誤選択の可能性がある)ため、呼び出し元スキルは
フォールバック由来の結果を、通常の正規結果と同等の確度で採用してよいかを自スキルの用途に照らして
判断する(例: 収束判定を伴うループでは、フォールバック由来の「問題なし」を確定に使わない安全
規則を持つ、等)。
使用不可の検知と再試行(セッション内で記憶)
- companion の応答・ジョブログに「Codex CLI is not installed」「認証が必要」等セットアップ起因 のエラーが現れた場合、この会話内で「Codex はセットアップ未完了で使用不可」と記憶し、その旨を 呼び出し元スキルの報告に明記させる。
- 使用量上限のエラーが現れた場合、リセット予定時刻をエラーメッセージから読み取れる範囲で把握し、 この会話内で記憶する。3時間以内なら待って自動再開する。3時間を超える場合は待たず停止し ユーザーへ平文で報告し、リセット予定時刻を明記する(選択肢プロンプトや迂回案の提示はしない)。
- この会話内でユーザーから「Codex に戻して」等の明示的指示があれば、以降は通常どおり Codex を使う。
- 次回このスキルを適用する際、この会話内に前回記憶した「使用不可」の状態(理由・リセット予定時刻)が
無いか先に確認する: 記憶が無ければ通常どおり進める。リセット予定時刻を現在時刻が過ぎていれば
記憶を消して自動的に進める。まだリセット時刻前、またはセットアップ未完了なら
codex:setupを 実行してreadyを再確認し、ready: trueなら記憶を消して進める。それ以外は記憶を維持し、 その旨をユーザーへ平文で報告してこのラウンドの実行はスキップする。
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
同じリポジトリのスキル
概要と使いどころ
Codexへの単発の相談・調査・診断依頼を、ハング防止(watchdog)付きで実行する。反復・収束判定・コミットゲートは持たない。行き詰まって一回だけCodexに相談・調査を依頼したいときに使う。コミット前のレビュー収束が目的ならcodex-review-loopを使う。
codex:rescueにレビューさせ、各指摘を実コードで検証して修正/反証/受容/保留に仕分け、再レビューを反復する。未解決ゼロ・千日手・要ユーザー判断のいずれかで終了。コードレビューを回したいときに使う。
gitコミットをcommit-workerエージェントに委譲して実行する。コミットの依頼を受けたとき、変更をコミットするときに使用する。
fable-reviewer(Fableモデル、read-only)にレビューさせ、各指摘を実コードで検証して修正/反証/受容/保留に仕分け、再レビューを反復する。未解決ゼロ・千日手・要ユーザー判断のいずれかで終了。Fableモデルでコードレビューを回したいときに使う。
opus-reviewer(Opusモデル、read-only)にレビューさせ、各指摘を実コードで検証して修正/反証/受容/保留に仕分け、再レビューを反復する。未解決ゼロ・千日手・要ユーザー判断のいずれかで終了。Opusモデルでコードレビューを回したいときに使う。