Sprouted: 仕様駆動開発の上位フレームワークとしての仮説木

どうもakaです. 新しいフレームワークを考えたぞ! ということで公開します.

アイデアなんで, 出したもんがちだよね. ということで, まだ検討するべき部分はありつつも, とりあえず公開しました.

⚠️ 免責: 以下のほぼ100%生成AIにアイデアの添削, 文章の作成をしてもらい, akaがレビューしてます.

Sprouted: 仕様駆動開発の上位フレームワークとしての仮説木

はじめに:仕様駆動開発への違和感

2025年、仕様駆動開発(Spec-Driven Development, SDD)が注目を集めている。「仕様を書いてからAIにコードを生成させる」ツールが次々と登場し、「vibe coding」からの脱却が叫ばれている。

この流れ自体は正しい。曖昧なプロンプトでコードを書かせるより、意図を明確にしてから実装に入る方が品質は上がる。しかし、実際にこれらのツールを使っていると、ある違和感が拭えない。

結局、要求が変われば仕様も変わる。

SDDツールは「仕様をソースオブトゥルースとして扱え」と言う。だが、その仕様の根拠となる要求自体が変わり得るなら、仕様を「確定したもの」として扱うことにどれだけ意味があるのか。要求も仕様も設計も、すべて仮説ではないのか。

さらに言えば、「要求」「仕様」「設計」という階層の呼び名にこだわることにも疑問がある。本質は、達成したいことそのための手段が各階層で分離できていることであって、それぞれを何と呼ぶかは本質的ではない。

本稿では、この考え方を「Sprouted」というフレームワークとして定義する。Sproutedは、SDDを否定するものではなく、SDDを含むより上位の構造を提供するメタフレームワークである。

Sproutedの核:Why / What / How の再帰木構造

基本構造

Sproutedでは、あらゆる開発上の意思決定を木構造のノードとして管理する。各ノードは3つの属性を持つ。

ユーザーにとっては Why / What / How の3つだけ考えればよい。ただし、Whyの中に動機と制約の両方が入り得ることを意識すると、Whyの質が上がる。

階層間の接続:2本の線が階層を降りていく

Sproutedの再帰構造を理解する鍵は、階層間の接続が2本の線で構成されていることだ。

そして各ノードの中では、動機がWhatを生み、制約がHowの選択肢を絞る

TODOアプリを例に見てみよう。

graph TD
    subgraph "第1階層"
        WM1["Why(動機): タスクを忘れて困っている人がいる"]
        WC1["Why(制約): スマホ利用者が対象 / 個人開発規模"]
        What1["What: タスクを記録・管理できるようにしたい"]
        How1["How: TODOアプリを作る"]
        WM1 --> What1
        WC1 --> How1
        What1 --> How1
    end

    subgraph "第2階層"
        WM2["Why(動機): ユーザーは日常的にタスクが発生・完了・変更される"]
        WC2["Why(制約): TODOアプリ(Web/モバイル)が前提"]
        What2["What: タスクの追加・完了・一覧表示ができる"]
        How2["How: React + SQLiteで実装する"]
        WM2 --> What2
        WC2 --> How2
        What2 --> How2
    end

    subgraph "第3階層"
        WM3["Why(動機): 一覧表示は件数が増えると見づらくなる"]
        WC3["Why(制約): React + SQLiteが前提。SQLのORDER BY/WHEREが使える"]
        What3["What: タスクを期限や優先度で並び替え・絞り込みできる"]
        How3["How: クエリパラメータによるソート・フィルタAPIを作る"]
        WM3 --> What3
        WC3 --> How3
        What3 --> How3
    end

    What1 -.->|"動機の連鎖"| WM2
    How1 -.->|"制約の連鎖"| WC2
    What2 -.->|"動機の連鎖"| WM3
    How2 -.->|"制約の連鎖"| WC3

    style WM1 fill:#4a9e4a,color:#fff
    style WM2 fill:#4a9e4a,color:#fff
    style WM3 fill:#4a9e4a,color:#fff
    style WC1 fill:#8B4513,color:#fff
    style WC2 fill:#8B4513,color:#fff
    style WC3 fill:#8B4513,color:#fff
    style What1 fill:#3a7bd5,color:#fff
    style What2 fill:#3a7bd5,color:#fff
    style What3 fill:#3a7bd5,color:#fff
    style How1 fill:#e67e22,color:#fff
    style How2 fill:#e67e22,color:#fff
    style How3 fill:#e67e22,color:#fff

この連鎖は必要なだけ続く。そして、どの階層も同じ構造を持つ。第1階層を「要求」と呼ぼうが、第2階層を「仕様」と呼ぼうが、第3階層を「設計」と呼ぼうが、それは自由である。構造は同一だからだ。

Whyの書き方

Whyの書き方で注意すべき点がある。

動機は、親のWhatを深掘りしたときに出てくる「ユーザーや現実の前提」を書く。 親のHowの言い換えにしてはいけない。「TODOアプリとして成立させるために」ではなく「ユーザーは日常的にタスクが発生・完了・変更される」。前者は親のHowを繰り返しているだけだが、後者は親のWhat「記録・管理できるようにしたい」を深掘りしたときに出てくる現実の前提だ。

制約は、親のHowを選んだことで生まれる前提・条件を書く。 「TODOアプリ」というHowを選んだからWeb/モバイルが前提になる。「React + SQLite」を選んだからSQLのORDER BYが使える。制約は複数あっても1つのノードにまとめてよい。

第1階層の制約も存在する。 親ノードがないから空、ではない。ビジネスの制約、市場環境、リソースの制約など、みんな頭の中では持っているが明示していないだけだ。ここが崩れると木全体に影響する。

仮説検証サイクルとしてのノード

各ノードは「前提 → 仮説 → 検証 → 結果」の小さなサイクルと対応する。

つまり、各ノードは小さな仮説検証サイクルである

1対多対多の選択肢と部分木の切り替え

