古いブランチからのrsyncが本番を巻き戻した夜 — 複数エージェント運用のデプロイ規律

古いブランチからの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: 初稿