ページを再読み込みしても、どの修正も効いていなかった
ルートは直っていた。state エンドポイントは書き直されていた。データフォーマットは修正されていた。すべての変更がリポジトリで確認され、ファイルに反映され、意図通りだった。
ブラウザを再読み込みした。何も変わらなかった。
同じ壊れたテーブル。同じ真っ白なキャンバス。
実際に起きていたこと
プラットフォームはローカルで Docker 上で動いている — 複数のコンテナがそれぞれサービスを実行し、共有設定で接続されている。フロントエンド web アプリはボリュームマウントされている:ディスク上のソースファイルが直接コンテナにマップされる。ビルドツールの Vite はファイル変更を監視し、ブラウザを自動的にリロードする。
ただし、監視していなかった。
Windows 上で WSL2 経由で Docker を動かす環境では — WSL2 は Windows がコンテナのために使う Linux 互換レイヤーだ — Vite が変更検出のために頼っているファイルシステムイベント通知が、仮想化境界を越えて正しく伝わらない。Linux の通知システムは変更を報告する。Windows はそれを転送しない。Vite はファイル更新を見ることがない。ブラウザは以前そこにあったコードを返し続ける。
修正は Vite 設定の 1 行だった:usePolling: true。変更通知を待つ代わりに、Vite は 300 ミリ秒ごとにチェックする。少し効率が悪い。動く。
テーブルエンジン — 実際のゲーム状態を管理するバックエンドサービス — も同じ問題の別バージョンを抱えていた。このスタックのバックエンドサービスは watch モードでは動かない。コード変更にはコンテナの手動再起動が必要だ。プロダクション級サービスでは標準動作。再起動が必要だと知っていればいいだけだ。
もう一つの間違い
環境の問題が解決したあと、3 つ目のバグが浮上した:テーブルルートに auth guard があり、ブラウザを常にログインページに送っていた。
ユーザーがログインしていなかったからではない。ログインしていた。Guard は決して値が入らない TanStack Router の context 値をチェックしていた — router が context provider なしで設定されていたため、context.auth は常に undefined だった。Guard は "未認証" と読み、ログインへリダイレクト。ログインは認証済みセッションを見て、ロビーへリダイレクト。ブラウザはループに陥った。
1 行変更した。Guard は authentication store から直接読むように更新された — アプリケーションの他のすべてのルートが使っているのと同じパターンだ。修正完了。
キーボードの前の人間に求められること
修正は正しかった。システムがそれを拾っていなかった。その観察 — 正しいコードと動いているコードは別物だという — には、正しい質問をするのに十分な開発環境の知識が必要だった。
エージェントは修正を書ける。バグを記述すれば追跡できる。ブラウザが設定変更前のコードのキャッシュ版を返していることに気づくことはできない。その観察は人間のものだ。
正しい修正がなぜ効いていないのか診断できるほどシステムを知っていること — それが自動化されない部分だ。
Polling 設定のあと、コンテナ再起動のあと、auth guard 修正のあと:テーブルが読み込まれた。席が現れた。Buy-in ダイアログがレンダリングされた。ロビーのカードは正しい高さだった。すべて動いた。
次の記事では、テストできる動くシステムが手に入ったあとの integration testing がどう見えたか — そしてそのフェーズが AI が書いたか人間が書いたかに関係なく同じに見える理由 — をカバーする。
この種のデバッグプロセスをナビゲートする創業者視点 — AI がコードベースのほとんどを書いたとき、human-in-the-loop の役割が実際に何を求めるか — は The Salty Korean にある。
Stay salty.
The Salty Korean
Salty Poker Networkの創設者。テキサスポーカー、プラットフォーム構築、オンラインポーカーの未来について執筆しています。 詳しくは The Salty Korean.