0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

`migrate:fresh`で本番DBが消える——Claude Codeの自動承認とフレームワークの破壊コマンド

0
Posted at

何が起きているか

Claude Code を自動承認(auto-accept)で走らせている人から、同じ系統の事故が続けて報告されています。直近の報告(anthropics/claude-code の起票 #69059)では、エージェントが php artisan migrate:fresh を確認なしで実行し、開発用のデータベースが2日続けて全テーブル削除されました。コメント欄には、tinker 経由でドキュメント指向のデータベースを落とした人、rails db:drop で消した人、と複数の枠組みで同型の被害が並んでいます。

migrate:fresh は「全テーブルを落としてから作り直す」コマンドです。本番の接続先を向いていれば、本番が消えます。エージェントは「テストを通すために一度リセットしよう」という素直な意図でこれを選びますが、自動承認では人間の確認をはさまずに走ります。

なぜ既存の安全策が見落とすのか

データ破壊を止める設定は世の中にありますが、その多くは rm -rfddmkfs といったシェルの破壊コマンドを対象にしています。ところが、

Laravel  : migrate:fresh / migrate:reset / db:wipe
Rails    : db:drop / db:reset
Django   : manage.py flush
Prisma   : migrate reset / db push --force-reset
Doctrine : schema:drop / database:drop

これらは枠組み固有の動詞で、シェルの危険パターンには一致しません。だから「rm -rf を止める」たぐいのガードはこれらを素通りさせます。git の保護(force push の禁止など)も、データベースは守ってくれません。守る層がぽっかり空いているのが、この事故が繰り返される理由です。

消される前に止める一行

対策は、コマンドが実行される前に内容を検査し、破壊の動詞が含まれていたら止める PreToolUse の hook です。無料の cc-safe-setup にこのガード(block-database-wipe)が入っているので、一行で導入できます。

npx cc-safe-setup --install-example block-database-wipe

導入した状態で実際の挙動を確かめました(2 が「止める」、0 が「通す」)。

[2] php artisan migrate:fresh          ← 止める
[2] php artisan migrate:fresh --seed   ← 止める
[2] rails db:drop                      ← 止める
[2] npx prisma migrate reset           ← 止める
[2] python manage.py flush             ← 止める
[0] php artisan migrate                ← 通す(通常の追加は邪魔しない)
[0] ls -la                             ← 通す

通常の migrate(テーブルを足すだけ)は通り、全削除の動詞だけが止まります。止まったときは理由が画面に出るので、本当に必要なら自分で実行し直せます。エージェントの手からだけ、取り返しのつかない一手を外す形です。

もう消えてしまった場合の復旧

予防の話を先にしましたが、すでに消えてしまった人向けに、戻せる可能性のある経路を事実だけ挙げます。いずれも事前にその仕組みが有効だった場合に限るので、過度な期待はしないでください。

  • MySQL: バイナリログ(binlog)が有効なら、mysqlbinlog で削除直前までの操作を再生して戻せることがあります。
  • PostgreSQL: 先行書き込みログ(WAL)が取られていれば、時点復旧(PITR)で戻せます。直近の pg_dump があればそこから。
  • ドキュメント指向のデータベース: 直近の mongodump のバックアップから復元。

バックアップも先行ログも無ければ、開発のデータベースは基本的に戻りません。だからこそ、止める一行を先に入れておく価値があります。

正直な限界

このガードは「危険な動詞の一覧に当たったら止める」型です。だから、tinker の中にインラインで書いた任意のコードからデータベースを落とすような書き方は、動詞の一致をすり抜けることがあります。自動承認を「これで完全に安全」と過信せず、本番に近い接続先で作業させない、危険な操作は手動の承認に回す、という運用と合わせて使ってください。完全な防壁ではなく、いちばん起きやすい一手を確実に外す層、という位置づけです。

もっと広く事故を防ぎたい人へ

データベースの全削除は、Claude Code を長時間まかせたときに起きる「取り返しのつかない操作」の一例です。ほかにも、未コミットの作業が消える、サブモジュールの作業ツリーが消える、worktree が親の HEAD を汚す、といった事故が、いま月ごとに新種が出ています。それらの予防と、起きた後の確認・復旧の手順を一冊にまとめたのが、有料の『Anthropic公式ガイドにない事故防止——Claude Code 800+時間の全記録』(Zenn・¥800)です。無料の章で対象と全体像が読めるので、合うかどうかを先に確かめてから判断してください。無料の hook 集 cc-safe-setup と合わせて使う前提の本です。

止める一行を入れるだけでも、今日いちばん怖い一手は防げます。まずは npx cc-safe-setup --install-example block-database-wipe から。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?