以下の内容はhttps://smooth-pudding.hatenablog.com/entry/2026/02/19/212356より取得しました。


AIの力を借りながら Water Sort Puzzle のソルバをまた作ってみた (cc-sdd)

以前 Water Sort Puzzle のソルバを作る記事を書きました。
smooth-pudding.hatenablog.com

あれから9ヶ月ぐらい経ち、AIの開発ツールも飛躍的に進化しました。同じようなテーマに取り組んでみても面白いかなと思い、再度挑戦してみます。

Water Sort Puzzle ってどんなゲーム?

YouTube とかでプレイ動画を調べて見るのが早いです。例えば↓
www.youtube.com

前回と変わったこと

前回の記事では Cursor を使って開発しました。大方針は自分で立てつつ、適度に指示の粒度を調整して、いい感じに作ってもらう、という方式を取りました。

あれからしばらく経って、Cursor から Claude Code に乗り換えました。今も変わらず Claude Pro を契約して使っています。
smooth-pudding.hatenablog.com

「今一番イケてるAIツールは?」という質問の答えは数週間ごとにコロコロ入れ替わりますが、その中でも Claude Code は結構息が長いような気がしています。何度か大人気の座を受け渡しては、モデルの公開ごとにまた人気を盛り返す、という印象です。

ツールだけでなく、活用の仕方も進化してきました。Vibe Coding の時代を経て、現在は仕様駆動開発 (Specification Driven Development, SDD) が主流の手法になっています*1

この SDD をアシストしてくれるツールとして cc-sdd というオープンソースのツールがあります。今回はこのツールを使って、イマドキ?の SDD っぽい作り方で改めて Water Sort Puzzle のソルバーを作ってみたいと思います。

参考文献

cc-sdd の具体的な使い方や各プロセスの意義については、こちらの記事が非常によくまとまっています。今回の記事はこれを読んで実践してみた、という風な位置づけになります。
zenn.dev

cc-sdd のソースコードはこちらです。
github.com


ソースコードの README にある Related Resources の文献も、cc-sdd の意義や特性を理解する上で非常に役に立ちました。
zenn.dev
speakerdeck.com

環境構築

前回と同様、Python で実装することにします。成果物は GitHub で公開したいので、以下の手順で準備を勧めます。

  1. GitHub で作業用のリポジトリを作成
  2. 適当な場所で clone
  3. uv で Python 環境の用意
  4. cc-sdd のインストール

GitHub で作業用のリポジトリを作成

ブラウザで自分の GitHub アカウントにログインし、適当なリポジトリを作成します*2。設定は以下のようにしました。

  • Public リポジトリ
  • README ファイルを追加
  • Python の .gitignore を追加
  • MIT ライセンスを追加

リポジトリ名は water-sort-puzzle-solver-2026 としました。この記事が公開されているころには、ここに完成品が上がっていることでしょう。
github.com

適当な場所で clone

コンソールを開いて、リポジトリフォルダを置く場所に移動してから、以下のコマンドを実行します*3

$ git clone git@github.com:mat-der-D/water-sort-puzzle-solver-2026.git

無事 clone されて、以下のフォルダ・ファイルが追加されました。

$ tree -a -L 1 water-sort-puzzle-solver-2026/
water-sort-puzzle-solver-2026/
├── .git
├── .gitignore
├── LICENSE
└── README.md

2 directories, 3 files

uv で環境構築

Python の環境構築のデファクトスタンダードは uv のようなので、こちらを使って環境を整えておきます*4

$ cd water-sort-puzzle-solver-2026
$ uv init .
Initialized project `water-sort-puzzle-solver-2026` at `/(〜中略〜)/water-sort-puzzle-solver-2026`
$ tree . -a -L 1
.
├── .git
├── .gitignore
├── .python-version
├── LICENSE
├── README.md
├── main.py
└── pyproject.toml

2 directories, 6 files

これで Python を使う準備ができました。試しに main.py を実行してみましょう。

$ uv run main.py
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
Creating virtual environment at: .venv
Hello from water-sort-puzzle-solver-2026!

このタイミングで仮想環境の .venv が作成されたようです。もう一回実行してみると「Hello ...」の部分だけ表示されました。

$ uv run main.py
Hello from water-sort-puzzle-solver-2026!

ここで一旦 commit しておきます。今後も作業中に適宜 commit しますが、説明は省略します。

$ git add .
$ git commit -m "[feat] Prepare Python environment"
[main bee478d] [feat] Prepare Python environment
 4 files changed, 22 insertions(+)
 create mode 100644 .python-version
 create mode 100644 main.py
 create mode 100644 pyproject.toml
 create mode 100644 uv.lock

cc-sdd のインストール

npm がインストール済みであれば、コマンド一つで cc-sdd をインストールできます。公式の README に従って日本語環境でインストールしてみます。

$ npx cc-sdd@latest --claude --lang ja
Need to install the following packages:
cc-sdd@2.1.1
Ok to proceed? (y)

問題ないので y と入力して Enter します。

Ok to proceed? (y) y

Planned changes:
  • Commands (.claude/commands/kiro/) — new (11 file(s))
  • Project Memory document (CLAUDE.md) — new (1 file(s))
  • Settings templates and rules (.kiro/settings/) — new (25 file(s))

✅ Setup completed: written=37, skipped=0


== Recommended models ==
  • Claude Opus 4.5 or newer


== Next steps ==
  1. Launch Claude Code and run `/kiro:spec-init <what-to-build>` to create a new specification.
  2. Tip: Steering holds persistent project knowledge—patterns, standards, and org-wide policies. Kick off `/kiro:steering` (essential for existing projects) and  `/kiro:steering-custom <what-to-create-custom-steering-document>`. Maintain Regularly
  3. Tip: Update `{{KIRO_DIR}}/settings/templates/` like `requirements.md`, `design.md`, and `tasks.md` so the generated steering and specs follow your team's and project's development process.
