1
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?

AIエージェントに git restore されて作業が消えた話 〜安全設定と多層防御〜

1
Posted at

はじめに

「AIに任せておけば大丈夫」

この認識が完全に崩れた。

Codex CLI でリファクタリングをお願いしていたら、突然こんなコマンドが実行された。

git restore --staged .
git restore .
git clean -fd

「え、待って、今なにした?」と思ったときにはもう遅い。未コミットの変更、全部消えた。数日分の作業が一瞬で。

調べてみると、同様の報告が GitHub Issues に複数上がっていた。

  • Claude Code で確認なしに git checkout が実行され、4日分の作業が消失#11237、Open)
  • Codex CLI がパッチ適用失敗時にファイルを上書きし、1日分の作業が消失#5904、Closed)

AI エージェントが予期せずデータを消失させてしまう問題は、珍しくないらしい。

この記事では、今回の失敗から学んだ多層防御の考え方と、Codex CLI / Claude Code それぞれの具体的な設定方法を整理する。

この記事で学べること

  • 破壊的な git コマンドの種類と復旧可能性
  • Codex CLI / Claude Code の安全設定(コピペで使える)
  • 設定が効かないケースと Hooks による回避策
  • 作業前チェックリスト

対象読者

  • AIコーディングエージェントを使っている方
  • 「そのうちやらかしそう」と薄々感じている方

破壊的な git コマンドと復旧可能性

まず、どんなコマンドが危険で、何が復旧できるのかを整理する。

復旧可能性の一覧

コマンド 何が消えるか 復旧可能性
git restore . 作業ディレクトリの変更 ❌ 不可能
git restore --staged . ステージング git fsck で一部可能
git clean -fd 未追跡ファイル ❌ 不可能
git reset --hard 未コミットの変更すべて ❌ 不可能
git checkout -- . 作業ディレクトリの変更 ❌ 不可能

⚠️ 重要: Git が確実に守れるのは「コミットされた変更」だけ。
ステージング済みの変更は git fsck で一部復旧できる可能性があるが、
作業ディレクトリのみの変更はゴミ箱にも残らない。


Codex CLI の安全設定

execpolicy(.rules ファイル)

Codex CLI では、~/.codex/rules/ ディレクトリに .rules ファイルを置くことで、コマンドの実行ポリシーを設定できる。Starlark 形式で記述する。

# ~/.codex/rules/block_destructive_git.rules

# git restore を禁止
prefix_rule(
    pattern = ["git", "restore"],
    decision = "forbidden",
    match = ["git restore ."],
)

# git clean を禁止
prefix_rule(
    pattern = ["git", "clean"],
    decision = "forbidden",
    match = ["git clean -fd"],
)

# git reset --hard を禁止
prefix_rule(
    pattern = ["git", "reset", "--hard"],
    decision = "forbidden",
    match = ["git reset --hard HEAD"],
)

# git checkout -- を禁止
prefix_rule(
    pattern = ["git", "checkout", "--"],
    decision = "forbidden",
    match = ["git checkout -- ."],
)

# rm -rf を禁止
prefix_rule(
    pattern = ["rm", "-rf"],
    decision = "forbidden",
)

decision の種類

動作 用途
forbidden 完全に禁止 破壊的コマンド
prompt 実行前に確認 注意が必要なコマンド
allow 自動で許可 安全なコマンド

config.toml の設定

# ~/.codex/config.toml

# 常に確認を求める
approval_policy = "on-request"

# サンドボックスモード(workspace-write で書き込みを制限)
sandbox_mode = "workspace-write"

設定の確認

# ルールが正しく適用されるか確認
codex execpolicy check --rules ~/.codex/rules/block_destructive_git.rules -- git restore .

Claude Code の安全設定

settings.json の基本設定

.claude/settings.json に禁止ルールを記述する。