WhyとWhat、WhatとHowの関係は1対多である。つまり構造は Why 1 : What 多 : How 多 だ。

ここがSproutedの重要なポイントになる。Why、What、Howのいずれかが変わったら、その下の部分木を切り替えなければいけないかもしれない

まず、一つのWhyに対してWhatが複数あるケースを見てみよう。

graph TD
    W["🌱 Why(動機): タスクを忘れて困っている人がいる"]

    W --> WA["What①: タスクを記録・管理できるようにする"]
    W --> WB["What②: タスクの期限が来たら通知する"]
    W --> WC["What③: 日常行動から自動的にタスクを抽出する"]

    WA --> HA1["How: TODOアプリ"]
    WA --> HA2["How: 付箋アプリ"]
    WA --> HA3["How: LINEボット"]

    WB --> HB1["How: プッシュ通知"]
    WB --> HB2["How: メールリマインダー"]
    WB --> HB3["How: カレンダー連携"]

    WC --> HC1["How: AIによる自動抽出"]
    WC --> HC2["How: 音声メモの自動解析"]

    style W fill:#4a9e4a,color:#fff
    style WA fill:#3a7bd5,color:#fff
    style WB fill:#3a7bd5,color:#fff
    style WC fill:#3a7bd5,color:#fff
    style HA1 fill:#e67e22,color:#fff
    style HA2 fill:#e67e22,color:#fff
    style HA3 fill:#e67e22,color:#fff
    style HB1 fill:#e67e22,color:#fff
    style HB2 fill:#e67e22,color:#fff
    style HB3 fill:#e67e22,color:#fff
    style HC1 fill:#e67e22,color:#fff
    style HC2 fill:#e67e22,color:#fff

Whatが変わるとHowの選択肢がまるごと変わる。What①「記録・管理」を選んだ場合のHow群(TODOアプリ、付箋アプリ、LINEボット)と、What②「通知する」を選んだ場合のHow群(プッシュ通知、メールリマインダー、カレンダー連携)は、まったく別の選択肢になる。

実際の開発では、各階層で選択肢の中から一つを選ぶ。重要なのは、選ばれなかった選択肢とその理由も記録することだ。

どれかが変わったら、部分木を見直す

ここがSproutedの実践的なポイントだ。

Whyの動機が変わった場合。 もし「タスクを忘れて困っている人がいる」という動機自体が崩れたら(例:実はユーザーはタスクを忘れているのではなく、優先順位がつけられないだけだった)、その下のWhat・How・さらにその下の全階層を見直したほうがいいかもしれない。

Whyの制約が変わった場合。 「個人開発規模」という制約が「チーム開発」に変わったら、Howの選択肢やその先の設計が変わってくるかもしれない。

Whatが変わった場合。 Whyはそのままで、What①「記録・管理」からWhat②「通知する」に切り替わったら、Howの選択肢群も変わってくる。TODOアプリのために検討していた設計は関係が薄くなり、通知の設計が新たに必要になるかもしれない。

Howが変わった場合。 WhyもWhatもそのままで、How「TODOアプリ」からHow「LINEボット」に切り替わったら、次の階層の制約が変わり、それに伴って子ノードの検討も変わってくる。

graph TD
    subgraph "変更前"
        B_W["Why(動機): タスクを忘れて困っている"]
        B_W --> B_What["What: 記録・管理できるようにする"]
        B_What --> B_How["How: TODOアプリ ✅"]
        B_How --> B_C1["CRUD API設計"]
        B_How --> B_C2["React UI設計"]
        B_How --> B_C3["SQLiteスキーマ設計"]
    end

    subgraph "Howを切り替えた後"
        A_W["Why(動機): タスクを忘れて困っている"]
        A_W --> A_What["What: 記録・管理できるようにする"]
        A_What --> A_How["How: LINEボット ✅"]
        A_How --> A_C1["Messaging API連携"]
        A_How --> A_C2["リッチメニュー設計"]
        A_How --> A_C3["会話フロー設計"]
    end

    style B_W fill:#4a9e4a,color:#fff
    style B_What fill:#3a7bd5,color:#fff
    style B_How fill:#e67e22,color:#fff
    style B_C1 fill:#ddd,color:#333
    style B_C2 fill:#ddd,color:#333
    style B_C3 fill:#ddd,color:#333
    style A_W fill:#4a9e4a,color:#fff
    style A_What fill:#3a7bd5,color:#fff
    style A_How fill:#e67e22,color:#fff
    style A_C1 fill:#f9e79f,color:#333
    style A_C2 fill:#f9e79f,color:#333
    style A_C3 fill:#f9e79f,color:#333

つまり、Why / What / Howのどれかが変わったら、その下の部分木も見直す必要が出てくる可能性がある。上位のノードほど変わったときの影響が大きく、下位のノードほど影響が局所的になる。これが「すべては仮説であり、違いは変わりやすさのグラデーションだけ」という思想の具体的な表れだ。

現実にはサンクコストがある

ただし、理屈の上では「部分木を丸ごと切り替える」のが合理的でも、現実にはそう簡単にはいかない。すでに設計が進んでいたり、コードが書かれていたり、チームがその方向で動いていたりする。サンクコストは現実に存在する。

だからこそ、Sproutedで木構造を可視化しておくことに意味がある。切り替えるかどうかの判断をするとき、「今どこにいて、何が影響を受けるのか」が見えていれば、感情的な判断ではなく構造的な判断ができる。全部切り替えるのか、一部だけ再利用できるのか、影響範囲はどこまでか。それを見た上で「サンクコストを受け入れてでも切り替える」のか「このまま進む」のかを選べばいい。

Sproutedは「常に正しい選択をする」ためのフレームワークではない。正しい選択かどうかは事後にしかわからない。ただ、今どんな仮説の上に立っていて、何が変わったら何に影響するのかが見えていれば、最善を尽くすことはできる。Sproutedは、そのためのフレームワークだ。