npm notice
npm notice New major version of npm available! 10.9.2 -> 11.10.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.10.0
npm notice To update run: npm install -g npm@11.10.0
npm notice

とても親切なインストラクションが表示されました。cc-sdd に必要な諸々のファイルが生成され、種々のコマンドで操作ができるようになりました。

$ tree -a -L 1
.
├── .claude
├── .git
├── .gitignore
├── .kiro
├── .python-version
├── .venv
├── CLAUDE.md
├── LICENSE
├── README.md
├── main.py
├── pyproject.toml
└── uv.lock

5 directories, 8 files

git 準拠での差分はこんな感じ。

$ git status .
ブランチ main
このブランチは 'origin/main' よりも1コミット進んでいます。
  (use "git push" to publish your local commits)

追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)
	.claude/
	.kiro/
	CLAUDE.md

nothing added to commit but untracked files present (use "git add" to track)

ちなみに「steering 作ったほうがいいよ!」と言われていますが、今回は空の状態から作るので、作っても作らなくても対して変わらないはずということで、無視します。既存のプロジェクトがあり、そこに機能を追加するという文脈なら、steering は必須だと思います。

cc-sdd で作成してみる

準備が整ったので早速作っていきます。先程のインストラクションでは「Opus 4.5 以上がおすすめ!」とか書いてましたが、Opus なんて使ったら一瞬でクレジットが溶けてしまうので、今回は Sonnet 4.5 メインで進めていきます。

cc-sdd での開発は以下のステップを踏みます。

内容 コマンド 作成/更新されるもの (spec.md 以外)
作業環境の作成 /kiro:spec-init requirements.md (作成)
要件の作成 /kiro:spec-requirements requirements.md (更新)
要件の精査 (option) /kiro:validate-requirements -
設計書の作成 /kiro:spec-design design.md (作成), research.md (作成)
実装計画の作成 /kiro:spec-tasks tasks.md (作成)
実装の実行 /kiro:spec-impl 実装されたファイル
実装の検証 (option) /kiro:validate-impl -

いずれも Claude Code のコマンドとして実行されるものなので、まずはリポジトリのルートで Claude Code を起動します。

$ claude .
Claude Code 起動画面

作業環境の作成

spec-init コマンドを実行します。引数にはプロジェクトの概要説明を入れるようです。今回は想定する仕様がさほど大きくないので、ざっくり与えておきます。

> /kiro:spec-init "Water Sort Puzzle のソルバ CLI"

すると以下のように表示されました。

● 生成されたフィーチャー名
                                                                                      
  water-sort-solver-cli        

  「Water Sort Puzzle ソルバ CLI」というプロジェクト説明から、ツールの本質(ソルバ)と形式 
  (CLI)を端的に表す名前を採用しました。
                                                                                           
  ---                                                       
  プロジェクト概要

  Water Sort Puzzle(ウォーターソートパズル)をコマンドラインで解くソルバツールの開発。

  作成ファイル

  - .kiro/specs/water-sort-solver-cli/spec.json
  - .kiro/specs/water-sort-solver-cli/requirements.md

  次のステップ

  /kiro:spec-requirements water-sort-solver-cli

  注意事項

  この段階では初期化のみを行い、要件・設計・タスクの生成は意図的に行っていません。スペック
  駆動開発では各フェーズを分離し、人間のレビューと承認を挟むことで品質を担保します。次フェ
  ーズ(要件定義)では上記コマンドを実行し、要件の生成・承認後に設計フェーズへ進みます。

メッセージの通り、.kiro/specs/ 以下に water-sort-solver-cli というフォルダが作られ、その下に2つのファイルが追加されました。

$ tree -a .kiro/specs
.kiro/specs
└── water-sort-solver-cli
    ├── requirements.md
    └── spec.json

requirements.md の中身は以下の通りです。箱だけがあり、まだ具体的な要件は入力されていません。メッセージのとおりです。

# Requirements Document

## Project Description (Input)
Water Sort Puzzle のソルバ CLI

## Requirements
<!-- Will be generated in /kiro:spec-requirements phase -->

spec.json は以下のような内容です。これは現在の状態を管理するためのファイルで、"phase" が "initialized" になっている通り、この spec は初期化されたできたてほやほやであることが記されています。

{
  "feature_name": "water-sort-solver-cli",
  "created_at": "2026-02-16T00:00:00+00:00",
  "updated_at": "2026-02-16T00:00:00+00:00",
  "language": "ja",
  "phase": "initialized",
  "approvals": {
    "requirements": {
      "generated": false,
      "approved": false
    },
    "design": {
      "generated": false,
      "approved": false
    },
    "tasks": {
      "generated": false,
      "approved": false
    }
  },
  "ready_for_implementation": false
}

要件の作成

次は spec-requirements コマンドを実行します。メッセージの通りのコマンドを実行してみます。

> /kiro:spec-requirements water-sort-solver-cli

スキル実行の許可を求められたので、もちろん許可して実行します。

実行結果は以下のように返ってきました。

