目次

決め手ログという比較投票アプリのリポジトリには、少し変わった特徴がある。最初の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行あった。