git worktree を1本ずつ消して音声ファイル数を確かめた日:スマホ版の修正と外付けSSDへの控え

開発eurekapu-nuxt4

git worktree を1本ずつ消して音声ファイル数を確かめた日

朝、引き継ぎファイルを1つ渡して、帳簿なし版のスマホ表示の続きから始めた。 Claude Code に制作画面を開かせると、「音声は未合成」と出た。 手元の音声ファイルが前日(10-27)の事故で消えていて、Mac から戻してもらってからの再開になった。 このセッションは結局、ほとんどが音声を取り戻して守る作業になった。

iOS 版と比べて、1つ目の違いだけを本体へ移した

開いてもらったスマホ版の No01(0:16 の位置)のレビューを求められたが、見てほしかったのはそこではなく iOS 版のほうだった。 帳簿なし版の iOS 版を最新にプルして、リポジトリ側と比べてもらった。 iOS 版のほうが、より良くなっている気がしていたからだ。

違いは2点で、どちらも iOS 側で後から足した改良だった。 iOS 版は Web 版の画をそのまま写し、写しを作るスクリプトを書き換えて改良を上乗せしている。 1点目は、ある説明をしている間だけ、図の①と②を画面いっぱいに出す動きである。

1点目は直してほしいと伝えた。 2点目は、今回こちら側では出ていない気がしたので、そのままにした。

この動きと、iOS 側でこの動きに入れていた直しを、まとめて本体へ移してもらった。 テストを更新して通したあと、わざと直しを外して、直しの検査がきちんと引っかかるかも確かめさせている。 1080×1920 で画を確かめ、変更理由の記録も書き足して、コミットまで進めた(push はまだしていない)。

irodori-tts の出力と、生成物の印

次に、音声の引き継ぎファイルを渡した。 すでに戻してあった5フォルダは、件数が手元と一致していた(490件、2,306件、323件、1,101件、742件)。 残り4フォルダは Mac 上で合わせて約9.7GB だった。 引き継ぎに1フォルダ14GBと書いてあった分は、ほとんどがキャッシュだった。 進め方は、MP3 にしてから戻す B 案に決まった。

ここで、2つ気になって聞いた。 irodori-tts で生成すると、必ず WAV になってしまうのか。 irodori-tts は生成したことが分かる印を入れていたはずだが、それは MP3 にする段階で消せるのか。

1つ目の答えは「必ずではない」だった。 2つ目は、Mac 側のコードで透かしの正体を確かめてもらってから答えを聞いた。 どちらの答えにも納得して、了解と返した。

そのあと計画書を書かせて Codex レビューを通し、残りのフォルダを取り込ませた。 取り込んだのは3フォルダ分で、2,860件、2,024件、1,862件とも SHA-256 で全件一致した。

for ループの削除コマンドが引っかかった

取り込みのあと、引き継ぎに残っていた worktree の片付けに移った。 ここで Claude Code 側の作業が何度か止まっている。 最初の検査コマンドは cmd //c の書き方を誤っていて、検査自体が走っていなかった。 次は、削除の安全装置が変数で書いたパスを拒否した。 最後は削除の直前で権限に止められ、判断がこちらに回ってきた。

差し出されたコマンドには、for ループが入っていた。 これが気になった。 ループで何を消しているのかを聞くと、サブエージェントの作業用 worktree(.claude/worktrees/agent-*)が5つで、ループの外で ipv6-monitor を1つ消すので、合わせて6つだという。

C ドライブがどれぐらい空くのかも聞いた。 答えは6〜8GBほどで、いまの空き239GBに対して3%程度だった。 急いで消す理由になるほどの量ではない。

それなら、1本ずつ自分で打つことにした。 各コマンドの最後に、音声ファイルの件数を数える find を付けた。

rm -rf .claude/worktrees/agent-xxxx/node_modules \
  && git worktree remove --force .claude/worktrees/agent-xxxx \
  && find audio-assets -type f | wc -l

1本目の結果は 12768 だった。 Claude Code に照合してもらうと、今朝戻した直後の9フォルダの合計(12,768件)と同じ数だった。 9フォルダの内訳は、先の5フォルダに、残り4フォルダの 1,060件、2,860件、2,024件、1,862件を足したものである。 2本目も3本目も、12768 のまま返ってきた。

「これも消しちゃってませんか」

3本目を消したあと、ローカルのレッスンページを開くと、ある画面で音が出なかった。 「これも消しちゃってませんか」と聞いた。

答えは「はい、消えています」だった。 ただし worktree の削除で消えたのではない。 そのレッスンのストーリー音声2系統(150本と199本)は、10-27 の事故で消えていて、控えもどこにも残っていなかった。 合成は 10-22 に、Windows の irodori-tts で行ったものだった(その時期、Mac はアプリ作りで使っていた)。