● 生成された要件サマリー            

  以下の6つの要件エリアで要件を定義しました:                                              
   
  - 要件 1 — パズル状態の入力: stdin                                                       
  またはファイル(YAML/JSON/テキスト)でボトル配色を受け取る
  - 要件 2 — パズル状態の検証: 入力の整合性チェックおよび --validate フラグ対応
  - 要件 3 — 自動解法(ソルバ): BFS/A* による探索、戦略選択・タイムアウト対応
  - 要件 4 — 解法の表示: ステップ表示・出力フォーマット(text/json/yaml)・verbose モード
  - 要件 5 — CLI インターフェース: --help / --version / 終了コード規約
  - 要件 6 — エラーハンドリング: ファイル不存在・形式エラー・デバッグ出力の stderr 分離

  ---
  ドキュメントの更新状況

  - .kiro/specs/water-sort-solver-cli/requirements.md — 要件定義書を生成・更新
  - .kiro/specs/water-sort-solver-cli/spec.json — phase: "requirements-generated",
  approvals.requirements.generated: true に更新

  ---
  次のステップ

  要件を確認し、問題がなければ以下を実行してください:

  /kiro:spec-design water-sort-solver-cli

  修正が必要な場合はフィードバックをお知らせください。要件を更新して再生成します。

  注意: ステアリングディレクトリ (.kiro/steering/) が空です。プロジェクト全体のコンテキスト
  がない状態で生成したため、既存コードベース(main.py,
  pyproject.toml)の構成を参考にしています。必要に応じて /kiro:steering 
  でステアリングを設定することを推奨します。

requirements.md を開くと、以下のような立派な内容が書かれています。6つの要件と、その受け入れ条件について記述があります。

# 要件定義書

## はじめに

Water Sort Puzzle ソルバ CLI は、ウォーターソートパズル(カラーウォーターソーティングゲーム)の初期状態をコマンドライン引数またはファイルで受け取り、最短または有効な手順を自動探索して解を出力する Python 製 CLI ツールである。ユーザーはパズルの盤面をテキストで記述し、ツールを実行するだけで解法ステップを取得できる。

## 要件

### 要件 1: パズル状態の入力

**目的:** パズルプレイヤーとして、ボトルの初期配色をCLIに入力できるようにしたい。手動でパズルを解く時間を節約するため。

#### 受け入れ基準

1. The Water Sort Solver CLI shall ボトル配列を標準入力またはファイル(`--input` オプション)から受け取ること
2. When `--input` オプションにファイルパスが指定された場合、the Water Sort Solver CLI shall 指定ファイルを読み込んでパズル状態を解析すること
...(略 79行)

また spec.json も更新されていますが、メッセージの通りの変更で、特に面白いわけでもないので省略します。

現時点ではタイトルから想像した要件が並んでいるので、自分がイメージする機能に合っているのか、ひとつひとつ確認します。ずれていたら「こうしてほしい」と依頼して、再度作成してもらいます。

要件の精査

一つひとつ確認していきます。

要件 1: パズル状態の入力
### 要件 1: パズル状態の入力

**目的:** パズルプレイヤーとして、ボトルの初期配色をCLIに入力できるようにしたい。手動でパズルを解く時間を節約するため。

#### 受け入れ基準

1. The Water Sort Solver CLI shall ボトル配列を標準入力またはファイル(`--input` オプション)から受け取ること
2. When `--input` オプションにファイルパスが指定された場合、the Water Sort Solver CLI shall 指定ファイルを読み込んでパズル状態を解析すること
3. The Water Sort Solver CLI shall ボトルをYAML・JSON・またはシンプルなテキスト形式で記述できること(各ボトルは色の配列で表現)
4. When パズル入力が与えられた場合、the Water Sort Solver CLI shall ボトル数と各ボトルの容量(色セグメント数)を認識すること
5. The Water Sort Solver CLI shall 標準的なパズルサイズ(ボトル数 4〜20本、容量 4 セグメント)に対応すること

パズル状態は結構複雑なので、標準入力はなくても良さそうです。この一点のみ変更要求しましょう。

要件 2: パズル状態の検証
### 要件 2: パズル状態の検証

**目的:** パズルプレイヤーとして、入力したパズル状態が有効かどうか確認できるようにしたい。不正な入力に気づいてやり直しできるため。

#### 受け入れ基準

1. When パズル状態が入力された場合、the Water Sort Solver CLI shall 各色の合計セグメント数がボトル容量の倍数であることを検証すること
2. If 同じ色のセグメント総数がボトル容量と一致しない場合、the Water Sort Solver CLI shall エラーメッセージとともに終了すること
3. If ボトルが0本または容量が0のボトルが存在する場合、the Water Sort Solver CLI shall 「無効なパズル状態」としてエラーを報告すること
4. When パズル状態が既に解決済みの場合、the Water Sort Solver CLI shall 「パズルはすでに解決されています」と通知して終了すること
5. The Water Sort Solver CLI shall `--validate` フラグのみを指定した場合、解を探索せずに入力の検証結果のみを返すこと

入力時点で検査できるポイントについては十分検査できているように思います。ここは特に修正依頼なしでよいでしょう。

要件 3: パズルの自動解法(ソルバ)
### 要件 3: パズルの自動解法(ソルバ)

**目的:** パズルプレイヤーとして、有効な解法手順を自動的に取得したい。自力では解けない難しいパズルを突破するため。

#### 受け入れ基準

1. When 有効なパズル状態が入力された場合、the Water Sort Solver CLI shall BFS(幅優先探索)またはA\*アルゴリズムで解を探索すること
2. The Water Sort Solver CLI shall 解が存在する場合に有効な移動手順(ボトル番号のペア列)を返すこと
3. The Water Sort Solver CLI shall `--strategy` オプションで `bfs`(最短手数)または `dfs`(高速探索)を選択できること
4. While 解探索が実行中の場合、the Water Sort Solver CLI shall `--timeout` オプションで指定された秒数(デフォルト 30 秒)以内に探索を完了すること
5. If 解が存在しない場合、the Water Sort Solver CLI shall 「このパズルは解決不可能です」と報告すること
6. If タイムアウトが発生した場合、the Water Sort Solver CLI shall タイムアウトを通知してプロセスを終了すること

1. と 3. が矛盾しています。深さ優先探索 (DFS) と幅優先探索 (BFS) ができれば十分なので、そう伝えることにします。
タイムアウトについては、タイムアウトなし設定が欲しいので、それも要求してみましょう。
他は問題なさそうです。

要件 4: 解法の表示
### 要件 4: 解法の表示

