シーン回帰テストの区間選びを改修し、メモリ逼迫からWindowsとMacのLAN直送を作った日
シーン回帰テストの区間選びを改修し、メモリ逼迫からWindowsとMacのLAN直送を作った日
朝、前日の引き継ぎファイルを Claude Code に渡した。 「これ多分何も進んでないですよね」と聞くと、答えはそのとおりだった。 引き継ぎで作るはずだった計画書は、まだ影も形もなかった。
同じ朝、もう一つのセッションでは前日のメモリ逼迫を追っていた。 原因探しから始めたはずが、話は Windows と Mac のあいだでメッセージをどう届けるかへ流れていった。 その日の最後に Mac へ渡したかった1行は、渡す方法が見つからないまま終わった。
回帰テストの改修を計画書から通す
計画書と2件の判断
要約だけで比べる案(c)を実際に計算させ、全区間ぶんの所要時間を測った。 3本で約25秒だった。 試作の1本を含む21区間すべてで、10-04 の変更前後の要約が一致した。
図つきの計画書を Codex のレビューにかけると、致命的な指摘が3件返ってきた。 直して2回目にかけたところで「実装着手可」になった。 判断が要る2件はフォームで答えた。 区間の選び方は3段構えにし、全区間の網を張るのは CI だけにする。
計画書ができた時点で、「引き継ぎっていうか、進めていいですよ、そのまま」と伝えて実装に入ってもらった。
Git Bash に壊された試しの入力
先に、作業ツリーに触れずに変更前のファイル一式を取り出せるかを確かめてもらった。 Git LFS の対象外だったので、取り出せることが分かった。 区間を選ぶ純粋関数を書き直し、単体テストは20件になった。
途中で、コメントだけの変更が「実行に影響あり」と判定された。
仕組みの誤判定かと思えたが、原因は試しの入力のほうにあった。
Git Bash が // を / に変えていて、入力そのものが壊れていたのである。
入力を直すと、コメントだけの変更は対象0本と正しく判定された。
ほかにも2件、試しのコミットの作り方がまずかった(改行が文字のまま入った、比べる元のファイルが古かった)ので作り直した。
取りこぼしを探す
過去の変更ごとに記録を取り直し、新しい仕組みの③で選ばれる本数と突き合わせた。 1件目の 09-28 の列の固定(14本)から7件目の 7b〜7f(5本)まで、取り直した本数と③の本数はすべて一致し、取りこぼしは0だった。
続けて、試しの変更を4つ流した(1つ数分)。 そのうち3つの結果は次のとおりである。
- AND 関数を変えると、AND を使う Step 5 と Step 7 の中から6本が選ばれ、ほかの区間は選ばれなかった
- カメラの動きの曲線を変えると、CF精算表の20本が全部選ばれた(試作の1本は別のエンジンで描くので変わらない)
- 固定カメラの試しでは 6a だけが選ばれた。今の仕組みでは0本で、取りこぼしていたところである
コミットは2つに分けた。 2つ目は Codex のコミットゲートで指摘なしだった。 1つ目は、モデルの混雑(capacity)でゲートのレビューが取れないまま通った。 そこで、モデルを gpt-6-astra に替えて、差分を手動でレビューにかけてもらった。 指摘は3件で、台本を直した区間は要約で絞らず全コマを照合すること、消えた外部ファイルも対象に残すことなどである。 直したあとの結果は、直す前と同じ6本だった。
全区間を流す
push してよいこと、全区間を流すべき場面なら流してよいことを伝えた。 あわせて「このセッションって確かこれ回帰テストのリファクタリングでしたっけ?何がゴールでしたっけ?」と聞き直した。 ゴールはひとまず達成した、という返事だった。 最後の確認として、全区間を流すことになった。
- CI の単体テスト:全21区間の回帰テスト(仮の時刻)が695秒で通った
- 手元:全21区間の全コマを、仮の時刻と本人の声の時刻の両方で照合し、44件すべて通った(44.9分)
- CI の E2E:落ちた
E2E を直すために、トップページのカード数を dev サーバーで実測すると8枚だった。 それに合わせてテストを直し、main に取り込んだ。 いったん「CI の完了」の知らせが来たが、それは昨日の古い実行を見ていただけだった。 今回の push の実行を指定して待ち直すと、Build、単体テスト、E2E のすべてが通った。 昨日の朝から main で落ちていた E2E も、これで直った。
前日のメモリ逼迫を調べる
もう一つのセッションでは、Irodori-TTS のメモリ逼迫を先に調べてもらっていた。 メモリのログによると、10/04 11:02 に別々のセッションが Irodori の合成を2本同時に起動し、物理メモリが 31.7 / 31.9GB に張り付いていた。 同じ用途のロックは 9/24 に作ってあった。 しかしスキルに書いていなかったので、別のセッションはロックを通さずに起動していた。
そこで、Irodori-TTS を使うスキルに、起動前に資源を測り、足りなければ待つゲートを入れた。 2本を同時に投げると片方が待つこと、ロックを通さずに走っている Irodori を検知して待つこと、待機の上限が効くことを確かめてもらった。
ただ、昨日メモリを埋めたのは Irodori だけではなかった気がしていた。 回帰テストを回していたときだったか、Python スクリプトがメモリを埋めて、一度自分で中断させた覚えがある。 そう伝えて、昨日のセッションを調べてもらった。 09:48 には node が一瞬 188 本(26GB)に膨らんでいた。 ログ調査はサブエージェントに任せた。 結果は、私が止めたのは2回で、どちらも原因を特定できた、というものだった。 メモリを大量に食う Python は、Irodori 以外には見つからなかった。
待っているあいだに、Windows が埋まっていたら Mac に合成を回す流れを提案された。 Mac に作らせる流れ自体は 9/22 に一度回していて、Mac が合成して R2 に上げ、Windows で取り込む形だった(129ファイルを取り込み、失敗0)。 MP4 の書き出しについては、最終版でしかやらないので要らないと伝えた。 そのうえで、フックとスキルを作ってもらった。 フックは12ケースすべてが期待どおりに判定され、settings.json に登録した。 Mac に依頼するときの手順書も、スキルの参照として足した。
Mac から Windows へ同じ Wi-Fi で送る
受け取りに R2 を使うと聞いて、それでもいいとは思いつつ、そもそもの疑問が浮かんだ。 同じ Wi-Fi にいるのだから、普通に送れないのだろうか。
聞いてみると、送れるという。 いまは Windows から Mac へ送る仕組みしかなく、Mac から Windows へ返す仕組みがないだけだった。 9/22 に R2 を経由したのも、Mac の受信サーバーが落ちていたからである。
それなら Mac が Windows へ送るほうがよい、と伝えた。 そのためには Windows の Firewall に受信の許可を足す必要がある。 許可を足すと決めたうえで、Firewall 的に問題がないかを確かめた。 範囲を絞って許可すれば心配はほぼない、という答えだった。 受け口を作り、手元で送受信と拒否のテストを済ませてもらった。 Firewall の許可は登録され、node.exe の受信を止める拒否ルールもなかった。
実装が終わったところで、セキュリティ面を中心に Codex のレビューを受けるよう頼んだ。 対象は受信サーバー、送信スクリプト、Irodori のフック、Irodori のゲートの4ファイルである。 待つあいだに、受信サーバーは常駐させないとダメなのか、ずっと動かしておくとメモリや負荷が重くならないかを確かめた。 常駐させないと受信できず、負荷が高いという話でもない、という理解で合っていた。
レビューの指摘を受けて、受信サーバー、送信側、ゲートを順に直し、最後にフックの抜け道を塞いだ。 Python 経由の書き換えはエスケープで失敗したので、Edit ツールで直してもらった。 テストは37ケース、続いて40ケースがすべて期待どおりになった。 push は、origin に Mac 側の新しいコミットがあったので一度拒否された。 中身を確かめて取り込み、push し直した。
届かない4件と tmux の新しいセッション
Mac からの疎通テストは、すぐには通らなかった。
Mac 側の Claude Code の auto mode が、~/.claude の pull を「自分自身の書き換え」として拒否し、curl も拒否したからである。
Mac からの返信が回収できていない、という話にも引っかかった。 Windows からは Mac へ直接メッセージを送れていたのに、なぜ逆向きは送れないのか。 回収とか未回収とかいう概念が、そもそも面倒くさい。 しかも Mac からは、続けて2通、合計4件送っていた。 受け取れていたのは2通だけだった。 このとき Mac では Remote Control を打っていた。 そう伝えると、残りの2通も取り出せた。 どちらも成功の報告で、Windows 側にファイルも届いていた。 Mac から Windows へのファイル送信は、送信スクリプトでも curl でも通っていた。
次に、Mac から SendMessage で返す方法をテストすることにした。 ところが Remote Control をつなぐと、Mac の入力欄の上の線にセッション名が入る。 LAN のブリッジはそれを入力欄と認識できず、テストの依頼を Mac へ送る段階で止めていた。 ブリッジは、名前入りの線の候補が複数あるときは一番外側を枠にするよう直してもらった。 Mac の実際の画面をテスト用の見本にして、テストも足した。 テストの1件が落ちたのは、見本の入力行がノーブレークスペースを含んでいて、テスト側の置き換えが当たらなかっただけだった。 ただし、直した版が Mac で効くのは、Mac で pull してブリッジを再起動したあとである。
その更新用の1行を、Mac のセッションにメッセージで送ってほしいと頼んだ。 Mac にスクリプトは置かれたものの、こちらから Mac のセッションへはメッセージを届けられないという。 経路を3つ試して、3つとも使えなかった。 わけがわからず聞き返すと、主な原因は、Mac で動いている古い版のブリッジがセッション名の入った線のせいで入力欄を見つけられないことだった。
それなら、Mac で tmux のセッションを新しく立ち上げれば送れるのではないか。 実際に立ち上げて確かめてもらうと、新しいセッションには依頼が届いた。 途中で一度「更新を確認」と報告されたが、これは誤りで、ブリッジはまだ古い版のまま動いていた。 Mac から SendMessage で直接返す方法は、今の環境では使えなかった。 代わりに、Mac に頼んだあとは返信が届くまで Windows 側がバックグラウンドで待ち受ける形にして、スキルに書き残した。 回収を私が気にしなくてよい形には、これで落ち着いた。
Mac でも有効にする1行が渡らない
続けて、フックを Mac でも有効にすることにした。 もう一つ、Mac のセッション履歴のバックアップがうまくいっていないのも気になっていた。 この2件を、新しい tmux セッションにまとめて頼んでもらった。
2件とも、Mac の auto mode に「自分の設定やログに触る操作」として止められた。 迂回はせず、私が実行するコマンドを Mac の画面に出す形になった。 それも面倒で、Mac に直接打ち込んでおいてほしいと頼んだ。 打ち込むことはできるが、打っても今回の2件は進まない、という返事だった。
おすすめの案に「y」と答え、auto mode の許可の文面とフックの登録を1本のスクリプトにまとめて Mac に置くことにした。 私が Mac で打つのは1行だけになる。 Mac に置く前に手元で試してもらい、Bash 用の登録がある場合と無い場合、2回続けて流しても二重にならないことを確かめた。 依頼は Mac に届き、返信を待ち受ける仕掛けも動いていた。 それでも、Mac に1行で渡す方法はここで行き詰まった。 バックアップが失敗している原因も、まだ分かっていない。
学びメモ
- ロックは、作っただけでは効かない。9/24 に作ったロックをスキルに書いていなかったので、別のセッションは素通りして Irodori を2本同時に起動していた
- 判定がおかしく見えたら、仕組みより先に試しの入力を疑う。コメントだけの変更が「影響あり」になったのは、Git Bash が
//を/に変えていたからだった - R2 を経由していたのは、Mac から Windows へ返す仕組みが無かったからである。同じ Wi-Fi にいるなら、受け口を作れば直接送れた