「音符をクリックしてドレミで遊べるWebアプリを作りたい」
この一文から始まった開発が、1日で「大譜表・音価・タイ・拍子切替・JSON保存・G線上のアリア全曲(両手)」を持つミニ楽譜エディタになった。要求を出したのも実装を止められなかったのも、全部自分である。
前半はその実録。後半は、この小さな実験が図らずも純粋培養してしまった「スコープクリープ」という現象を、受託開発の現場とAI時代の文脈で考える。
エスカレーションの全記録
コミット履歴から再構成すると、要求はこう育った。
| 段階 | 要求 | 一言 |
|---|---|---|
| v1 | 16マスの五線譜。クリックでドレミが鳴る | ここでは「おもちゃ」だった |
| v2 | プリセットをきらきら星→G線上のアリアに | 「ワンフレーズだけ」のはずだった |
| v3 | 32マス→8ページ制でアリア全曲 | もう「おもちゃ」ではない |
| v4 | 全音符〜16分音符・タイ・4/4拍子とアクセント | 音価パレットが生えた |
| v5 | 拍子記号の表示と4/4・3/4・2/4・6/8切替 | 楽譜エディタの顔になる |
| v6 | ヘ音記号の伴奏段(大譜表) | 「下の音も入れたい」 |
| v7 | 伴奏ベースを全曲ぶん | 和声から機械構成 |
| 最終 | 原曲MIDIから両パートを機械再採譜 | リズムのズレを根治 |
どの一歩も、その時点では完全に合理的だった。それが恐ろしい。
なぜ音楽は止まらないのか
作りながら気づいた構造が3つある。
1. 楽譜は1000年かけて完成した「切り取れない全体」である。
音の高さを入れれば長さが欲しくなる。長さを入れれば拍子が要る。拍子を入れれば強拍が、強拍を入れれば弱起が、そして休符・付点・3連符・調号・強弱……。楽譜の記法は相互に依存した閉じた体系で、どこで切っても「未完成」に見える。TODOアプリなら「期限なし版」でも完成に見えるが、楽譜の部分実装は誰の目にも欠けて見える。ドメインモデルが強固すぎる領域では、部分こそが不自然なのだ。
2. 検証対象(名曲)がドメインの全機能を要求してくる。
動作確認に「本物の曲」を使った瞬間、その曲が仕様書になる。G線上のアリアは、長い保持音(タイ)、16分の駆け下がり(音価)、ゆったりした4/4(拍子)、そしてあの歩くベース(大譜表)を全部持っている。テストデータに名曲を選ぶことは、事実上、要件定義書に名曲を採用することである。
3. AI開発は「ついで」の限界費用をゼロに見せる。
発注者と実装者が同一人物で、しかも実装がAIで数分なら、スコープを止める人間がどこにもいない。「拍子も変えられるようにするか」の実装コストが1時間なら踏みとどまれたかもしれない。数分だから頼んでしまう。要求のエスカレーションは意志の弱さではなく、実装速度の関数だった。
途中で起きた事故と謎解き
ただ膨らんだだけでなく、開発としての読みどころもあった。3つ記録する。
手書き配列は嘘をつく。 アリアの音列をコードに埋め込む際、最初は会話の流れで配列を「手で」書いた。検証でパース結果と機械照合したら不一致。以後、採譜データはすべてスクリプトが生成しHTMLへ機械的に差し替える方式に変えた。AIも人間と同じで、200個の数値を手書きしたら間違える。照合を仕組みにするしかない。
協和チェックが名曲を壊した。 自作の簡易ベースに「強拍でメロディと不協和なら直す」という自動修正を入れたら、冒頭の象徴的な下降「ド→シ→ラ→ソ」のシが消えた。4度を不協和扱いする過剰に厳格な理論が、原曲の響きそのものを「バグ」と判定したのだ。基準を本当の衝突(2度・7度)だけに緩めて解決した。理論の過剰適用は、正しさの顔をして音楽を殺す。
リズムのズレの犯人は採譜のドリフトだった。 「上と下のリズムが揃っていない気がする」という違和感の正体は、ドレミ譜から復元したメロディが合計23.56小節と半端で、小節グリッドに対して徐々に流れていたこと。ベースは16セルきっちりのグリッド張り付きなので、進むほどすれ違う。根治策はMutopia Project(パブリックドメイン)の原曲MIDIからの機械再採譜だった。ニ長調を全音下げるとハ長調=ほぼ白鍵に落ち、量子化したら24.0小節ぴったりに整列した。数ターン悩んだ協和アルゴリズムより、正しいデータソースを1つ見つけるほうが強かった。
現代のスコープクリープの闇
ここからが本題の後半である。この1日で観測した現象は、業界が何十年も苦しんできた病気の、実験室バージョンだった。
受託の「ついで」は善意から始まる。 私は受託開発の現場を長く見てきたが、プロジェクトを溶かすのは悪意の仕様変更ではない。「ここまで作ったなら、これも入りますよね?」という善意と期待の積み重ねである。一つひとつは正論で、断る理由が見つからない。音楽アプリで言えば「拍子があるなら弱起も」は完全に正論だ。正論の連鎖は、固定価格と固定納期の上で複利で効いてくる。要件定義の漏れを「ついで」で埋め続けた現場が、スケジュールの溶けた鍋になるのを何度も見た。
「アジャイルだから」は免罪符になった。 変化への適応を説いたはずのアジャイルは、現場によっては「要件は決めなくていい」「あとから何でも足せる」の言い訳として消費されている。スプリントは要求の受け皿として無限に開き、バックログは墓場になる。変化に適応することと、境界を持たないことは別物だ——が、この区別を維持するには、誰かが「入れない」と言い続ける胆力が要る。SaaSの世界ではこれが「フィーチャーファクトリー」と呼ばれる病になり、OSSの世界ではメンテナが機能要求の圧に燃え尽きる。私が楽譜アプリを公開しないと決めた理由の半分は、「休符はまだですか」というIssueが立つ未来がありありと見えたからである。
そしてAIが、最後のブレーキを外した。 これまでスコープクリープには天然の抑止力があった。実装コストである。「それ、3週間かかりますよ」は最強の防波堤だった。AI開発はこの防波堤を撤去する。数分で実装できるなら、頼まない理由がない——今回の私がまさにそうだった。そしてこれは私だけの話ではない。AIは全員を「発注者兼実装者」にする。 つまり業界全体が、あの止まらなさを、稟議も見積もりもなしに個人のスケールで体験する時代に入った。実装がタダに近づくほど、価値の重心は「何を作れるか」から「どこで止めるか」へ移る。スコープの規律は、かつてPMの仕事だった。これからは全員の仕事になる。
どこで止めたか
ヘ音記号と全曲ベースまで作ったところで、「次は同一段内の和音では?」という欲が来た。ここで打ち止めを宣言し、READMEに書いた。
同一段内の和音・休符記号・付点・調号・強弱はサポートしない。それは楽譜エディタの領分であり、このプロジェクトはここで止まることに価値がある。
打ち止めをコードではなくREADMEに書いたのは、次にリポジトリを開いた未来の自分(あるいはAI)への手紙にするためだ。スコープの境界は、決めた瞬間に文書へ固定しないと、次の「ついで」で溶ける。受託なら契約書とSOWがこの役割を担うが、個人開発とAI開発には契約書がない。だからREADMEに書く。境界の文書化は、AI時代の新しい必須スキルだと思う。
そしてもう1つの決断: このアプリは公開しない。リポジトリもprivateのまま眠らせた。完成と公開は別の意思決定である。遊びきったものを、遊びきったまま棚に置く自由もある。
まとめ
- 音楽アプリの要件が膨らむのは、楽譜が「切り取れない全体」で、名曲がそのまま要件定義書になり、AIが「ついで」のコストをゼロに見せるから
- 受託のクリープは善意の正論から始まり、固定価格の上で複利で効く。「アジャイルだから」は境界の放棄の免罪符ではない
- AIは実装コストという最後の防波堤を撤去した。これからの規律は「何を作れるか」ではなく「どこで止めるか」
- 打ち止めはREADMEに書く。境界は文書化しないと「ついで」で溶ける
- 賢いアルゴリズムより正しいデータソース。困ったらパブリックドメインのMIDIがある
1日の遊びとしては上等だった。バッハは偉大である。そして楽譜という完成された体系は、スコープクリープを観察する最高の実験室だった。