Whyが複数になるケース

複数の親から同じHowに到達するケースがある。例えば「タスク忘れ防止」と「チーム進捗の可視化」という異なるWhyから、どちらも「TODOアプリ」というHowに到達するケースだ。これは木構造がDAG(有向非巡回グラフ)になることを意味する。

しかし、WhyやWhatが異なればHowの詳細も微妙に変わる。個人のタスク忘れ防止のためのTODOアプリと、チーム進捗可視化のためのTODOアプリでは、必要な機能が異なる。安易に共通化すると、どちらの目的にとっても中途半端なものが出来上がる。そしてWhyが違う以上、片方のWhyが変わったときの部分木の切り替えが、もう片方の木に意図しない影響を与えてしまう。

この問題については後のセクション「共通化の罠」で詳しく論じる。

すべては仮説である

確定物という幻想

従来の開発プロセスでは、「要求は確定、仕様は変わる」「仕様を固めればコードが安定する」といった前提が暗黙的に置かれてきた。SDDツールも同様に、仕様を「ソースオブトゥルース」つまり確定した真実として扱っている。

しかし、すべての階層は仮説である

「タスクを忘れて困っている人がいる」は仮説であり、本当にそうかはわからない。困っている人がいたとしても、「TODOアプリが最適な解決策である」というのも仮説だ。仕様もコードも、すべてはその仮説を前提とした「賭け」である。

仕様が「確定物」であるという前提が、SDDの硬直性を生んでいる。仕様が変わったとき、それは「仕様の管理が甘かった」のではなく、前提となっていた仮説が崩れたのだ。これは正常なプロセスであり、むしろ歓迎すべきことである。

変わりやすさのグラデーション

すべてが仮説だとしても、変わりやすさには差がある。

「要求は安定、コードは不安定」という従来の見方は、実はこの木構造の性質そのままである。ただし、従来は特定の階層を特別扱いしていた。Sproutedでは、どの階層も仮説として平等に扱い、違いは変わりやすさのグラデーションだけだと認識する。

確信度による管理

すべてが仮説なら、「どこまで信頼できるか」を管理する仕組みが必要になる。Sproutedでは、各ノードに確信度を持たせる。

確信度が上がる条件は明確に定義できる。

確信度が閾値を超えたノードは「ロック」を提案される。ロックされたノードを変更するには、影響範囲(部分木)が可視化され、変更のコストが明示される。

これにより、「すべてが仮説」という思想を保ちつつ、実務上の安定性も確保できる。仮説が崩れたときには、その部分木全体が再検討対象として自動的にフラグされる。

共通化の罠

WhyとWhatが違うのにHowが同じに見える問題

開発者は共通化したがるバイアスを持っている。似たような機能を見つけると、「これは一つにまとめられるのでは?」と考える。しかし、Howが同じに見えるだけで、WhyとWhatが異なるものを共通化すると、どちらの目的にとっても中途半端になる

しかも、共通化した後に片方のWhyが強くなると、もう片方の目的が犠牲になりやすい。

典型的な失敗パターン

多機能化による迷走。 あるメモアプリが「メモ」「タスク管理」「ドキュメント管理」を一つのアプリに詰め込んだとする。Sproutedで構造化すれば、これは3つの異なるWhyから生まれた異なる木であることが明確になる。

これが可視化されていれば、「これは3つの別の木であり、本当に一つのアプリにすべきか?」という問いが立てられたはずだ。

同一目的の乱立。 逆のパターンもある。ある企業がメッセージングアプリを5つも6つも作ってしまったとする。同じWhy「離れた人とコミュニケーションしたい」から出発しているのに、部署ごとに別の木を作ってしまった。一つの木として管理していれば、Whatレベルで「チャットとビデオ通話は分けるべき」「業務用と個人用は統合すべき」という判断が構造的にできたはずだ。

適切な分離の成功例。 一方で、プロジェクト管理ツール群を提供するある企業は、共通のWhy「チームで成果を出したい」に対して、Whatが明確に異なるツール群(課題追跡ツール / ナレッジベース / 軽量タスクボード)を分離して提供している。Whyは共通だがWhatが異なるから、Howを分離する判断が正しかったのだ。

共通化の判断基準

Sproutedでは、共通化すべきかどうかの判断基準が構造的に定まる。

共通化する場合も、Howをさらに細かく分解すれば、本当に共通な部分と各Whyに固有の部分が分離できる。共通化の粒度が粗すぎることが多くの問題の原因であり、細かくすれば共存できる部分が見つかる。

使いまわしてよいケース

逆に、異なる場所に似たノードが出現したとき、Why / What / Howのすべてが完全に一致しているなら、それは同じものであり使いまわしてよい

判断基準はシンプルだ。

一つでもNoなら、たとえ似ていても別ノードとして管理したほうがいい。どれかが変わったときに片方だけ切り替えたいのに、共通化していると巻き添えになるからだ。

既存SDDツールとの比較

現在のSDDツールの構造

2025年現在の主要なSDDツールは、いずれも線形的なパイプラインを採用している。典型的なワークフローは以下のような形だ。

いずれも「仕様を書き、それに基づいてAIがコードを生成する」という基本構造を持つ。要件を構造化し、不変の原則を定義し、仕様を永続的なアーティファクトとして維持する、というアプローチだ。

SDDツールが抱える構造的問題

これらのツールには、いくつかの構造的な限界がある。

第一に、仕様を「確定物」として扱っている。 仕様をソースオブトゥルースと位置づけ、要件→設計→タスクを線形に進める。しかし前述の通り、要求も仕様もすべて仮説であり、確信度のグラデーションがあるだけだ。仕様を確定物として扱うから、変更が起きたとき「仕様と実装の乖離」が問題になる。最初から仮説として扱っていれば、変更は「仮説の更新」として自然に処理できる。

