| name | think |
| description | critic-design による敵対的批判を伴う設計探索。生き残った案を構造化 plan にまとめ、自己点検して呼び出し元に返す。plan の永続先は issue の Plan 節が唯一。計画意図のないコードベース調査には使わない (代わりに /research)。 |
| when_to_use | 計画して, 設計して, アプローチ検討, 方針決め, planning, design exploration |
| allowed-tools | Read Write LS Task AskUserQuestion Bash(ugrep:*) Bash(bfs:*) Bash(test:*) Bash(git cat-file:*) Bash(git show:*) Bash(git rev-parse:*) |
| model | opus |
| argument-hint | [task description] |
/think - 設計探索
2 つ以上の案を critic-design の批判にかけ、生き残った案だけを構造化 plan にまとめる。plan は templates/plan.md の骨格で下書きファイルに書き出し、会話でも返す。永続化は /issue が issue の Plan 節へ移設して行う。
入力
$ARGUMENTS でタスク説明と調査の文脈を受け取る。空なら AskUserQuestion でユーザーに確認する。先頭行をタスクのタイトルとして扱う。
Phase 1: Why の確立
.claude/OUTCOME.md を読む。存在しない場合は /outcome で生成する。Why は 3 点で構成し、タスクが Bug のときは 4 点目として原因を足す。誰がどんな痛みを抱えて必要としているか、何を成功とみなすか、なぜ今やるか、Bug なら原因は何か。痛みには根拠を添える。原因は再現手順やログなど根拠とともに特定し、原因が未確定なら設計へ進まず /research に回す。設計はこの Why が $ARGUMENTS と会話から読めてから始める。曖昧なまま仮置きせず、AskUserQuestion で詰める。
Phase 2: 設計探索
案を現実のコードと既存の調査に接地させる。関連コードを読み、.claude/workspace/research/ からタスクに該当する調査出力を探して読む。調査レポートの発見のうち、次のアクションが「記録のみ」のものは背景知識として扱い、plan のスコープに入れない。案を生成する前に、ドメインを問わず画面の組か layer の組が一致する既存モジュールを reference_module 候補として探索する。結果は kind (module/no-module/new-shape) と理由で控える。異なる視点 (動く最小解/構造と拡張性/開発体験) から 2 つ以上の案を生成する。独立した技術判断は 1 つの質問に束ねず、推奨とトレードオフを添えて別々に問う。
タスク、issue、調査レポートのいずれかがモック画像やスクリーンショットを参照しているなら、その画像ファイルを Read で開いてから設計する。テキスト側に記載が無いことを、その要素が存在しない根拠にしない。
- 案に
critic-design を起動する。プロンプトにタスクのタイトルを一字一句そのまま含め、結果は { verdict: "GO" | "NO-GO", weaknesses: string[], actionable: string[] } の JSON オブジェクト 1 つで返させる
- NO-GO は blocker をその場で解消してから進む。生き残った設計をトレードオフの根拠とともにユーザーに提示し、承認を待つ
- 承認後、技術判断に DR が必要か問う
Phase 3: Plan 生成
承認された設計を、独立して実装可能な成果の束 (unit) に実装順で分解する。分解の結果は PLAN_SCHEMA 相当の JSON { test_command, reference_module, units: [{ id, goal, contract, files: string[], tests: [{ id, name }], seam }] } に直列化する。分解はテスト先行で構成し、unit の大きさはテストの束から機械的に決める。設計全体から受け入れテスト候補を列挙し、成果のまとまりごとの束へ分け、各束が触るファイルを割り当てて unit にする。束の大きさは non-seam unit の上限に収め、超える束はさらに分ける。検証可能な振る舞いの無い成果 (docs/設定) からは受け入れテスト候補が出ないので、束とは別に unit を立てる。
- id は U-001/T-001 形式の連番で、T-NNN は plan 全体で一意にする
- tests[].name は条件 + 期待結果の 1 行言明。code workflow がテスト名として逐語使用し、build が固定文字列で照合する
- 検証可能な振る舞いが無い unit (docs/設定) は tests を空配列にする。build はその unit を Red-Green ではなく直接実装の 1 ステップとして進める
- 各 unit のテストは自分の境界をテストダブルへ置き換えるので、tests を持つ unit が 2 つ以上になったら seam unit をちょうど 1 つ最後に置き
seam: true を付ける。その tests は unit 間の境界を跨いで実モジュールを動かし、テストダブルへ置き換えるのはシステム外部との I/O に限り、unit どうしをつなぐ接続を assert する。seam unit が無い plan は build の validate() が reject する
- non-seam unit の上限は files 3 つ、tests 4 個。seam unit の tests は unit 境界を跨ぐので files が増え、この上限の対象外になる。上限を超えた unit は成果を軸に分割し、生じた新しい unit 構成をユーザーと確認する。スコープ外へ切り出した候補は plan から外し、backlog candidates に回す。この上限は seam の除外も含めて
workflows/build.js の UNIT_CAPS が決定論的に強制する。変更はこの記述と UNIT_CAPS を同一コミットで揃える
- 自己点検 (必須フィールドの欠落、id の重複、units、files、goal、contract のいずれかが空) と書き出し前検証を通す。通ったら
${CLAUDE_SKILL_DIR}/templates/plan.md の骨格で .claude/workspace/planning/YYYY-MM-DD-<slug>.plan.md に書き出す。slug はタイトルの小文字ハイフン区切り。## Plan と ## Backlog candidates の両節を含める
- 受け入れテスト候補のうち test_command で実行できない基準 (画面の見た目確認、外部サービスとの手動連携など) は T-NNN にせず、
### 実機確認 へ委譲する。委譲した基準には、それを引き取る機構 (test-storybook、コードレビューなど) を添える
- ドメインフィールドを描画する unit は、表示するフィールドを T-NNN に 1 フィールド 1 件で列挙する。まとめて 1 件にすると個別フィールドの欠落を検出できない
test_command
test_command の失敗は計画スコープだけに帰着できなければならない。リポジトリ全体の型エラーやフォーマット差分といった既存負債を抱えたリポジトリでは、触るディレクトリだけを lint し、型チェック出力を path パターンでフィルタしてゲートを絞る。内容 grep では絞らない。build の Revalidate も code の verify もリポジトリルートから走るので、ルートから実行して成立するコマンドとして書く。
base
base: には plan を実装するブランチ (PR のベースブランチ) を書く。タスク説明か会話から読み取り、指定が無ければ現在の checkout のブランチを書く。
reference_module
contract が引用できるのは 1 箇所の振る舞いだけで、周辺構造の手組みは止まらない。候補は Phase 2 で探索済みなので、ここでは結果を reference_module: { path, files, instances } に記録するだけにし、やり直さない。構造は reference_module セクションに書き、各 unit はそこを参照する。
- 骨格が 4 ファイル未満に収まるときだけ U-001 をその構造複製 (同じディレクトリ配置/コンポーネント名/export 名。tests は空配列) にする。収まらないときは layer ごとに unit を割り、各 unit が担当分を複製する
- 維持する共有慣例 (合成する共有コンポーネント/フォーマット処理の置き場所/状態の渡し方) を明記する。逸脱は plan に理由を書いたときのみ許す
- 候補が複数なら画面の組がもっとも近いものを選び、他は prose に名前を挙げる
- 一致が無ければ null とし、この形が新規である理由を prose に書く。理由の無い null は planning の欠陥として扱う
- instances が 2 以上なら「N 例目」と prose に書き、実装者へ設計でなく複製を指示する
前提 (preconditions)
既存の依存先のみを、リポジトリルート起点の path 単独か path + stable anchor の 2 形式で書く。anchor は ugrep -F が固定文字列として一致する公開シンボル名 1 つに限り、private な実装詳細/コメント文字列/行番号は使わない。安定したシンボルが無ければ path のみの行にする。unit が新しく作るファイルは載せない。
contract
生成でなく選択で書く。prose で振る舞いを素描したりコード片を新造したりせず、contract は引用 + やりたいこと 1 行のセットにする。引用は、コードベースの既存の形 (path + 公開シンボル、前提と同じ stable anchor 規則) > docs/wiki のページ > pinned version の公式 docs への deep link の優先順で選び、外部ライブラリは SOURCING.md に従う。引用できる出典が無い新規の形は signature を発明せず、形の決定は実装に委ねて受け入れテストが振る舞いを固定する。引用した path + シンボルは ### 前提 にも載せる。
モックや設計資料が UI 文言 (ラベル、placeholder、ボタン名、選択肢名) を逐語で持つなら、出典のパスを添えて contract にそのまま写す。
書き出し前検証
build workflow の Revalidate と同じリポジトリルートで検証し、失敗した行は修正するか落とす。base: が現在の checkout と異なるブランチを指すときは、base ブランチ側の内容で検証する。ファイルの実在は test -f <path> の代わりに git cat-file -e <base>:<path> を使い、anchor は git show <base>:<path> | ugrep -F '<pattern>' を使う。
### 前提 の各行。path は test -f <path>、anchor は ugrep -F '<pattern>' <path> (base が異なるときは上記の base ブランチ形式)
units[].files と reference_module.files のうち既存ファイルを指す行を test -f <path> で確認 (同じく base ブランチ形式に置き換え)
- 既存ファイルを触る unit があるのに
### 前提 が空か不在なら失敗。要となる依存を anchor する行を足す
reference_module: null は理由の明記が prose に無ければ失敗
- templates/plan.md が定める行数規則を超えていないこと
- 各 non-seam unit の
files と T-NNN の個数を数え、unit 上限に収まっていること。超えていれば分割してから再検証する
- test_command をリポジトリルートで 1 回実行する。plan より前から在る原因 (script 不在/リポジトリ全体の負債) で失敗したら、
### test_command に従ってコマンドを絞り直し、絞った理由を plan の prose に書く
- T-NNN のうち test_command で実行できない基準が紛れていないこと。紛れていれば
### 実機確認 へ移す
出力
以下を会話で呼び出し元に返す。
| 項目 | 内容 |
|---|
| ready | plan が自己点検を通過し、未決着の論点が無いとき true |
| plan | 自己点検済みの構造化 plan |
| plan file | 書き出した .plan.md のパス |
| blockers | ready = false の原因のうちユーザー判断が要る論点 |
| backlog candidates | スコープ外へ切り出した候補。無ければ「なし」 |
| 設計要約 | 採用した案、比較した案、critic-design の判定、DR 要否 |