plan-viewer には「プランを承認する前に、非エンジニア向けHTMLを作りなさい」と自動で促す仕組み(hook = 特定操作の直前に別の処理を差し込む仕組み)がある。
しかし今回の調査で、この仕組みが一度も動いていなかったことが判明した。Claude Code のプラン承認メニュー(「Yes, and bypass permissions」等の選択肢)はフックのシステムを完全にスキップしていたため、チェックが一切かからずプランがそのまま実装に進んでいた。
放置すると、プランの内容がHTMLに変換されないまま実装が完了し、非エンジニアがプランの内容を確認できない。
tmux(ターミナルを分割してプログラムを動かせるツール)で Claude Code を3回テストし、デバッグ用のログも仕込んだ。結果、ログは完全に空。フックのスクリプトは一度も呼ばれていなかった。
原因は Claude Code のプラン承認メニュー。プランが完成すると「1. Yes, clear context / 2. Yes, and bypass permissions / ...」という選択肢が表示される。この選択肢を選んでプランモードを終了すると、内部的にフックを通らずに直接プランモードが解除される。これは GitHub Issue #15660 で報告されている既知の仕様。
仮にフックが動いても、プランモード中は「ファイルに書き込むな」というAIへの指示が効いているため、HTMLを書けない。この指示はプログラム的なブロックではなく、AIへのテキスト指示(プロンプト)だけで制御されているが、AIはこの指示に忠実なので実質的に書けない。
理想的な解決策である「プランモード終了時フック」(PlanModeExited)は、GitHub Issue #20526 で提案されているが、2026年3月時点で未実装。
「プランモード終了」は検知できないので、プラン承認後に最初の実装ツール(ファイル書き込み・編集・コマンド実行)が呼ばれる瞬間をゲートにする。そこで「plan-viewer HTML をまだ書いてないよね?先にそっちを書いて」とブロックする。
plans/ ディレクトリ内の .md ファイル)を書いた直後に自動で「フラグファイル」を作成する。フラグには「どのセッションで」「どのプランを」書いたかを記録する。これが「plan-viewer HTML 未生成」のマーカーになる。| 指摘 | 対応 |
|---|---|
| Write だけゲートでは Edit/Bash が素通り | Write|Edit|MultiEdit|Bash を全部ゲート |
| prompt フックだけでは弱い | command フック(exit 2)でブロック + prompt は補助 |
| タイムスタンプベースは壊れる | session_id + plan_hash でステート管理 |
| 異常終了でフラグが残る | TTL(有効期限)で自動クリーンアップ |
調査の経緯: 最初は「プランモード中に Write が使えないデッドロック」が問題だと思っていた。しかし tmux での検証で「そもそもフックが発火していない」という、より根本的な問題が見つかった。
Codex との合意: Claude(Anthropic)と Codex(OpenAI GPT-5.4)の2つの AI で設計をクロスチェック。「実装の入り口をゲートにする」方針で一致した。
将来的な理想: Claude Code に PlanModeExited フック(Issue #20526)が実装されれば、もっとシンプルな設計にできる。今回の設計はそれまでのワークアラウンド。
見送った案: (A) prompt フックで plan mode の Write 制約を上書き → Codex が「権限レイヤーは上書きできない」と判定。(B) PostToolUse + Stop のみ → 「後追い承認」になり本質的でない。