第二に、Whyが構造に組み込まれていない。 ユーザーストーリーを生成するツールもあるが、それが上位のWhyとどう繋がるかは管理外だ。不変の原則を定義する概念も、仮説として検証される対象ではない。「なぜこの仕様が存在するのか」が構造的に追えないため、仕様の妥当性を評価する根拠が失われやすい。

第三に、変更の伝播が構造的に解けていない。 仕様が変わったとき、どの設計やコードに影響するかを人が追いかけている状態だ。古くなった仕様がAIエージェントを誤導し、現実と合わない実装を生成してしまうリスクがある。

第四に、粒度の柔軟性がない。 小さなバグ修正でも大きな機能開発と同じ重さのプロセスが適用されてしまう。問題のサイズに応じてプロセスの深さを変える仕組みが弱い。

Sproutedが埋めるギャップ

Sproutedは、これらの問題に対して構造的な解を提供する。

SDDの問題Sproutedのアプローチ
仕様が確定物として扱われるすべてのノードが仮説。確信度によるグラデーション管理
Whyが構造に組み込まれていない各ノードがWhy(動機+制約)/What/Howを持ち、Whyが起点
変更の伝播が手動木構造により影響範囲が部分木として自動的に特定される
粒度の柔軟性がない木の深さで粒度が自然に決まる。深く掘るか浅く留めるかは自由
共通化の判断基準がないWhy/Whatの一致度で共通化すべきか構造的に判断

重要なのは、SproutedはSDDを否定しないということだ。SDDツールは「仕様→コード生成」という葉ノードレベルの変換に優れている。Sproutedは、その上位にある「なぜその仕様を書くのか」「その仕様は本当に正しいのか」「仕様が変わったらどこに影響するのか」を構造的に管理する。

Sproutedの木構造の葉ノードが十分に具体的なHowになったとき、それは既存のSDDツールが受け取る「仕様」と同等のものになる。つまり、Sproutedは既存のSDDツールを置き換えるのではなく、その上に乗るメタフレームワークである。

関連する既存アプローチとの関係

Sproutedの思想は、ソフトウェア工学の複数の分野と接点を持つ。ここでは特に関連の深い3つのアプローチ — Goal-Oriented Requirements Engineering(GORE)、Hypothesis-Driven Development(HDD)、Design Rationale(DR) — との関係を整理する。

結論を先に述べると、SproutedはGOREの構造性とHDDの仮説管理を組み合わせ、DRが50年間解けなかった実用化の壁をLLMで乗り越えようとするものとして位置づけられる。

Goal-Oriented Requirements Engineering(GORE)

GOREとは何か

Goal-Oriented Requirements Engineering(GORE)は、要求工学の分野で20年以上にわたって研究されてきたアプローチであり、ゴール(目標)を起点として要求を引き出し、モデル化し、分析する手法群の総称である。代表的なフレームワークとしてKAOS(Keep All Objectives Satisfied)とi*(iStar)がある。

KAOSでは、最上位のゴールをAND/OR分解で段階的に具体化し、最終的にエージェント(人間やソフトウェア)に割り当て可能なレベルまで落とし込む。各ゴールは時相論理(LTL)で形式的に定義でき、ゴール達成を妨げる障害(Obstacle)の分析も体系的に行われる。i*は、組織内のアクター間の依存関係(誰が誰に何を依存しているか)をモデル化し、「なぜ(Why)」「誰が(Who)」「どうやって(How)」の次元を扱う。

Sproutedの再帰的な木構造、WHY/HOWによる分解、代替案の明示的管理は、GOREの基本的な発想と表面的に類似している。しかし、両者は根底にある認識論が異なり、対象とするレイヤーも異なる。

認識論の違い:ゴールは「正しいもの」か「仮説」か

GOREは「ゴールはステークホルダーから引き出された正しいものであり、それを漏れなく形式的に分解するのが仕事」という立場に立つ。ゴール自体が間違っている可能性を構造的に管理する仕組みはない。

Sproutedは「すべてのノードは仮説であり、確信度のグラデーションの中にある」という立場に立つ。最上位のWhyですら検証されるまでは賭けであり、崩れたときには部分木全体を見直す。

この違いは変換を試みると明確になる。KAOSでTODOアプリをモデル化すると「タスクが適切に管理される」というゴールが起点になる。これをSproutedに持ち込もうとすると、Whyが書けない。KAOSではゴール自体が起点だが、Sproutedでは「タスクを忘れて困っている人がいる」というWhyが起点であり、ゴールに相当するWhatはそこから導出されるものだからだ。

逆方向も同様で、SproutedのノードをKAOSに変換すると、確信度と仮説管理、動機と制約の2本線接続が消失する。KAOSにはゴールが「間違っているかもしれない」という概念がないため、Sproutedの核である仮説管理の構造が行き場を失う。

つまり、両者の間にきれいな双方向変換は成立しない。

レイヤーの違い:木の中の整合性 vs. 木自体の妥当性

認識論の違いは、対象とするレイヤーの違いでもある。

KAOSの形式検証は、ゴールを時相論理で定義し、システムの状態遷移モデルを記述した上で、モデルチェッカーが全経路を探索して「このゴールに到達できない経路があります」と報告する仕組みである。これは強力だが、検証できるのは「定義済みの状態空間の中の抜け漏れ」だけであり、状態変数や操作の列挙自体は人間が行う。モデルに入れ忘れた世界の抜け漏れは原理的に検出できない。

Sproutedは、そもそも「木自体が間違っている可能性」を前提にしている。KAOSが「TODOアプリでタスクを管理する」というゴール木の中の整合性を完璧にしたとしても、ユーザーの本当の課題が「忘れること」ではなく「優先順位がつけられないこと」だったなら、その木全体が無意味になる。Sproutedはこの「木自体を取り替える判断」を支援する。

つまり、GOREは木の中の整合性を検証し、Sproutedは木自体の妥当性を問う。両者は対立ではなく、レイヤーが異なる。

GOREの知見の取り込み