**目的:** パズルプレイヤーとして、解法の手順を分かりやすい形式で確認したい。実際のゲーム画面で手順を再現できるため。

#### 受け入れ基準

1. When 解が見つかった場合、the Water Sort Solver CLI shall 各ステップを「ボトル X → ボトル Y」の形式で標準出力に表示すること
2. The Water Sort Solver CLI shall 解法の総手数をサマリーとして表示すること
3. Where `--verbose` フラグが指定された場合、the Water Sort Solver CLI shall 各ステップ後のボトル状態をビジュアル表示(テキストアート)すること
4. Where `--output` オプションが指定された場合、the Water Sort Solver CLI shall 解法をファイルに書き出すこと
5. The Water Sort Solver CLI shall `--format` オプションで `text`(デフォルト)・`json`・`yaml` の出力形式を選択できること

これは問題なさそうです。

要件 5: CLI インターフェース
### 要件 5: CLI インターフェース

**目的:** パズルプレイヤーとして、直感的なコマンドラインインターフェースを通じてツールを操作したい。学習コストを最小化するため。

#### 受け入れ基準

1. The Water Sort Solver CLI shall `--help` オプションで使用方法・オプション一覧・使用例を表示すること
2. The Water Sort Solver CLI shall `--version` オプションでバージョン番号を表示すること
3. When 不明なオプションが指定された場合、the Water Sort Solver CLI shall エラーメッセージとともにヘルプの参照方法を表示すること
4. The Water Sort Solver CLI shall 正常終了時に終了コード 0 を返し、エラー時に非ゼロの終了コードを返すこと
5. The Water Sort Solver CLI shall `uv run python main.py [オプション]` の形式で実行できること

これも自然な要件かと思います。問題なし。

要件 6:
### 要件 6: エラーハンドリングとユーザビリティ

**目的:** パズルプレイヤーとして、エラーが発生した場合に原因を把握して対処できるようにしたい。トラブルシューティングを迅速に行うため。

#### 受け入れ基準

1. If 入力ファイルが存在しない場合、the Water Sort Solver CLI shall 「ファイルが見つかりません: {パス}」というエラーメッセージを表示すること
2. If 入力ファイルの形式が不正な場合、the Water Sort Solver CLI shall 解析エラーの行番号と内容を含むエラーメッセージを表示すること
3. The Water Sort Solver CLI shall すべてのエラーメッセージを stderr に出力すること
4. When `--debug` フラグが指定された場合、the Water Sort Solver CLI shall 探索の進捗(訪問済み状態数、経過時間)を stderr に出力すること

2. の「行番号」がソースコードなのか入力ファイルなのか不明瞭ですが、ソースコードであれば不要ですし、入力ファイルであれば過剰な要求に思います。行数の指定ではなく、どのような意味のエラーであったかを表示すればよさそうです。

修正要求まとめ

以上をまとめると、以下の修正要求となりました。

以下の点について requirements.md を更新してください。

# 要件1
- パズルの状態の入力は、ファイルからの入力のみをサポートしてください。

# 要件3
- 探索するアルゴリズムは BFS と DFS をサポートしてください。
- タイムアウトについて、タイムアウトなしオプションを選択できるようにしてください。

# 要件6
- 入力ファイルの形式が不正だった場合は、その不正の種類や期待した形式が分かるようなメッセージを表示するようにしてください。行番号は不要です。

これを Claude Code に投げてみます。返答は以下のようなものでした。

● 以下の変更を行いました:                                                                 
  
  要件 1 — 基準 1                                                                          
  - 「標準入力または」を削除し、ファイル入力のみに限定
  - はじめにの説明文も同様に修正                                                           
                                                                                           
  要件 3 — 基準 135(新規追加)
  - A* をDFSに変更
  - --strategy の説明を bfs(最短手数・デフォルト)/ dfs(高速探索)に更新
  - 新たに基準 5 を追加: --timeout 0 または --no-timeout でタイムアウトなし選択に対応

  要件 6 — 基準 2
  - 行番号を削除し、エラーの種類と期待フォーマットを示すメッセージに変更

  他に修正したい点があればお知らせください。問題なければ次のステップへ:

  /kiro:spec-design water-sort-solver-cli

しっかり要求を汲み取ってくれたみたいなので、これでOKです。

次のステップに行く前に、一旦 /clear で文脈を削除しておきます。

設計書の作成

作成した要件に沿って設計書を作ってもらいましょう。以下のコマンドを実行します。

> /kiro:spec-design water-sort-solver-cli -y

ここで "-y" は「直前のプロセスの結果を承認します」という意味です。ここでは要件の作成部分について承認しました、という意味になります。現時点ではまだ要件の承認を与えていないので、これがないと「未承認だから進めません」という風なエラーになります。

承認なしに実行した場合

気を取り直して "-y" で実行します。このプロセスは結構時間がかかります。

5分ほど待って、以下の返答がありました。

---                             
  設計生成完了
                                                                                           
  Status: .kiro/specs/water-sort-solver-cli/design.md を生成しました。
                                                                                           
  Discovery Type: フルディスカバリー(New Feature / グリーンフィールド)

  Key Findings:
  1. 状態表現: tuple[tuple[str, ...], ...] による immutable 表現で BFS visited 集合への
  O(1) 参照を実現。research.md に根拠を記録。
  2. CLI ライブラリ: 追加依存ゼロの argparse を採用。外部依存は YAML 対応の pyyaml
  のみに抑制。
  3. タイムアウト: signal.alarm(POSIX 専用)を避け、ループ内 time.perf_counter()
  ポーリングでクロスプラットフォーム互換を確保。

  Next Action: 設計をレビューし、承認後に /kiro:spec-tasks water-sort-solver-cli -y
  でタスク生成へ進んでください。オプションで /kiro:validate-design water-sort-solver-cli
  による設計品質レビューも利用できます。

  Research Log: .kiro/specs/water-sort-solver-cli/research.md を更新しました。