{
  "permissions": {
    "deny": [
      "Bash(git restore:*)",
      "Bash(git checkout:*)",
      "Bash(git reset --hard:*)",
      "Bash(git clean:*)",
      "Bash(rm -rf:*)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

設定ファイルの優先順位

優先度 ファイル 用途
1(最高) .claude/settings.local.json ローカル設定(git 管理外)
2 .claude/settings.json プロジェクト共有設定
3(最低) ~/.claude/settings.json ユーザー設定

サンドボックスの有効化

{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "excludedCommands": ["docker"]
  }
}

設定が効かない問題と Hooks による回避

なぜ設定が効かないのか

調べてみると、deny 設定が無視される事例が複数報告されていた。

  • Claude Code Issue #6699: v1.0.93 で deny 設定が完全に無視される
  • Claude Code Issue #6631: Read/Write ツールの deny が機能しない
  • Codex CLI Issue #6022: AGENTS.md で禁止した git checkout が実行される

原因は様々だが、設定だけに頼るのは危険

⚠️ 注意: deny 設定はバージョンによって効かないケースが報告されている。Hooks との併用を推奨。

Hooks で確実にブロックする(Claude Code)

Claude Code の Hooks 機能を使うと、ツール実行前にスクリプトを挟める。deny 設定より確実。

.claude/hooks/block_dangerous_git.sh:

#!/bin/bash

# stdin から JSON を読み取り
json_input=$(cat)
command=$(echo "$json_input" | jq -r '.tool_input.command // empty')

# 危険なパターンをチェック
dangerous_patterns=(
    "git restore"
    "git clean"
    "git reset --hard"
    "git checkout -- "
    "rm -rf"
)

for pattern in "${dangerous_patterns[@]}"; do
    if [[ "$command" == *"$pattern"* ]]; then
        echo "BLOCKED: '$pattern' is not allowed" >&2
        exit 2  # exit code 2 = ブロック
    fi
done

exit 0  # 許可

.claude/settings.json に Hook を登録:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/block_dangerous_git.sh"
          }
        ]
      }
    ]
  }
}

Hook の動作確認

# 実行権限を付与
chmod +x .claude/hooks/block_dangerous_git.sh

# テスト(ブロックされるはず)
cat << 'EOF' | .claude/hooks/block_dangerous_git.sh
{"tool_input":{"command":"git restore ."}}
EOF
echo $?  # 2 が返れば成功

多層防御の考え方

1つの防御が突破されても、次の層で止める。これがセキュリティの基本。

対策 備考
第1層 ツールの deny 設定 効かないことがある
第2層 Hooks によるブロック より確実
第3層 チェックポイント機能 Cursor/Cline/Windsurf
第4層 こまめなコミット 最も確実

チェックポイント機能があるツール

一部の AI コーディングツールには、変更前の状態を自動保存する機能がある。

ツール 機能
Cursor 変更前に自動保存、ワンクリック復元
Cline Task 単位でスナップショット
Windsurf Cascade で変更履歴を保持

Codex CLI / Claude Code にはこの機能がない。ここが今回ハマったポイント。


作業前チェックリスト

AI エージェントに作業を依頼する前に確認すること。

必須

  • 未コミットの変更がないか確認(git status
  • 重要な変更はコミット済みか
  • 安全設定(.rules / settings.json)が有効か

推奨

  • Hooks スクリプトに実行権限があるか
  • 長時間コミットしていないなら WIP コミット
  • 重要なファイルは別途バックアップ

作業中

  • AI の実行コマンドを目視確認
  • 怪しいコマンドは即キャンセル(Ctrl+C)

まとめ

対策 効果 備考
deny 設定 効かないケースあり
Hooks deny より確実
チェックポイント機能 Cursor/Cline/Windsurf のみ
こまめなコミット 最も確実

AI コーディングエージェントは便利だけど、過信は禁物

設定を入れても効かないことがある。チェックポイント機能がないツールもある。結局、こまめにコミットする習慣が一番の防御になる。

実務での使い分けのポイント:

  1. 設定ファイルだけに頼らない → Hooks と併用
  2. チェックポイント機能がないツール(Codex CLI / Claude Code) → より慎重に
  3. 長時間の作業 → 30分ごとに WIP コミット
  4. 迷ったら → こまめにコミット

今回の失敗で「数日コミットしてなかったな」と気づいたときにはもう遅かった。


参考文献

本記事は以下の情報源を参考に、筆者の実務経験を加えて執筆しました。

公式ドキュメント

GitHub Issues

データ消失の報告

設定が効かない問題


最後まで読んでいただきありがとうございました!
質問やフィードバックがあれば、コメントでお知らせください。

1
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
1
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?