GOREが持つ強みのうち、Sproutedの思想と自然に接続するものはルールとして取り込んだ。

障害(Obstacle)分析 → SHOULDルールとして取り込んだ。 KAOSには、ゴール達成を妨げる障害を体系的に洗い出す仕組みがある。Sproutedの「すべては仮説」という思想と自然に接続するため、「重要なノードには、仮説を崩しうるリスクを記述する」というルールを追加した(付録「仮説管理に関するルール」を参照)。

AND/OR分解の区別 → SHOULDルールとして取り込んだ。 KAOSではサブゴール群が「すべて必要(AND)」か「代替手段(OR)」かを明示的に区別する。変更影響分析のときに「What②を諦めても上位のWhyは達成できるか?」の判断に関わるため、What群のAND/OR関係を明記するルールを追加した(付録「選択肢と意思決定に関するルール」を参照)。

非機能要求 → 既存構造で対応可能であることを明記した。 GOREにはソフトゴール(完全には満たせないが十分なレベルで満足させるべき要求)という概念がある。Sproutedでは非機能要求もWhy/What/Howで記述でき、達成条件が曖昧な場合は確信度を低めに設定すればよい(付録「仮説管理に関するルール」を参照)。

一方、以下はスコープ外とした。

形式的検証。 KAOSの形式検証は、定義済みの状態空間の中を完全に探索するという強みがある。しかし、状態遷移モデルの記述コストが高く、かつモデル自体の妥当性は人間の判断に依存する。Sproutedは自然言語主義とLLMとの親和性を設計方針としており、形式検証とはトレードオフの関係にある。ただし、将来的にLLMが自然言語から状態遷移モデルを自動生成できるようになれば、確信度の高いノードに対して部分的に形式検証を適用する統合の余地がある(「展望」セクションを参照)。

アクター/エージェントのモデリング。 i*は「誰が誰に依存しているか」を明示的にモデル化する。重要な観点だが、Why/What/Howの3属性にWhoを足すとノードの認知コストが上がり、「実務者の認知的コストを下げる」という設計方針と矛盾する。将来的な拡張の余地として残す。

Hypothesis-Driven Development(HDD)

HDDとは何か

Hypothesis-Driven Development(HDD)は、Lean Startup の思想をソフトウェア開発プロセスに直接適用するアプローチである。「要求(requirements)」を「仮説(hypotheses)」に置き換え、新しい機能やサービスの開発を「一連の実験」として捉える。

典型的なHDDのプロセスは以下の通りだ。

  1. 仮定(Assumption)を書き出す
  2. 仮説(Hypothesis)に変換する。テンプレートとしてよく使われるのは: 「We believe that [機能X] will result in [成果Y]. We will know we have succeeded when [指標Z]
  3. 実験を設計する(A/Bテスト、プロトタイプ、ユーザーインタビュー等)
  4. 実験を実行し、結果を分析する
  5. 仮説を支持(persevere)するか反証(pivot)するかを判断する
  6. 次の仮説へ

例えば「ホテル画像を大きくすれば予約率が上がる」という仮説を立て、A/Bテストで検証し、48時間以内に予約率が5%上昇するかどうかを測定する、といった形で運用される。

学術的には「Hypotheses Engineering」という概念も提唱されており、要求工学が要求を扱うのと同様に、仮説を引き出し、文書化し、分析し、優先順位付けする必要があると主張されている。ここでは「仮定(assumption)」は暗黙的に真実として受け入れられた理解、「仮説(hypothesis)」は検証可能な明示的な記述と定義されている。

Sproutedとの共通点

HDDとSproutedは、認識論のレベルで最も近い既存アプローチである。

「すべては仮説」という認識論。 HDDも「私たちはもうプロジェクトをやらない。実験だけだ」と言い切っている。Sproutedの「すべてのノードは仮説」と同じ立場だ。

仮説検証サイクル。 HDDの「仮説→実験→結果→ピボット or 続行」は、Sproutedの「Why→What→How→結果」の仮説検証サイクルとほぼ対応する。

要求の否定。 HDDは「要求を仮説に置き換えるべき」と主張し、Sproutedは「仕様は仮説である」と主張する。方向性は同じだ。

決定的な違い:構造の有無

共通の認識論を持ちながら、HDDとSproutedには決定的な違いがある。

第一に、HDDの仮説には階層構造がない。 HDDの仮説は基本的にフラットなリストとして管理される。「ホテル画像を大きくする」「ボタンの色を変える」「料金表示を変える」が並列に並ぶ。仮説間の親子関係がないため、ある仮説が崩れたときに他のどの仮説に影響するかという構造的な分析ができない。

Sproutedは仮説を木構造で管理する。「ユーザーはタスクを忘れて困っている」が崩れたら、その下の「TODOアプリ」「React+SQLite」「ソートAPI」が全部影響を受けるということが構造的に見える。

第二に、Why/What/Howの分離がない。 HDDの仮説テンプレート「We believe that [X] will result in [Y]」は、手段(X)と成果(Y)が一文に混在している。SproutedのようにWhyの動機と制約、What、Howを分離し、動機の連鎖と制約の連鎖を追跡する仕組みがない。

第三に、変更伝播の概念がない。 HDDでは仮説が反証されたら「ピボットする」というが、何がどこまで影響するかの分析は人間の頭の中で行われる。Sproutedは部分木として影響範囲が自動的に特定される。

第四に、適用範囲が異なる。 HDDはプロダクトの成果指標(コンバージョン率、DAUなど)に対する仮説検証に特化している。A/Bテストやfeature flagsとの統合が前提であり、本番環境でのデータ収集を重視する。Sproutedはそれより上流の「そもそも何を作るべきか」「なぜ作るのか」「その仕様は本当に正しいのか」の構造化にフォーカスしている。

SproutedはHDDの構造化版として位置づけられる