まず、新しく作られたのは以下の2つです。

ファイル名 概要 行数
design.md 設計書本体 659行
research.md 設計のために調査が必要だった事項の結果 117行

これからこれらを確認し、OKなら承認します。

しかしあまりにも大きくて確認が大変です。そこで、まずは AI に品質の評価をしてもらいましょう。

/compact で現在の文脈を圧縮してから*5、以下のコマンドを実行します。

> /kiro:validate-design water-sort-solver-cli

すると以下のように返ってきました。(長いので一部を割愛しました。)

● 設計書と評価ガイドラインを確認しました。ステアリングディレクトリは空のため、設計自体で評 
  価を進めます。                                            
                                                                                           
  ---                                                       
  設計レビュー: water-sort-solver-cli                                                      
                                                            
  設計レビューサマリー

  型安全性・レイヤー分離・要件トレーサビリティのいずれも高品質。グリーンフィールドのスコー
  プに対してアーキテクチャの粒度は適切で、実装に進むのに必要な情報がほぼ揃っている。ただし
  、以下の 3 点が実装時に実際の混乱を招く可能性があるため、軽微な修正を推奨する。

  ---
  Critical Issues(重大懸念事項)

  🔴 Critical Issue 1: CLIArgs 型が models.py のコードブロックに定義されていない

(〜詳細略〜)

  ---
  🔴 Critical Issue 2: formatter.py が solver.py の apply_move() に暗黙依存(レイヤー違反)

(〜詳細略〜)

  ---
  🔴 Critical Issue 3: ボトル容量(BOTTLE_CAPACITY)の伝達経路が未定義

(〜詳細略〜)

  ---
  Design Strengths(設計の強み)

(〜詳細略〜)

  ---
  Final Assessment

  決定: GO(条件付き)

  根拠: 3
  つの指摘事項はいずれも根本的なアーキテクチャ変更を要しない局所的な修正で解決可能。Issue 13 は design.md の該当セクションに数行追記するだけ、Issue 2 も main.py
  へのロジック移動または models.py への関数移動で解消できる。これらを design.md
  に反映した後、タスク生成へ進むことを推奨する。

  次のステップ:
  - 上記 3 点を design.md に反映(任意: 軽微であれば tasks
  フェーズで実装者判断に委ねることも可)
  - design.md の修正後: /kiro:spec-tasks water-sort-solver-cli -y でタスク生成へ進む

  ---
  ご意見をお聞かせください: Issue 2(apply_move() の依存)について、(a) main.py
  で中間状態を事前生成、(b) models.py
  に移動、のどちらが好ましいですか?または現状の設計のまま(実装時に判断)としますか?

3つの指摘事項があり、1と3はおすすめの解決策が一つ、2はおすすめが二種類あるようです。1, 3 はおすすめで解決してもらうことにして、2についてはメリット・デメリットを提示してもらいましょう。以下のように返信します。

> Issue 1, 3 については推奨の内容で design.md に反映させてください。Issue 2 については、2つの方法のトレードオフを分析したいので、それぞれのメリット・デメリットを提示してください。

1, 3 については適用した上で、いろいろな観点で比較してくれました。まとめは以下のとおりです。

  ---
  比較まとめ

  Column 1: レイヤー整合性
  案 (a): main.py で事前生成: ✅ 完全維持
  案 (b): models.py に移動: ✅ 完全維持(Output→Models は許容)
  ────────────────────────────────────────
  Column 1: models.py の純粋性
  案 (a): main.py で事前生成: ✅ 変化なし
  案 (b): models.py に移動: ⚠️  ロジック追加(軽微)
  ────────────────────────────────────────
  Column 1: main.py のシンプルさ
  案 (a): main.py で事前生成: ⚠️  状態再生成ロジックが混入
  案 (b): models.py に移動: ✅ 変化なし
  ────────────────────────────────────────
  Column 1: 将来の再利用性
  案 (a): main.py で事前生成: —
  案 (b): models.py に移動: ✅ A* 等での再利用が容易
  ────────────────────────────────────────
  Column 1: 実装コスト
  案 (a): main.py で事前生成: ✅ 低(verbose 分岐を追加するだけ)
  案 (b): models.py に移動: ✅ 低(関数移動のみ)

  私の見立て: apply_move() は副作用のない純粋な状態変換関数であり、「ロジック」というよりは
  「型に付随する操作」に近い性質を持ちます。案 (b)
  の方が将来のアルゴリズム追加時の再利用性も高く、設計上自然です。ただし models.py を
  "ロジックなしのデータ定義のみ" として厳格に維持したい場合は案 (a) が適切です。

  どちらを採用しますか?決定次第、design.md に反映します。

トレードオフ分析を踏まえて、より詳しい前提でのおすすめが提示されました。(b) の方が自然らしいので、(b) で適用してもらうことにします。

> では案 (b) で design.md に反映させてください

念の為、もう一度 /compact して /kiro:validate-design water-sort-solver-cli を実行します。すると以下のように返ってきました。

● 設計書の内容を確認しました。前セッションの3点修正(CLIArgs追加・BOTTLE_CAPACITY・apply_mo
  ve移動)がすべて正しく反映されていることを確認しました。レビューを実施します。           
                                                                                           
  ---                                                       
  設計レビュー:water-sort-solver-cli                                                      
                                                            
  Design Review Summary

  前回の3つの指摘事項(Issue 13)がすべて適切に反映されており、設計全体の構造的品質は大き
  く向上している。レイヤー境界・型安全性・要件トレーサビリティのいずれも水準を満たしている
  が、修正の副作用として生じた小規模な不整合が3点残存している。

