ワダチを作る #14:公開の前に、別のモデル(Fable)にセカンドオピニオンを頼んで、公開した
前回(#13)で、利用規約や紹介のページを作り、あとは本番の Access を外すだけになりました。
その前に、ここまでのコードと文を、別の目で見直してもらうことにしました。今回は、そのレビューと、実際に公開した話です。
- 書いたのとは別のモデル(Fable)に、5 つの観点でレビューを頼んだ
- 報告を 1 件ずつ確かめて、直すもの・直さないものを決めた
- 公開の前に直すものを直して、本番の Access を外した
なぜ、別のモデルに頼んだか
ワダチのコードと文は、ほとんど同じモデル(Claude の Opus)が書いています。同じ頭で見直すと、書いたときと同じ思い込みのまま、通してしまうおそれがあります。
ちょうど、Claude の新しいモデル「Fable」が、使っているプラン(Max)で、しばらくのあいだ使えました。そこで、Fable にセカンドオピニオンを頼むことにしました。ねらいは 2 つです。
- 違うモデルの目で見て、同じ見落としを重ねない
- 決めた経緯を知らない、新しい目で見る(「前に確かめたから大丈夫」という思い込みがない)
ハコヅミでも、ベータ版の前に同じレビューをしています。そのときは別のモデルを使えず、同じモデルの新しいセッションで行いました。それでも、直す Issue がいくつも出ました。
頼み方
観点を 5 つに分け、観点ごとに、新しいセッションで頼みました。
- 全ソース(バグと、よりよい構成)
- セキュリティ
- 利用規約・プライバシーポリシー(文と実装のずれ)
- テスト(空振りしているテスト、確かめていない経路)
- 画面の使い方(提案だけ)
どの回にも、同じ前置きを付けています。要点は次のとおりです。
- 直させない。報告だけ。重い順に、何が問題か・ファイルと行・どういう入力で何が起きるか・確信の度合い
- 「こう決めた」と書いてあることでも、決め方そのものが危なければ指摘してよい
- 前のセッションの経緯(記憶)は、判断の根拠にしない。今のコードと文を読んで判断する
- 問題がなかったところは、「何を見て、問題がないと判断したか」を書く(見ていないのか、見て大丈夫だったのかを区別するため)
報告は、うのみにしません。ふだんのセッションに戻って、1 件ずつ、本当に起きるかを確かめました。
見つかったこと
1. ソース:記録の画面が、無料プランの上限を大きく超えていた
いちばん大きかったのは、記録の画面が、表示のたびに、全期間の記録を読んで数え直しているという指摘です。
本番の Cloudflare のログ(Observability)を見ると、記録の画面の CPU 時間は、1 回 41〜114ms でした。Workers の無料プランの上限は、1 回 10ms です。まだエラーにはなっていませんでしたが、記録が増えるほど重くなります。この直しは、次回の話です。
ほかにも、小さな穴がいくつか見つかりました。
- 始めた日を打ち間違えると(2026 年を 0226 年など)、記録の画面が何百年分を数えて、開けなくなる
- 内容を 51 個以上選ぶと、エラーになる(D1 は、1 つの SQL 文に渡せる値が 100 個まで)
- 2 つの端末からほぼ同時に保存すると、座った時間が減る・期間が 2 つできる、がまれに起きる
2. セキュリティ:他人のデータに届く経路は、なかった
Fable は、手元で確認用のユーザーを 2 人作り、利用者 B から A の習慣へ、17 種類のリクエストを実際に送って確かめていました。どれも 404 か 400 で、他人のデータに届く経路は見つかりませんでした。
指摘は 3 つでした。
- 回数の制限が、無料プランの 1 日の枠を守れていない:ログインの始まりは、ログインしていなくても、1 回ごとにデータベースに 1 行書く。今の制限(1 分 30 回)では、枠を使い切れてしまう
- 入口の判定(hooks)は URL をエンコードされたまま、画面の振り分けはデコードしたあとで見ていて、ずれがある(今は抜け道にならない)
- Google のログインのトークンが、データベースに平文で残っている(アプリは使っていない)
3. 規約:「お知らせします」と書いたのに、知らせる場所がない
利用規約に「本サービスの中でお知らせします」と書いてあるのに、お知らせの仕組みがない、という指摘です。言われてみれば、そのとおりでした。
ほかにも、文と実装のずれが 10 件ほど。たとえば、「残しません」の直後に「残ります」と書いてある、タイムゾーンのクッキーがログインの前から付く、ブログに入っていないアクセス解析のクッキーのことを書いている、などです。
4. テスト:空振りはなかったが、言いすぎがあった
「断られること」を確かめるテスト 65 か所を、1 つずつ突き合わせてもらいました。空振りしているテストは、ありませんでした。
ただ、Issue の受入条件に「自動テストで確認」と書いたのに、実際にはテストが通っていない経路が 3 つありました。テストを足しました。
5. 画面:初めて使う人のつまずき
画面の絵 34 枚つきで、22 件の提案をもらいました。初めて使う人が、つまずきそうなところです。
- 曜日を選んでも「曜日を指定」に切り替わらず、黙って「毎日」で保存される
- 「やめる」が、確認なしで、すぐ実行される
- 記録の画面に、毎日、割合(%)が出る。成績表のように見えて、「責めない」方針と合わない
- タイマーを止めたあと、何が記録されたか分からない
直したもの・直さなかったもの
指摘を確かめて、公開の前に直すものを 6 つの Issue にしました。
- 小さな穴(始めた日の範囲、内容の数、同時の保存)
- 守りの強化(ログインの回数を 1 分 10 回に、パスの判定をデコードしたあとに、Google のトークンを暗号にして保存)
- 記録の画面を軽くする
- お知らせを作る(ハコヅミと同じ作り)
- 規約・ポリシー・画面の文を、実装に合わせる
- 初めて使う人のつまずき(曜日を触ったら自動で「曜日を指定」に、「やめる」に確認、記録の画面から割合を外す、タイマーの結果を出す、など)
直さないと決めたものには、理由を残しました。たとえば、GitHub Actions の参照を、タグではなくコミットの番号で固定する、という指摘です。安全にはなりますが、版を上げる手間が増えます。使っているのは GitHub 公式のものだけなので、長く 1 人で保守する方針を優先しました。
画面の提案のうち、すぐに直さないものは、あとで直す Issue(ステップ5)にしました。
公開した
直しを本番に出したあと、前回書いた手順で、本番の Access を外しました。Access の画面の操作は、人が行います。
- 本番で、招待制が効いていることを確かめた。招待していないアカウントでログインすると、「このアカウントは、招待されていません」と断られ、ユーザーも作られない
- 本番の Access と、ホーム画面のアイコンのための例外の設定を消した
curlとブラウザで、ログインしていなくても、トップページ・使い方・規約が見え、記録の画面はログインの画面に移ることを確かめた
招待制を確かめるには、「まだユーザーがいない Google アカウント」が要ります。ところが、手元のアカウントは、確かめる前に一度ログインしてしまっていました。そこで、その行を本番のデータベースから人が消してから、試しました。
あわせて、Cloudflare のレート制限ルール(IP アドレスごとに 10 秒 100 回まで)を入れました。アプリの中の回数の制限は送信しか数えないので、読むだけのリクエストもまとめて抑えるためです。無料プランでは、ルールの画面に「ホスト名」の欄がなく、「式を編集」で http.host eq "wadachi.jiru-labo.com" と書きました。
招待制は、続けます。ベータ版のあいだは、初めて使い始められるのは、招待した人だけです。ステップ4のマイルストーンを閉じて、ステップ5(その他の機能強化)に進みました。
おわりに
- 書いたのとは別のモデルに、観点ごとに、直させずに報告だけを頼んだ
- 報告は、うのみにせず、1 件ずつ確かめてから直した。直さないものは、理由を残した
- いちばん大きな収穫は、本番の CPU 時間が、無料プランの上限を大きく超えていたことに気づけたこと
- 「自動テストで確認」と書いたのに通っていない経路は、レビューでなければ気づけなかった
次回は、記録の画面の CPU 時間を下げた話と、その途中で気づいた、データベースの「読む行の数」の落とし穴です。