古いブランチからのrsyncが本番を巻き戻した夜 — 複数エージェント運用のデプロイ規律
この記事について
これは自慢話ではない。一晩でバグ修正2件を本番から消し飛ばした、運用側の自爆事故の事後談だ。
舞台は、複数のAIエージェントが同じリポジトリを横断して触る運用環境。「手元のコードを本番へ手早く反映したい」という、ごく普通の欲が引き金になった。同じ構図で作業している個人開発者・小規模チームに向けて、何が壊れたかと、どう規律で塞いだかを書く。
何が起きたか — gzip修正を「手早く」反映しようとした結果
事故は2026-06-05に起きた。収集サーバ(住宅回線に常駐している1台)で動くダッシュボードに、配信をgzip圧縮する軽い修正を入れた。これ自体は正しい修正だ。
問題は反映の仕方だった。mainより10コミット遅れた古い作業ブランチの手元ファイルを、収集サーバへ直接 rsync で送りつけた。「1ファイルだけだし、手元のが最新だろう」という思い込みだ。
結果、収集サーバのファイルは「古いブランチ版のコード + gzip修正」というフランケンシュタイン状態になった。そしてこの古いブランチには、直近でmainに入っていた2つの改善が入っていなかった。
| 巻き戻ったもの | 内容 |
|---|---|
| 画像移植のWorker化 | サーバ上りの帯域で画像を送り524タイムアウトになる問題の対策 |
| マニフェスト処理のperf修正 | 無駄なオブジェクトコピーを廃止して重い処理を解消した修正 |
gzip 1件を足すために、本番で動いていたバグ修正2件を消した。しかもサーバはgit上dirtyになり、次の git pull も素直に通らなくなった。
真因は帯域でもタイポでもなく「手元=最新」という思い込み
技術的なトリガーはrsyncだが、真因はもっと手前にある。複数のAIエージェントが同じリポジトリを触る環境で、自分の手元の状態を「最新」だと思い込んだことだ。
一人で一つのブランチを触っているなら、手元がmainから10コミット遅れることはまずない。だが、別のエージェントがその間にmainへ改善をマージしていると、自分の古いブランチは静かに時代遅れになる。git status はローカルの差分しか見ないから、この遅れは目に入らない。
手元がクリーンであることと、手元が最新であることは、まったくの別物だ。
rsync はこの落とし穴を最大化する道具だった。gitの履歴も先行関係も一切無視して、手元のファイルをそのまま上書きする。「古いけどクリーンな手元」を「最新な本番」に平気で塗り重ねてしまう。
どう塞いだか — ルールを3つに畳んだ
再発防止は根性論では回らない。エージェントが毎セッション無条件で従える、機械的な規律に落とした。
- 作業前fetchの義務化: 公開判断や反映の前に必ず
git fetch origin mainを実行し、git log HEAD..origin/mainでリモートがどれだけ先行しているかを確認する。ローカルのgit statusだけで状況を判断しない。 - 反映経路を「mainマージ → 対象機で git pull」に一本化: 作業中ブランチから本番へ直接rsyncするのを禁止した。修正は必ず最新mainベースで作り、PR→マージ→対象機で
git pull --ff-only。緊急でrsyncするときすら、送る前にgit diff origin/main -- <file>で「そのファイルがmainと同期した最新版か」を確認する。 - 散らかったブランチとworktreeを定期的に刈る: 古いブランチに居座り続けること自体が事故の温床なので、マージ済みブランチと未使用worktreeを安全に削除するスクリプトを用意した。デフォルトはdry-run(何を消すか表示するだけ)、
--applyで実行。mainと現在のブランチ、未コミットの変更を持つworktreeには触らない設計にして、掃除そのものが事故らないようにしてある。
ポイントは、3つとも「気をつける」ではなく「実行するコマンド」として書けることだ。エージェントに渡せる規律は、意志ではなく手順の形をしていないと守られない。
やってみてわかったこと
複数のAIエージェント(あるいは複数人)で1つのリポジトリを回すとき、一番危ないのは技術力の差ではなく、それぞれが持っている「現在地の認識」がずれることだ。誰かがmainを前に進めた分だけ、他の全員の手元は古くなる。その事実は git status には映らない。
だから対策は「賢くなる」ことではなく、「手元を疑う手順を毎回踏む」ことになる。作業前に必ずfetchして先行を見る。反映はmain経由に限定する。古いブランチには住み続けない。地味だが、この3つが揃っていれば、あの夜の巻き戻しは起きなかった。
道具(rsync)を責めても再発は防げない。防げるのは、道具を使う前に現在地を確認する規律のほうだ。
更新履歴
- 2026-07-06: 初稿