(〜中略〜)

  ---
  Final Assessment

  判定: GO(条件付き)

  根拠: 3点はいずれも実装前に数行の修正で解消できるドキュメント不整合・型注釈のズレであり、
  アーキテクチャ上の根本的な問題ではない。前回の指摘事項がすべて適切に反映されており、設計
  全体の品質は実装開始に十分な水準に達している。

  次のステップ:
  - Issue 13 を design.md に反映(修正を適用する場合)
  - または現状のまま /kiro:spec-tasks water-sort-solver-cli -y でタスク生成に進む

  いずれかの対応をどうされますか?

別に問題なさそうですが、せっかくなので反映してもらいます。そしてせっかくなので、反映後にもしつこくもう一回 /compact + /kiro:validate-design を実行してみます。すると・・・

(〜前略〜)

  ---
  Final Assessment

  ✅ GO

  Rationale: Critical Issue 1 は build_parser()
  のコメント1行追加で解決可能な軽微な文書ギャップであり、アーキテクチャや型設計に影響しない
  。2ラウンドの修正で本質的な問題はすべて解消済みであり、実装に進む準備が整っている。

  Next Steps:
  - design.md に修正を反映する場合 → build_parser() の Implementation Notes に --no-timeout
   の実装メモを追記
  - そのまま進める場合 → タスク生成へ

  /kiro:spec-tasks water-sort-solver-cli -y

  ---
  --no-timeout の記載を design.md
  に追記してからタスク生成に進みますか?それとも現状のままタスク生成を行いますか?

条件なしの GO サインがでました。やったね。

本当はこのあと自分の目で確認が必要だと思いますが、面倒くさくなってきたので、このまま次に進みます。

実装計画の作成

/clear で一旦文脈を削除して、以下のコマンドを実行します。"-y" は「設計を承認する」という意味です。

> /kiro:spec-tasks water-sort-solver-cli -y

spec-design 同様、このプロセスもそこそこ時間がかかります。今回は5分ぐらいで終了しました。返答は以下のとおりです。

---                               
  ステータス: タスクを .kiro/specs/water-sort-solver-cli/tasks.md に生成しました。
                                                                                           
  タスクサマリー:
  - 合計: 7 メジャータスク、24 サブタスク                                                  
  - 全 31 件の要件をカバー(1.11.5, 2.12.5, 3.13.7, 4.14.5, 5.15.5, 6.16.4)
  - 平均タスクサイズ: 13 時間/サブタスク

  品質検証:
  - ✅ 全要件をタスクにマッピング済み
  - ✅ タスク依存関係を確認(125 並行可 → 67)
  - ✅ テストタスクを含む(7.1(P)7.2(P)7.3(P) は並行実施可能)

  タスク構成:
  1. 共有データモデルと基盤整備(models.py + 環境)
  2. 入力解析機能(parser.py)
  3. パズル検証機能(validator.py)
  4. ソルバ(solver.py)
  5. 出力フォーマッター(formatter.py)
  6. CLI エントリポイント(main.py)
  7. テスト実装

  次のアクション: tasks.md を確認し、承認後に実装を開始してください。
  実装開始前にコンテキストをクリアしてから /kiro:spec-impl water-sort-solver-cli 1.1 
  を実行してください。

これにより tasks.md というファイルが生成されました。このファイルには、実際に実装を進めるためのチェックリストがあります。以下はこのファイルの最初の部分です。

# 実装計画

- [ ] 1. 共有データモデルと基盤整備
- [ ] 1.1 プロジェクト基盤のセットアップ
  - `src/` ディレクトリと `src/__init__.py` を作成し、パッケージ構造を整備する
  - `tests/` ディレクトリを作成し、テスト用の基本構造を用意する
  - `pyproject.toml` に pyyaml 依存と Python 3.12+ 設定が揃っていることを確認し、不足があれば追記する
  - _Requirements: 5.5_

- [ ] 1.2 パズル状態・移動手順・解法結果の型定義
  - `BottleState`(色文字列タプル、下から上の順)と `PuzzleState`(ボトルタプルのイミュータブルなタプル)を定義する
  - `Move`(from_bottle / to_bottle の 0-indexed ペア)と `SolverResult`(solved フラグ・moves リスト・states_visited・elapsed_time)を定義する
  - `BOTTLE_CAPACITY` 定数(デフォルト 4)を定義する
  - _Requirements: 1.4, 3.2_

(〜後略〜)

全体で149行しかなく、この時点で大きな事故が起こるとはあんまり考えられないので、このまま実装に移行しちゃいます。

実装の実行

実装の実行は以下のコマンドを使います。

> /kiro:spec-impl water-sort-solver-cli (タスク番号) -y

タスクは細切れにされているので、タスク単位で実装を依頼しながら、細かく修正するという設計意図だと思われます。

とはいえ今回ぐらいの仕様なら一気に生成しても大したことなさそうなので、全部投げてみます。/clear のあと、以下を実行します。枝番は7番までだったのでこれで大丈夫なはず。

> /kiro:spec-impl water-sort-solver-cli 1 2 3 4 5 6 7 -y

元気よく実装を始めてくれました。デフォルトでテスト駆動開発で進めてくれるので安心感があります。

実装進行中の様子

10分弱で全体の実装を終えてくれました。

