Baby Monitor Timmyは、家庭でのプライバシーを尊重するベビーモニターを作るという、シンプルなアイデアから始まりました。 クラウドへの録画保存はなく、子ども部屋から外部へ向かう不要なデータ経路もありません。あまり知られていませんが、Timmyはチューリッヒで私一人が開発しているプロジェクトです。そして GitHub Copilot は、私にとって非常に速いペアプログラマーです。
人とAIの開発フロー
役割分担は明確です。機能を定義し、優先順位を付け、アーキテクチャ上の判断を下すのは私です。 Copilotは実装を支援します。コードの作成、テストの追加、バグの絞り込み、リリース手順の準備などです。
私の普段のスプリントは、おおむね次のような流れです。
- 機能の説明: エッジケースや制約も含めて、その機能に何をさせたいかを説明します。
- 実装: Copilotがコードを提案し、プロジェクトの既存の規約に従います。
- テスト: 2台のエミュレーターで自動E2Eテストを実行し、子ども側と親側の実際の接続を確認します。
- 配布: テストに通れば、AndroidとiOSのビルドを適切なストアおよびテスト配布トラック向けに準備します。
このサイクルを機能追加やバグ修正のたびに繰り返します。すべての行を自分で書いているわけではありません。それでも、 何を 作るか、 なぜ 作るか、そして提案がTimmyに合っているかどうかを決めるのは私です。
構想からWebRTCへ
中心となる技術課題は最初から明確でした。2台のスマートフォン間でリアルタイムに音声と映像を届けることです。 WebRTCは当然の選択肢でしたが、Flutterへの統合は簡単ではありません。ICE候補、 SDPネゴシエーション、TURNフォールバック、DataChannelを正しい順序で連携させる必要があります。
Copilotは、これらの要素を一つずつ組み合わせるのに役立ちました。ピア接続の設定、 重要な順序の維持(offerの前にDataChannel、setRemoteDescriptionの前にonTrack)、 Firebase Firestoreでのシグナリングです。次へ進む前に、各要素を2台のエミュレーターで動かす必要がありました。
ECDHによる安全なペアリング
最も重要な機能の一つが、 安全なペアリングシステムです。 2台のデバイスは、互いの身元を保証する中央サーバーに頼らず、相互に信頼関係を確立する必要があります。解決策は、Firebase経由のECDH P-256鍵交換と、中間者攻撃を検知するために画面上で確認する番号(SAS)を組み合わせることでした。
Copilotは暗号処理の一連の実装を支援しました。鍵生成、公開鍵交換、 共有シークレットの導出、SASの計算、さらに後続するすべてのシグナリングデータに対するAES-256-GCM暗号化です。 ペアリングキーをバックエンドに送ることはありません。Firestoreドキュメントの識別子には、そのSHA-256ハッシュだけを使います。
セキュリティ監査:脆弱性の発見と修正
私にとってAI支援開発は、単に入力が速くなるだけではありません。体系的なバグ探しにも役立ちます。 集中的なセキュリティ監査スプリントで、Copilotはコードベースを分析し、修正が必要な 6件の問題 を見つけました。
- シグナリングデータの入力検証不足
- ICE候補の処理で起こり得る競合状態
- 適切にクリーンアップされていなかった古いセッションデータ
- 許可範囲が広すぎるFirestoreセキュリティルール
- 証明書ピンニングに関する検討不足
- TURN認証情報フローにおけるエラーハンドリング不足
6件すべてを同じスプリントで修正しました。Copilotが力を発揮するのはここです。多くのファイルを読み、パターンを比較し、私がより詳しく確認すべき箇所を示してくれます。
反復スプリント:アプリの進化
Timmyは、スピーディーでありながら範囲を明確に区切ったスプリントで成長してきました。主な節目をご紹介します。
- v1.8: ペアリングを全面的に再設計 — 旧来の直接鍵方式を、4文字コード+Firebase経由のECDH P-256に置き換えました。
- v1.10: セキュリティ強化スプリント — 6件の脆弱性を監査し、修正するサイクルを実施しました。
- v1.11: すべての画面に対応したダークモードに加え、今お読みのホームページとブログ。
- v1.12: 親側画面を大幅に刷新し、ナイトビジョンモードと、カメラフレーム解析による動き検知を追加しました。
どのスプリントも基本の流れは同じです。目標を説明し、提案を確認し、自動テストを行い、テスターへ配布します。
デバイスをまたぐE2Eテスト
ベビーモニターを1台のデバイスだけで適切にテストすることはできません。子ども側のデバイスと親側のデバイスが必要です。 プロジェクトは2台のAndroidエミュレーターを同時に動かすところから始まり、現在は ローカルのiOSシミュレーターと実機での確認もこのループに加えています。Androidの自動テスト スクリプトは現在も次のことを行います。
- 両方のエミュレーターにアプリをインストールする
- 両方のデバイスでペアリングを進める
- 音声と映像の接続が確立されることを確認する
- プッシュ・ツー・トーク、カメラ操作、その他の機能をテストする
2台のエミュレーターは同じIPアドレスを共有しているため(10.0.2.15)、STUNを使った直接のP2P接続はできません。テストを実行するたびにCloudflare TURNリレーを経由する必要があります。面倒ではありますが、役にも立ちます。最も複雑な接続経路が毎回テストされるからです。
学んだこと
AIペアプログラマーと一緒にアプリを完成させるなかで、いくつか学んだことがあります。
- アーキテクチャはこれまで以上に重要です。 明確なルールと十分に文書化された コードベースがあれば、AIは一貫性のあるコードを提案しやすくなります。曖昧さのコストはすぐに大きくなります。
- テストは欠かせません。 AIが生成したコードにも、人が書いたコードと同じ厳格な テストが必要です。自動E2Eテストのおかげで、手作業では見落としやすい問題を発見できました。
- 人が常に関わり続けます。 アーキテクチャ上の判断、セキュリティ上の トレードオフ、プロダクト上の線引きは、すべて私が決めます。AIは実装を速めますが、判断そのものを置き換えるものではありません。
- スピードが品質を支えます。 機能を数日ではなく数時間でリリースできるため、 仕上げやバグ修正に充てられる反復回数が増えます。ただし、速ければ自動的によいものになるわけではありません。
これから
Baby Monitor Timmyはこれからも進化していきます。iOS版のリリースは間近で、その後もセンサー機能の追加と継続的なセキュリティ強化を予定しています。 開発フローは変わりません。方向性と境界を決めるのは私で、Copilotが実装と確認を素早く支援します。
セキュリティに関わる構成要素は現在、 明確に 区分された形で、公開 されている baby-monitor-timmy-coreリポジトリに置かれています。 ペアリング、シグナリング、バックエンドインターフェースに関するアーキテクチャ上の判断も、同じリポジトリに記録されています。