外付け SSD に控えはなかった

ここで、Windows に繋いである外付け SSD を思い出した。 あそこにバックアップしていなかったか。 Claude Code に中身を見てもらい、フォルダ名でも探してもらったが、音声の控えは見つからなかった。

それなら、WAV も C ドライブではなく SSD に置いてほしい。 SSD を外したら当然聞こえなくなるが、挿しておけば済む話でもある。 ローカルの開発環境なら、SSD に置いても C に置いても、ブラウザで再生できるのではないか。

聞いてみると、技術的にはできるという答えだった。 ブラウザの再生は dev サーバーがファイルを読んで返しているだけなので、置き場所が変わっても聞こえ方は同じになる。 ただし注意点が2つあって、勧められたのは「本体は C、SSD には控えを写す」形だった。

それでいい、と決めた。 ミラーで控えを取る運用にする。

実装は、私の言った「ミラー」をそのまま /MIR にせず、足すだけのコピー(/E)で組んでもらった。 ミラーは、元に無いものを控えからも消す。 前日のように元が消えた状態で流すと、控えまで消えてしまう。 足すだけのコピーなら、元で消えたファイルも控えに残る。

1回目の控えは約1分で終わった。 手元の12,771件(15.0GB)をすべて SSD に写し、全件が控えにそろっていることも確かめさせた。 以後は、合成や取り込みのあとに node scripts/backup-audio-to-ssd.mjs を流す。 SSD を挿していないときは、このスクリプトは何もせずに止まる。

残り3本の削除と、Mac での合成し直し

控えの仕組みをコミットしてもらい、残り3本の削除コマンドをもう一度出してもらった。 消えた2系統の音声も合成し直していいと伝え、ちょうど MacBook を開いていたので Mac でやることにした。 コミットの際は、メッセージ中の「F:」を削除の安全装置が削除先と取り違えて拒否した。 メッセージはファイルに書いて渡し直してもらった。 控えを取ったときに件数が3件増えたので、ここからの目安は、最後の数字が12,771以上であることに変わった。

4本目は、1〜3本目と同じく node_modules を消してから worktree を外した。 5本目と6本目は、git worktree remove --force だけで消した。 6本目は、一時フォルダに置いていた ipv6-monitor である。 3本とも、最後の数字は 12771 のままだった。

6つが消え、C ドライブの空きは239GBから247GBに増えた(約8GB)。 残したのは、残すと決めていた3つの worktree と本体だけである。

Mac の tmux のセッション名は、手順書の想定と違って claude と claude-audit の2つで、どちらも使用中だった。 「Mac に頼むなら何でもいい、tmux のセッションを立ち上げてもらってもいい、A パターンでいい」と返した。

Mac 側でも、すんなりとは始まらなかった。 git fetch は、SSH 経由だと GitHub の認証情報を読めずに止まった。 合成は、メモリのゲートで順番待ちになった。 空きメモリが7.7GBで、合成を始める条件の8GBにわずかに届かない。 メモリを多く使っていたのは、iOS シミュレータ2つと Claude Code 2つ、それに写真の解析(約0.9GB)だった。

メモリが空いて合成が始まり、1場面目ができるまで、ゲートの待ちを含めて約6分かかった。 この速さだと、46場面で4時間前後になる。 全部を待たずに、できた2場面で「取り込み → MP3 化 → ブラウザで再生」の流れを先に通させた。 16件を取り込んで SHA-256 が一致し、MP3 14本(3.0MiB)に変換して、問題なく再生できた。

その後は1場面あたり3〜4分のペースで進んだ。 46場面中8場面が済んだところで、場面ごとの報告をやめて、全部終わったときか失敗が出たときだけ知らせる見張りに切り替えてもらった。 残りは2時間半ほどの見込みである。

振り返り

for ループなら、6つの worktree は一度に消せた。 そうせずに1本ずつ打ち、そのたびに 12768 か 12771 が返ってくるのを見てから次を打った。 数字は最後まで減らなかった。 一方で、音が出ないレッスンを見つけてみると、音声はもっと前の事故で消えていて、どこにも控えがなかった。

  • 消す操作はループにまとめず1本ずつ打ち、守りたいファイルの件数を毎回数える。数字が変わらなければ、守りたいものを巻き込んでいないと分かる。ただし分かるのは、数え始めてからの増減だけである
  • 控えは「足すだけ」で取る。ミラーは元に無いものを控えからも消すので、元が消えたあとに流すと控えまで失う
#eurekapu-nuxt4#git worktree#バックアップ#音声ファイル#irodori-tts#Claude Code