---                                                                
  実装完了サマリ                
                                                                                           
  実行タスク: フェーズ 17(全タスク)
  テスト結果: 91テスト / 91テスト 合格 ✅                                                  
                                                            
  作成ファイル                                                                             
                                                                                           
  ┌─────────────────────────┬──────────────────────────────────┐                           
  │        ファイル         │               役割               │                           
  ├─────────────────────────┼──────────────────────────────────┤                           
  │ src/__init__.py         │ パッケージ初期化                 │                           
  ├─────────────────────────┼──────────────────────────────────┤                           
  │ src/models.py           │ 型定義・apply_move() 純粋関数    │
  ├─────────────────────────┼──────────────────────────────────┤
  │ src/parser.py           │ YAML/JSON/テキスト入力解析       │
  ├─────────────────────────┼──────────────────────────────────┤
  │ src/validator.py        │ パズル状態検証・解決済み判定     │
  ├─────────────────────────┼──────────────────────────────────┤
  │ src/solver.py           │ BFS/DFS 探索・タイムアウト制御   │
  ├─────────────────────────┼──────────────────────────────────┤
  │ src/formatter.py        │ text/json/yaml 出力フォーマット  │
  ├─────────────────────────┼──────────────────────────────────┤
  │ main.py                 │ CLI エントリポイント(argparse) │
  ├─────────────────────────┼──────────────────────────────────┤
  │ tests/test_models.py    │ 15テスト                         │
  ├─────────────────────────┼──────────────────────────────────┤
  │ tests/test_parser.py    │ 17テスト                         │
  ├─────────────────────────┼──────────────────────────────────┤
  │ tests/test_validator.py │ 13テスト                         │
  ├─────────────────────────┼──────────────────────────────────┤
  │ tests/test_solver.py    │ 14テスト                         │
  ├─────────────────────────┼──────────────────────────────────┤
  │ tests/test_formatter.py │ 14テスト                         │
  ├─────────────────────────┼──────────────────────────────────┤
  │ tests/test_main.py      │ 18テスト(E2E含む)              │
  └─────────────────────────┴──────────────────────────────────┘

  動作確認

  $ uv run python main.py --input puzzle.yaml --strategy bfs
  ステップ 1: ボトル 1 → ボトル 5
  ...
  合計 13 手で解決しました。

main.py が編集されて、src/ と tests/ およびその中のファイル群が追加されました。

$ ls main.py
main.py
$ tree -a -L 1 src
src
├── __init__.py
├── __pycache__
├── formatter.py
├── models.py
├── parser.py
├── solver.py
└── validator.py

2 directories, 6 files
$ tree -a -L 1 tests
tests
├── __init__.py
├── __pycache__
├── test_formatter.py
├── test_main.py
├── test_models.py
├── test_parser.py
├── test_solver.py
└── test_validator.py

2 directories, 7 files

この時点で時間が遅くなったので、一旦区切りました。Claude のクレジット消費割合は70%弱ぐらいでした。

実装内容の検証

翌日、前回の文脈がまっさらの状態で、検証のコマンドを実行しました。

> /kiro:validate-impl water-sort-solver-cli

1分ほどで以下のように返ってきました。

● 全チェック完了です。バリデーションレポートを生成します。                      
                                                                                
  ---                                                                           
  実装バリデーションレポート                                                    
                                                                                
  フィーチャー: water-sort-solver-cli                                           
  日時: 2026-02-17
  フェーズ: implementation-complete

  ---
  1. タスク完了チェック

(〜中略〜)

  ---
  6. 判定

  ✅ GO

  ┌────────────────┬───────────────────────┐
  │      項目      │         結果          │
  ├────────────────┼───────────────────────┤
  │ タスク完了率   │ 27/27 (100%)          │
  ├────────────────┼───────────────────────┤
  │ テスト通過率   │ 91/91 (100%)          │
  ├────────────────┼───────────────────────┤
  │ 要件カバレッジ │ 6/6 (100%)            │
  ├────────────────┼───────────────────────┤
  │ 設計整合性     │ 6/6コンポーネント一致 │
  ├────────────────┼───────────────────────┤
  │ 重大な問題     │ なし                  │
  └────────────────┴───────────────────────┘

  実装はすべての要件・設計・タスクと完全に整合しており、デプロイ準備完了です。

どうやら問題なさそうです。実際に動かしてみます。となったところで問題が発覚しました。インプットのフォーマットがわかりません。

steering ファイルを追加する

ちょうど「既存機能への追加」という要件が生えてきたので、この時点で steering ファイル群を生成しておきます。/clear の後、以下を実行します。

> /kiro:steering

コードベースを分析し、以下のファイル群が生成されました。

$ tree .kiro/steering
.kiro/steering
├── product.md
├── structure.md
└── tech.md

これにより、次回以降 kiro の機能でプロジェクトを素早く正確に理解してくれるようになります。

cc-sdd で機能追加する

さて、「input のフォーマットがわからない」という問題が発生したので、/kiro:spec-init から改めてスタートしてみます。

> /kiro:spec-init "--input 引数で与えるファイルのフォーマット構造をヘルプで表示"

新しいフィーチャー名 "input-format-help" が作成されました。続けて要件ファイルを生成します。

> /kiro:spec-requirements input-format-help

今回は要件が小さくかつ具体的なので、初期生成されたもので問題なしでした。/clear の後、設計の生成を行います。

> /kiro:spec-design input-format-help -y

今回は3分弱で生成されました。ほぼ機械的な変更で validate するほどでもないので、このまま /clear してタスクの生成を行います。

> /kiro:spec-tasks input-format-help -y

タスクは 1~5 まで生成されました。/clear の後一気に依頼してみます。

> /kiro:spec-impl input-format-help 1 2 3 4 5 -y

5分ほどですべて生成されました。最後に validate-impl しておきます。

> /kiro:validate-impl input-format-help

結果は以下のとおりです。問題ないようです。

(〜前略〜)

  ---
  判定

  ✅ GO — 実装完了、全要件充足、リグレッションなし

  - 全 112 テスト合格(0 失敗)
  - 要件 1.15.4(計 16 項目)すべてトレース確認済み
  - 設計 design.md の構造・インターフェイスと完全一致
  - steering(tech.md, structure.md)の命名・インポート規則に準拠

ちなみに、この時点でクレジットは約40%消費ぐらいです。

動作確認

準備ができたので、以下の json のインプットを作ってみました。

{
    "bottles": [
        [ "R", "R", "B", "B" ],
        [ "B", "B", "Y", "Y" ],
        [ "Y", "Y", "R", "R" ],
        [ ]
    ]
}