まとめると、HDDは「仮説として扱う」という認識論は共有しているが、仮説の構造化と変更影響分析を持たない。Sproutedの独自の貢献は、HDDの仮説管理にGOREの構造性を組み合わせたところにある。

HDDが日常的な機能レベルの仮説検証(「この機能は使われるか?」)を担い、Sproutedがその上位にある構造的な仮説管理(「そもそもなぜこの機能が必要で、何が変わったら何に影響するのか」)を担う、という役割分担も考えられる。

Design Rationale(DR)

DRとは何か

Design Rationale(設計根拠)は、設計の過程でなされた意思決定の理由を明示的に記録・管理するアプローチであり、1970年にW.R. KunzとHorst Rittelが開発したIBIS(Issue-Based Information System)を起源とする。以降、PHI(Procedural Hierarchy of Issues)、QOC(Questions, Options, and Criteria)、DRL(Decision Representation Language)など複数の変種が提案されてきた。

DRの基本構造は、Sproutedと驚くほど近い。

IBISは、Issue(問題)→ Position(立場・選択肢)→ Argument(論拠)という構造で意思決定を記録する。あるIssueに対して複数のPositionが提示され、各Positionに対してそれを支持するArgumentと反対するArgumentが紐づく。

QOCは、Question(問い)→ Option(選択肢)→ Criteria(基準)という構造で設計空間を分析する。あるQuestionに対して複数のOptionが並び、各Optionが各Criteriaを満たすかどうかが評価される。

DGAは、Decision(決定)→ Goal(目標)→ Alternatives(代替案)という構造で、決定の根拠を記録する。

これらをSproutedと対比すると、構造的な対応関係が見える。

Design RationaleSprouted
Question / Issue / DecisionWhat(達成したいこと)に近い
Option / Position / AlternativeHow(手段の候補群)に近い
Criteria / Argument / GoalWhy(動機と制約)に近い
選ばれなかった選択肢の記録選ばれなかったHowとその理由の記録

Sproutedとの共通点

構造の類似性に加え、思想レベルでも共通点がある。

意思決定の理由の明示。 DRの核心は「なぜこの設計にしたのか」を記録することであり、Sproutedの「Whyが起点」という思想と一致する。

代替案の記録。 DRは「選ばれなかった選択肢とその理由」の記録を重視する。Sproutedの「選ばれなかった候補とその理由を記録する」ルールは、DRの知見と直接対応する。

階層的な分解。 PHI(Procedural Hierarchy of Issues)やIBISの拡張版では、Issueが階層的に分解される。これはSproutedの再帰的な木構造と対応する。

決定的な違い

第一に、DRには仮説管理がない。 DRは「なされた決定の根拠を記録する」アプローチであり、その決定自体が間違っている可能性を構造的に管理する仕組みはない。確信度の概念もなく、「この決定は仮説であり、検証されるまでは賭けである」という認識論がない。

第二に、変更伝播の構造がない。 DRは個々の意思決定の根拠を記録するが、ある決定が変わったときに他のどの決定に影響するかを木構造として追跡する仕組みが弱い。QOCのQuestionは独立して存在し、Question間の親子関係やSproutedの「動機の連鎖」「制約の連鎖」に相当する接続構造がない。

第三に、DRは事後的記録の性格が強い。 QOCの原論文自身が「設計空間分析は設計プロセスの記録ではなく、設計と並行して構築される副産物である」と述べているが、実際には多くの場合、設計が終わった後に根拠を書き起こすという運用になりがちである。Sproutedは設計の「前」に木を構築し、木に基づいて設計を進めるという順序を想定している。

DRはなぜ50年間広まらなかったのか

Design Rationaleの歴史は、Sproutedにとって最も重要な教訓を含んでいる。構造がSproutedに近い(Why/What/Howの分離 ≈ Question/Option/Criteria)にもかかわらず、50年間にわたって実務での普及に失敗してきたからだ。

その原因は明確に分析されている。

記録コストが高い。 IBISもQOCも、設計者が意思決定のたびに手動でIssue→Position→ArgumentやQuestion→Option→Criteriaを記録しなければならない。設計のスピードと根拠記録のコストが釣り合わない。

設計思考を制約する。 議論的な視点が設計思考に構造を強制し、それが設計者にとって煩わしいと受け止められてきた。設計者は自由に発想したいのに、「まずIssueを定義して、Positionを列挙して…」というプロセスが創造性を阻害すると感じる。

ツールが開発環境から分離されている。 専用ツール(gIBIS、QuestMap、Compendiumなど)が必要で、日常の開発ワークフローに統合されていない。

読む人がいない。 苦労して書いた根拠を、実際に後から参照する場面が限られている。新しいメンバーの参入時や大規模リファクのときくらいしか使われず、記録コストに見合わない。

SproutedとLLMがDRの課題を解く可能性

DRの失敗原因は、すべて「人間が手動で構造化する」ことに起因している。そしてこれは、Sproutedの「展望:LLMとの親和性」セクションで述べた内容と直結する。

記録コスト → LLMが自然言語から構造を自動抽出する。設計者は自然言語で考えを書くだけで、Why/What/Howへの分類はLLMが行う。

設計思考の制約 → 自然言語で自由に書いてからLLMが後から構造化を提案する。構造化は設計と同時ではなく、設計の直後に行われるため、創造性を阻害しない。

ツール統合 → LLMが既存の開発環境やチャットツールの中で動く。専用ツールへの切り替えが不要になる。

つまり、Design Rationaleが50年間解けなかった「構造化のコスト」問題を、LLMが解く可能性がある。Sproutedが「LLMの登場によって初めて実用的になるフレームワーク」であるという主張は、DRの歴史によって裏付けられる。

Sproutedの位置づけ

3つの既存アプローチとの関係を整理すると、Sproutedが埋めている位置が見えてくる。

GOREから借りたもの:構造性。 ゴールの木構造分解、AND/OR分解、障害分析。ただし認識論は異なる。

HDDと共有しているもの:認識論。 「すべては仮説」「要求ではなく仮説」という立場。ただしHDDには構造がない。

