API レイヤーに潜んでいたそのバグ
テーブルのビューがロードされた。Canvas がレンダリングされた。テーブルはデータベースに存在していた。
しかしフロントエンドがサーバーにテーブルの現在の状態を尋ねたとき — 座席、スタック、誰がどこに座っているか — サーバーは 404 を返した。何も。座席も、ゲームデータも、レンダラーが作業できるものは何もなかった。
Canvas は描くものがなかったから空白だった。
技術的な説明をできるだけ短く:テーブルエンジンの前にある API ゲートウェイは、リクエストを転送する前にすべての URL から接頭辞を取り除く。/api/v1/tables/... はテーブルエンジンに /tables/... として到着する。ビルドセッションが書いたテーブルエンジンのルートは完全な接頭辞を期待して登録されていた — だからサーバーは /api/v1/tables/... をリッスンしていたが、受け取っていたのは /tables/... だった。すべてのリクエストが外れた。
ロジックエラーではない。壊れたアルゴリズムでもない。間違ったアドレスを持つルーティングテーブルだ。スタック全体を一緒にテストしたときにのみ表面化する種類のものだ。
見つけるのにどれくらいかかったか?
スタートから修正まで:1 時間未満。
これは速い。何が速くしたか:デバッグ方法論。
これについて AI エージェントと作業するというのは、「何が悪い?」と尋ねて答えを期待することではない。エージェントに同時に正しいコンテキストを与えることを意味する — 接頭辞を扱うプロキシ設定、テーブルエンジンのルート登録ファイル、404 を示すリクエストログ — そして不一致を追跡するように頼むこと。
これらの断片が一緒に見えるとき、エージェントは人間のエンジニアがナビゲートするだけで 20 分かかる表面領域にわたってパターンマッチできる。エージェントはプロキシの rewrite ルールとテーブルエンジンのルート登録の間のミスマッチを約 3 分で見つけた。
バグの裏のバグ
ルーティングバグを見つけたことで次のバグが露わになった。
エンドポイントは今度は応答した。しかし返したデータの形式が間違っていた。
テーブルエンジンは内部で 1 つの言語を話す:座席番号、occupied のようなステータスコード、生のチップ数を単純な整数として。フロントエンドのレンダラーは別の言語を話す:座席インデックス、$235.50 のようなフォーマット済み通貨文字列、それが対して書かれた型定義から契約として期待する特定のフィールド名。
誰も変換レイヤーを書かなかった。ビルドセッションがエンドポイントを書き、それは内部形式を返した。レンダラーは認識できないデータを受け取り、静かに何も生成しなかった。
これは事前にテストを書くのが悪名高く難しいクラスのバグだ。両方のシステムが動いていて、接続されていて、互いに話そうとしているのを見る必要がある。どのシステムも単体ではバグを持っていないとき、2 つのシステム間のギャップをカバーするユニットテストはない。
これがビルド方法論にとって意味すること
テスティングフェーズは方法論が失敗したことを意味しない。方法論が我々をテスティングまで連れてきたことを意味する。
すべてのソフトウェアプラットフォームには、各部品が実世界で互いに出会わなければならない統合レイヤーがある。Spec-driven 開発はそのレイヤーへ素早く連れていく。それをスキップしない。
このシリーズの次の記事では、修正を適用したときに何が起きたかをカバーする — そしてブラウザは依然として同じ壊れた結果を表示した。
我々がどう構築するかの背後にあるエンジニアリング方法論 — spec、セッション、セッション中にエージェントが何をするか、アーキテクトが何をするか — 完全な記述は The Salty Korean にある。
Stay salty.
The Salty Korean
Salty Poker Networkの創設者。テキサスポーカー、プラットフォーム構築、オンラインポーカーの未来について執筆しています。 詳しくは The Salty Korean.