目次
決め手ログという比較投票アプリのリポジトリには、少し変わった特徴がある。最初のcommit(2026年8月7日17時45分)に、アプリのコードが1行もない。入っているのは、仕様のMarkdownが5本で2,115行、画面モックのPNGが2枚、あとはpackage.jsonなどの雛形だけだ。コードより先に、主要な決定事項がファイルになっていた。
中身を並べると、こうなる。
docs/reference/kimete-log-login-reference.png (モック)
docs/reference/kimete-log-visual-reference.png (モック)
docs/spec/kimete-log-fable5-phase1-prompt.md 405行
docs/spec/kimete-log-phase2-screen-spec.md 186行
docs/spec/kimete-log-phase3-data-design.md 454行
docs/spec/kimete-log-phase4-tech-plan.md 548行
docs/spec/kimete-log-spec-107.md 522行
ほか .gitignore / package.json などの雛形6ファイル
これは「仕様をたくさん書いた」という自慢の話ではない。書いておきたいのは置き場所の話だ。このプロジェクトでは、AIと決めたことをAIとの会話の中に置いたままにせず、ファイルへ固定してから次の工程へ渡した。その最初の物証が、このコードゼロの初commitだった。
会話の中に置いたままにしなかった
決め手ログの仕様は、ChatGPTとの対話で詰めた。2〜3個の候補で迷っている人が投稿して、みんなが「自分ならどれを選ぶか」とその決め手を投票する——そういうサービスの輪郭から、投票の細かい挙動までを会話で決めていった。
ただ、会話で決めたことは、そのままだと会話の中にしかない。そして実装するのはChatGPTではなく、別のAIのClaude Codeだ。決めた内容をClaude Codeへ渡すには、会話から取り出して、読み直せる形にする必要がある。
そこで、実装に渡す決定事項をMarkdownへ固定した。それが107項目の番号付き仕様書(kimete-log-spec-107.md)で、画面仕様・DB設計・技術計画・依頼文と合わせて5本のファイルになった。初commitの14分前には、この5本とモック2枚をまとめた受け渡し用のフォルダがローカルに作られていて、今もそのまま残っている。107項目の仕様書は設計書であると同時に、ChatGPTとの間で決めたことをClaude Codeへ持ち運ぶための媒体だった。
107項目で固定したのは「作るもの」だけではない
107という数は数え直した実数で、番号付きの項目がちょうど107個ある。範囲は13章 — サービスの基本、投票・決着、満足度、ログイン、結果表示、テーマ比較、ナビゲーション、通知、通報・BAN、退会、共有、運営管理、公開準備まで。「候補は最低2件、最大3件。4件以上は扱わない」「同率の場合は『同率』と表示する」のような粒度で決まっている。
面白いのは、固定されていたのが「作るもの」だけではないことだ。仕様書には「初期版で入れないもの」が16項目、独立した節として列挙されている。非公開投稿、コメント、いいね、通知、キーワード検索、生票数の表示——作らないものにも名前が付いて、ファイルに書かれている。冒頭には「候補の優劣・勝敗を決めない」「勝者・Winner・1位などの表現を使わない」という言葉の禁止まで置かれていた(この原則が開発開始5分後にテストになった話は、前に書いたとおりだ)。
つまりこのファイルには、作るもの・作らないもの・使ってはいけない言葉、までが会話の外に出た状態で揃っていた。
依頼文もファイルだった
初commitにはもう1本、405行のファイルが入っている。Claude Codeへの依頼文そのものだ。冒頭にこうある。
この依頼は全5フェーズのうち Phase 1のみ です。
Phase 1が完了してもPhase 2へ進まないでください。 Phase 1の実装・テスト・レビュー・修正・報告まで完了した時点で停止してください。
さらに本文には、
仕様にない機能を「便利そうだから」という理由で追加しないでください。 不明点のうちユーザー体験に影響しない内部技術判断は、自分で妥当な案を選んで進めてください。
とある。前半だけ読むと厳しい縛りに見えるが、後半の1文が対になっているのが実態に近い。どこで止まるか・何を足さないかという境界はファイルで固定し、境界の内側の技術判断はClaude Codeに任せる。全部を縛ったわけではなく、縛る場所を選んで書いてあった。
依頼文が会話ではなくファイルなのも、同じ理屈だ。実装の途中でセッションが変わっても、依頼の境界は同じ文面のまま読み直せる。
Phase単位で回った、およそ17時間
実装はこの依頼文どおりPhase単位で進んだ。初commitの5分後にPhase 1の最初の実装commitが積まれ、56分後にはshared・DB・Worker・Web・Mobileの土台が揃ってPhase 1が閉じた。夜にPhase 2「比較の核」、日付が変わってPhase 3「投票・決着」、深夜2時にPhase 4「周辺機能」。そこから8時間41分のcommit空白を挟んで、翌朝10時44分にPhase 5「公開品質・公開準備」が閉じている。
初commitからPhase 5完了までは16時間59分29秒。ただしこれはcommit間の経過時間で、途中の空白が示すとおり、実際に17時間作業し続けたわけではない。Phase 5完了時点のテストは295件(shared 65・Worker 110・DB 120)で、のちの追加開発後の数字とは別だ。
各Phaseの完了時にはセッション記録が.ai/sessions/へ残され、開発開始から2時間半後には.ai/というディレクトリ自体が追加されている。commitメッセージは「ChatGPT連携用のAI共有基盤」。現在地(CURRENT)と確定事項(DECISIONS)をrepoに置いて、ChatGPTとClaude Codeが同じファイルを見る——決めたことの置き場所が、開発中もずっと会話の外にあり続けた。
ファイルは会話より長生きする
このやり方が正解だったと証明することはできない。速く進んだのは事実だが、それが仕様の完成度のおかげかどうかは検証できないし、決め手ログ自体はいまも未公開のまま休止している。
それでも、決めたことがファイルになっていたことの効果は、いくつか形として残った。「優劣を決めない」という会話の中の合意は、仕様書の冒頭になり、確定事項ファイルになり、最後は破ると落ちるテストになった。Phaseの境界は依頼文の文面として残り、実際にPhase単位で止まりながら進んだ。そして休止から2週間経った今でも、リポジトリを開けば、当時決めたことは決めたときの言葉のまま読める。
僕自身は今でも、会話だけで決めたことをあとから取りこぼす。だから最近は、この個人サイトの記事制作フローみたいな運用ルールも、会話ではなくrepoの中のファイルに置くようになった。AIと何かを決めたら、その決定はAIに覚えていてもらうのではなく、次のAIと未来の自分が読み直せる場所に書いておく。決め手ログの初commitは、それを一番わかりやすい形でやった記録だと思っている。コードは1行もなくて、仕様と依頼文が2,115行あった。