DRと共有しているもの:意思決定の構造。 Why/What/Howの分離 ≈ Question/Option/Criteria。ただしDRには仮説管理がなく、実用化に失敗した。

Sproutedは、GOREの構造性 × HDDの仮説管理 × DRの意思決定記録を統合し、LLMによってDRが50年間解けなかった実用化の壁を乗り越えようとするものとして位置づけられる。

展望:LLMとの親和性

Sproutedは、LLMの登場によって初めて実用的になるフレームワークでもある。

構造化支援

ユーザーが自然言語でノードを記述すれば、LLMが「これはWhat寄りの記述ですね」「Whyの動機が曖昧です。もう少し具体的にすると、子ノードの選択が楽になります」といった構造化の支援を行える。論理の飛躍(WhyからいきなりHowに飛んでWhatが抜ける)や、一つのノードにWhy/What/Howが混ざって書かれているケースも、LLMが検出して分離を提案できる。

これにより、従来は「この抽象化を自分でできる人」だけが使えるフレームワークだったものが、より多くの開発者に開かれる。

曖昧さの検出と確信度の更新

自然言語で書かれたノードには曖昧さが残る。LLMは「このWhatは複数の解釈が可能です」と曖昧さを検出し、確信度の評価に反映できる。

また、Why(動機・制約)/What/Howが分離されていることで、曖昧さのスコープが狭まる。一文にすべてを詰め込むのと、属性ごとに分けて書くのとでは、曖昧さのポイントが特定しやすい。

変更影響分析

親ノードの仮説が崩れたとき、その子孫ノードへの影響をLLMが自然言語レベルで推定できる。「この要求が変わったら、この仕様と矛盾しますよ」「この部分木は再検討が必要です」という警告を自動的に生成できる。

重複検出と共通化判断

異なる枝に似たノードが出現したとき、LLMが「この2つのノード、Why/What/Howがすべて一致しています。共通化しますか?」と提案できる。逆に「Howは同じですがWhyが違います。本当に共通化しますか?」と警告もできる。

確信度に連動した形式検証の統合

GOREの分野では、ゴールを時相論理で定義し、システムの状態遷移モデルを記述した上で、モデルチェッカーが全経路を探索して抜け漏れを検出する手法が確立されている。この手法の最大のコストは、状態変数と操作の列挙を人間が行う部分にあった。

LLMがSproutedの自然言語ノードから状態遷移モデルを自動生成できるようになれば、確信度の仕組みと連動した部分的な形式検証が可能になる。

具体的には、確信度が高くロック候補となったノードに対して、LLMがWhy/What/Howの記述から状態変数と操作を抽出し、モデルチェッカーに渡す。モデルチェッカーが「この経路ではWhatに到達できません」と報告し、人間がその結果を受けてHowを修正するか、リスクとして受容するかを判断する。

確信度が低いうちにこの検証をかける意味はない(どうせ変わるから)。確信度が上がり「ロックしていいか?」という判断のときに、ロック前の最終チェックとして形式検証をかける。これにより、Sproutedの仮説管理の思想を保ちつつ、固まった部分については形式的な保証を得られる。

ただし、形式検証が保証するのはあくまで「定義済みの状態空間の中の完全性」であり、モデルに含まれていない世界の抜け漏れは検出できない。Sproutedの「すべては仮説」という立場はこの限界を前提としており、形式検証は仮説管理を置き換えるものではなく、補強するものとして位置づけられる。

既存SDDツールとの接続

Sproutedの葉ノードが十分具体的になったら、そのまま既存のSDDツールやAIコーディングエージェントに渡せる。「分解不要なレベルまで来たか」の判定もLLMが支援できる。

Sproutedはツールチェーンの最上位に位置し、「なぜ作るのか」から「具体的に何を作るか」までを仮説木として管理する。そして、「どうコードにするか」は既存のSDDツールに委譲する。

おわりに

Sproutedの本質は、ソフトウェア開発におけるすべての意思決定を「仮説の木」として管理するという思想にある。

要求も仕様も設計もコードも、すべて仮説である。違うのは、抽象度と変わりやすさのグラデーションだけだ。この認識に立てば、特定の階層を特別扱いする必要はなく、すべての階層に同じ操作(分解、トレース、変更影響分析、仮説検証)を適用できる。

Sproutedというフレームワーク名は、「Whyという種から仮説が芽吹き(sprout)、木として育っていく」という開発プロセスのメタファーから来ている。種が良ければ木は健全に育つし、種(Why)が間違っていればどんなに丁寧に仕様を書いても意味がない。

SDDツールは「仕様→コード」の変換を効率化した。Sproutedは、その仕様がなぜ存在するのか本当に正しいのか変わったときに何が影響するのかを構造的に管理する。両者は対立するものではなく、組み合わせることでより堅牢な開発プロセスを実現できる。

すべての開発は、一粒の種 — 「なぜ」 — から始まる。


付録:Sproutedのルールとチェックリスト

本フレームワークのルールは、RFC 2119に倣い以下の3段階で定義する。

ノード構造に関するルール

MUST: 各ノードはWhy / What / Howを持つ。 これがSproutedの最小単位である。どれか一つでも欠けているノードは不完全であり、判断の根拠や手段が追えなくなる。

MUST: Whatは親のWhyの動機から導出する。 動機のないWhatは「なぜそれが必要か」が説明できない。「何を作るか」の前に「なぜ必要か」がなければならない。

SHOULD: Whyには動機と制約の両方を書く。 動機(親のWhatから来る)と制約(親のHowから来る)を意識して分けると、Whyの質が上がり、WhatとHowの選択がぶれにくくなる。ただし、厳密に分けて書くことは必須ではない。

SHOULD: Whyの動機を親のHowの言い換えにしない。 「TODOアプリとして成立させるために」ではなく「ユーザーは日常的にタスクが発生・完了・変更される」。親のHowの言い換えは情報量がなく、Whatの導出に使えない。