実行結果は以下のとおりとなりました。

$ uv run main.py --input input.json 
ステップ 1: ボトル 1 → ボトル 4
ステップ 2: ボトル 1 → ボトル 4
ステップ 3: ボトル 3 → ボトル 1
ステップ 4: ボトル 3 → ボトル 1
ステップ 5: ボトル 2 → ボトル 3
ステップ 6: ボトル 2 → ボトル 3
合計 6 手で解決しました。

アカーン!同じ色が連続した部分が塊として移動していないようです。修正が必要ですね。合法手の適用の部分の修正が必要みたいです。

もう原因もほとんど分かっているので、cc-sdd 方式ではなく、直接命令します。

> @src/models.py の apply_move の実装がおかしい。同じ色が連続している場合は塊で移動するようにしてほしい。ただし、塊の長さが移動先の空きセグメント数よりも少ないなら、移動先のセグメントを埋める量だけ移動するように。 

すぐに直してくれました。以下は編集後の結果です。

$ uv run main.py --input input.json 
ステップ 1: ボトル 1 → ボトル 4
ステップ 2: ボトル 3 → ボトル 1
ステップ 3: ボトル 2 → ボトル 3
合計 3 手で解決しました。

解決していないですね・・・。コードを見てみると、終了条件がおかしそうです。

> @src/validator.py の is_solved の条件がおかしいです。water sort puzzle での終了条件は、各色のセグメントがそれぞれ同じボトルに満たされている状態です。 

すぐに修正されました。修正後の結果がこちらです。

$ uv run main.py --input input.json
ステップ 1: ボトル 1 → ボトル 4
ステップ 2: ボトル 3 → ボトル 1
ステップ 3: ボトル 2 → ボトル 3
ステップ 4: ボトル 2 → ボトル 4
合計 4 手で解決しました。

ちゃんと直りました!

冒頭で引用した動画の問題も解いてみましょう。

インプットは以下のようになります。

{
    "bottles": [
        [ "", "", "", "" ],
        [ "", "", "", "" ],
        [ "", "", "", "" ],
        [ "", "", "", "" ],
        [ "", "", "", "" ],
        [ "", "", "", "" ],
        [ "", "", "", "" ],
        [ ],
        [ ]
    ]
}

実行結果はこうなりました。

$ uv run main.py --input input.json
ステップ 1: ボトル 1 → ボトル 8
ステップ 2: ボトル 2 → ボトル 9
ステップ 3: ボトル 1 → ボトル 2
ステップ 4: ボトル 3 → ボトル 8
ステップ 5: ボトル 4 → ボトル 9
ステップ 6: ボトル 5 → ボトル 9
ステップ 7: ボトル 6 → ボトル 5
ステップ 8: ボトル 4 → ボトル 6
ステップ 9: ボトル 4 → ボトル 8
ステップ 10: ボトル 2 → ボトル 4
ステップ 11: ボトル 3 → ボトル 2
ステップ 12: ボトル 5 → ボトル 3
ステップ 13: ボトル 1 → ボトル 5
ステップ 14: ボトル 6 → ボトル 1
ステップ 15: ボトル 6 → ボトル 2
ステップ 16: ボトル 5 → ボトル 6
ステップ 17: ボトル 5 → ボトル 9
ステップ 18: ボトル 7 → ボトル 2
ステップ 19: ボトル 7 → ボトル 1
ステップ 20: ボトル 7 → ボトル 8
ステップ 21: ボトル 3 → ボトル 7
ステップ 22: ボトル 3 → ボトル 6
合計 22 手で解決しました。

正しいかどうかはちょっと面倒くさいので確かめませんが、動画は26手だったので、それよりやや短いようです。

ちなみに深さ優先探索をするとこうなりました。

$ uv run main.py --input input.json --strategy dfs
...
(〜中略〜)
...
ステップ 2423: ボトル 1 → ボトル 9
ステップ 2424: ボトル 5 → ボトル 9
ステップ 2425: ボトル 1 → ボトル 3
合計 2425 手で解決しました。

めっちゃ遠回りしてそう。

その後、適当な問題数問で確かめてみましたが、確かにちゃんと答えにたどり着いていそうでした。

感想

cc-sdd を使うと、数ステップに分けて機能を作成するので、じっくり人間がチェックできます。しかも最終ステップでは細かいタスクごとに実装できるので、人間が確認しやすい粒度に分解して PR を作成するなども可能で、やはり人間によるチェックに主眼を置いたスタイルなのかなと感じました。

一方、入念にチェックを重ねることを前提とした構成のため、今回のユースケースだとちょっと過剰かな、と感じました。特に後半の機能追加はかなりシンプルなので、plan モードで適当に命令するぐらいでもきっとうまく動いただろうな、という感じがします。ステップバイステップで確認する分、無駄に時間がかかった感触です。またクレジット消費も大きいのが気になりました。

結論としては、AI を使った開発では以下のように使い分けるのがよいのかなと思いました。

  • 小規模な機能実装
    →通常モードで命令を投げる
  • 中規模な機能実装、または要件が特殊な小規模実装
    →plan モードで命令を投げる
  • 大規模な機能実装、または要件が特殊な中規模実装
    →cc-sdd で仕様駆動開発

適材適所でうまく使い分ければきっと強い武器になると思います。

ではまた。

*1:もしかするとこれももう古い?最先端が爆速で変わりすぎて自信がありません。

*2:アカウントを持っていない方は作成 (無料) が必要です。

*3:git が未インストールの方はインストールが必要です。

*4:uv が未インストールの方はインストールが必要です。

*5:spec-design は5分もかかるプロセスなので、おそらく抱えている文脈量も相当なものだろう、という推定で実行しました。




以上の内容はhttps://smooth-pudding.hatenablog.com/entry/2026/02/19/212356より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14