SHOULD: 第1階層のWhyにも制約を明記する。 ビジネスの制約、市場環境、リソースの制約など。明示されていない前提は、崩れたときに認識すらできない。

MAY: Why / What / Howの記述フォーマットを統一する。 自然言語で自由に書いてよいが、チームで使う場合は書き方のテンプレートを決めると曖昧さが減る。

階層と分解に関するルール

MUST: 親のWhatが子のWhyの動機を生み、親のHowが子のWhyの制約を生む。 これがSproutedの再帰構造の根幹である。この接続が切れると、階層間のトレーサビリティが失われる。

SHOULD: 一つのノードに複数の関心事を詰め込まない。 Whyが異なるものは別のノードに分ける。例えば「素早くメモできる」と「メモを検索・整理できる」は異なるWhyから来る別の木であり、同じノードにまとめるべきではない。

SHOULD: 分解の深さは問題のサイズに合わせる。 小さなバグ修正に3階層も4階層も掘る必要はない。逆に、大きな機能開発を1階層で終わらせると検討漏れが起きやすい。

MAY: 葉ノードが十分具体的になったら既存のSDDツールやコーディングエージェントに委譲する。 Sproutedは「なぜ作るか」「何を作るか」を管理し、「どうコードにするか」は既存ツールに任せてよい。

選択肢と意思決定に関するルール

MUST: Whatに対して複数のHowの候補を検討する。 最初に思いついた手段にそのまま飛びつくのではなく、選択肢を並べた上で選ぶ。1つしか候補がない場合でも、「他にないか」を一度は考える。

SHOULD: 選ばれなかった選択肢とその理由を記録する。 後から前提が変わったときに再検討が容易になる。理由がなければ、なぜその手段を選んだのかが追えない。

SHOULD: What群が並列するとき、すべて必要(AND)か選択肢(OR)かを明記する。 AND関係にあるWhat群の一つを落とすと上位のWhyが達成できなくなるが、OR関係なら代替が効く。変更影響分析のときにこの区別がないと「このWhatを諦めても大丈夫か?」の判断がしにくい。

MAY: Whatの候補も複数列挙してから選ぶ。 Howだけでなく、Whatレベルでも「他の切り口はないか」を考えると、より本質的な解決策が見つかることがある。

仮説管理に関するルール

MUST: すべてのノードを仮説として扱う。 確定した事実はない。要求も仕様もコードも、すべて確信度のグラデーションの中にある。

SHOULD: 各ノードに確信度を持たせる。 「どのくらい確からしいか」を明示しておくと、変更の判断が容易になる。確信度が高いノードはロックを検討し、低いノードは積極的に検証する。

SHOULD: 上位ノードが変わったとき、影響を受ける部分木を確認する。 自動的に確認できる仕組みがあるのが理想だが、手動でも「親が変わったから子も見直す」という習慣を持つだけで品質が上がる。

SHOULD: 重要なノードには、仮説を崩しうるリスクを記述する。 「何がこの仮説を覆しうるか」を事前に考えておくと、仮説が崩れたときの対応が速くなる。すべてのノードに書く必要はないが、確信度が低いノードや影響範囲が大きいノードでは特に有効である。

MAY: 仮説検証の結果をノードに記録する。 「検証済み」「未検証」「反証された」などの状態を持たせると、木全体の健全性が可視化される。

MAY: 非機能要求もWhy / What / Howで記述する。 パフォーマンス、セキュリティ等の非機能要求も同じ構造で扱える(例:Why「ユーザーが遅いと離脱する」→ What「レスポンスが速い」→ How「200ms以内を目標にキャッシュ導入」)。達成条件が明確でない場合は確信度を低めに設定する。

共通化に関するルール

MUST: Why / What / Howのすべてが一致している場合のみ使いまわしてよい。 一つでも異なるなら別ノードとして管理する。

MUST: Whyが異なるものを共通化しない。 Howが同じに見えても、Whyが違えば別の木である。共通化すると、片方のWhyが変わったときにもう片方が巻き添えになる。

SHOULD: 共通化したくなったら、まずWhy / What / Howの一致度を確認する。 「似ている」と「同じ」は違う。共通化の前に構造を確認する習慣を持つ。

MAY: 共通化できない場合でも、Howをさらに細かく分解して部分的に共通化する。 粒度を細かくすれば、本当に共通な部分と固有の部分が分離できることがある。

チェックリスト:ノードを作るとき

新しいノードを作る際に確認すべき項目を以下にまとめる。

  1. Whyが書かれているか? 動機がないノードは存在意義が不明
  2. Whyの動機は親のHowの言い換えではなく、親のWhatから導出されているか?
  3. Whyの制約は明記されているか? 特に第1階層で忘れがち
  4. Whatは動機から自然に導かれているか? 飛躍がないか
  5. Whatが複数あるとき、AND(すべて必要)かOR(選択肢)か明記したか?
  6. Howの候補は複数検討されたか? 最低2つは考えたか
  7. 選ばなかった候補とその理由は記録されているか?
  8. ノードに複数のWhyが混ざっていないか? 混ざっていたら分割する
  9. 確信度は? 検証済みか、未検証の仮説か
  10. 重要なノードなら、仮説を崩しうるリスクを書いたか?

チェックリスト:ノードを変更するとき

既存のノードを変更する際に確認すべき項目を以下にまとめる。

  1. 何が変わったのか? Why(動機/制約)/ What / How のどれか
  2. 子ノードへの影響は確認したか? 動機が変わればWhatが、制約が変わればHowが影響を受ける
  3. 部分木全体を見直す必要があるか、一部で済むか?
  4. サンクコストを踏まえた上で、切り替えるかどうかの判断をしたか?
  5. 共通化しているノードがある場合、他の利用箇所への影響は?
  6. 変更の理由は記録したか? 後から「なぜ変えたのか」を追えるように
Top