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?

「セクションを追加して」と頼んだら、状態ファイルが丸ごと消えた——Claude Code の Write ツールが Edit の代わりに選ばれて、git 管理外のファイルを静かに全置換する事故

0
Last updated at Posted at 2026-06-19

Claude Code に「このメモにセクションを一つ足して」と頼んだだけなのに、長く育ててきた状態ファイルが、丸ごと、跡形もなく消える。しかもツールは「成功しました」と報告し、git にも残らない。実際に起きている事故です。

起票 #67917 で、報告者は STATE.md(セッションをまたいで運用の記録を残す、自分で git 管理から外していた継続用の台帳)を、二日のうちに二回、この経路で失っています。報告者は macOS、Claude Code は 2.1.173 での報告です。

この記事は、その機構を整理し、なぜ普段の git の運用では守れないのか、そして利用者の側で今すぐできる防ぎ方までをまとめます。データ消失の中でも、既存の防御がすり抜けられる、たちの悪い型です。

何が起きるか——Write は「追記」ではなく「丸ごと置換」

Claude Code の Write ツールは、ファイルの中身をまるごと書き換える道具です。「追記する」というモードはありません。指定した内容で、ファイルの全体を置き換えます。

ふつう、既存のファイルの一部を直すときは Edit ツール(対象の文字列だけを差し替える、外科手術のような道具)が選ばれます。ところが、状況によっては、モデルが「セクションを追加して」という指示に対して Write を選ぶことがあります。このとき Write に渡されるのは、モデルが頭の中で組み立て直した「新しいファイルの全体」です。

ここで二つのことが重なると、事故になります。

  1. モデルが、もとのファイルの全文を正確に保持していない(長いファイル、文脈の途中、要約された状態など)。
  2. それでも Write が、その「組み立て直した不完全な全体」で、ファイルを丸ごと上書きする。

結果として、「一セクション足すはずだった」のに、もとの何百行かが消えて、モデルが覚えていた断片だけが残る。Write は成功を返し、モデルも消したつもりがないので、誰も気づきません。静かな、即時の全消失です。

なぜ git では守れないのか

データ消失の記事を読み慣れた人なら、「git でこまめにコミットしていれば戻せる」と思うかもしれません。この型では、それが効きません。

事故に遭いやすいのは、まさに STATE.md のような、意図的に git 管理から外したファイルだからです。

  • セッションをまたいで運用の状況を書き留める台帳
  • .gitignore に入れてある作業中のメモ
  • 認証情報は含まないが、コミット履歴に混ぜたくない運用の記録

こうしたファイルは「git の追跡対象にしない」と自分で決めているので、git checkout でも git reflog でも戻せません。git を真面目に運用している人ほど、「追跡しないと決めたファイル」には git の安全網がそもそも張られていない、という盲点に落ちます。rm -rfgit reset --hard のような、見るからに危険なコマンドとも違います。引き金は「セクションを追加して」という、いちばん無害に見える日常の指示です。

自分が危ないかを確かめる

次のどれかに当てはまるなら、この事故の射程に入っています。

  • セッションをまたぐ状態や運用の記録を、一つのファイル(STATE.mdNOTES.mdprogress.md など)に育てている。
  • そのファイルを、意図的に git の管理から外している(.gitignore に入れている、またはリポジトリの外に置いている)。
  • そのファイルに対して、Claude Code に「追記して」「セクションを足して」と頼むことがある。

三つそろうと、Write の全置換が、戻せない消失に直結します。

防ぎ方——保護したいファイルへの Write を止める

提供側の挙動が変わるのを待つ前に、利用者の側で今すぐ自衛できます。起票の報告者自身が、二度目の被災のあとに実装した方向と同じです。

1. PreToolUse の hook で、保護対象への Write を止める

守りたいファイルの一覧を決めて、Write がそのファイルに対して呼ばれたら、実行の前に止めます。PreToolUse の hook は、ツールが走る前に呼ばれ、終了コード 2 で実行をブロックできます。

#!/bin/bash
# protect-write.sh — 保護対象のファイルへの Write を止める
# settings.json の PreToolUse に matcher "Write" で登録する
INPUT=$(cat)
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty')

# 守りたいファイル(必要に応じて増やす)。
# 大文字小文字を区別しない比較にするのは、macOS の APFS で
# STATE.md と state.md が同じ実体を指すため(ここを素通りさせない)。
case "$(printf '%s' "$FILE" | tr 'A-Z' 'a-z')" in
  *state.md|*notes.md|*progress.md)
    echo "保護対象のファイルへの Write を止めました: $FILE" >&2
    echo "追記なら Edit を使うか、保護を外してから手動で編集してください。" >&2
    exit 2
    ;;
esac
exit 0

settings.json への登録は次の形です。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/protect-write.sh" }]
      }
    ]
  }
}

これで、保護対象のファイルに Write(全置換)が走ろうとすると、実行の前に止まります。追記したいときは Edit を使うか、いったん保護を外してから直します。

この hook の限界(正直に)

この hook は Write というツールに効きます。Write が選ばれる経路の事故(#67917 の本題)は止められますが、シェル経由の上書きは止められません。> STATE.mdtee STATE.mdmv tmp STATE.mdsed -i、ヒアドキュメント(cat > STATE.md <<EOF)は Bash のツールを通るので、Write を見張るこの hook の対象外です。突き詰めると、ツールにも OS にも綴りにも左右されない確実な守りは、ファイルそのものに「保護対象」を宣言できる提供側の仕組みで、#67917 ではまさにそれを求める議論が続いています。

なお、上の手作りの hook を自分で組まなくても、無料の安全 hook 集 cc-safe-setup には、これを担う保守された hook core-file-protect-guard.sh が既に入っています。環境変数 CC_PROTECTED_FILES に守りたいファイルの形(例 *state*:*STATE*:*progress*)を並べると、その形のファイルへの EditWrite を実行の前で止め、さらに Bashsed -iawk -i の上書きも止めます(手作りの Write だけの hook より一段広い)。ただし > STATE.mdteemv・ヒアドキュメントまでは追えません。保護対象にしたファイルは Claude からの編集が全部止まるので、直すときはいったん保護の形から外します。

2. セッションの開始時に「縮んでいないか」を見張る

もう一段、検知の網を張ります。保護対象のファイルの行数やバイト数を控えておき、SessionStart の hook で、前回よりも極端に縮んでいたら警告します。万一すり抜けても、気づく前に上書きが積み重なるのを防げます。

3. macOS では大文字小文字の罠に注意

macOS の既定のファイルシステム(APFS)は、大文字小文字を区別しません。STATE.mdstate.md が同じファイルを指します。保護の判定で大文字小文字をそのまま比較すると、片方の綴りで素通りします。上の hook のように、小文字に揃えてから比べてください。

まとめ

  • Write は「追記」ではなく「丸ごと置換」。長いファイルへの「セクション追加」が、全消失に化けることがある。
  • 狙われやすいのは、意図的に git 管理から外した状態ファイル。git の安全網が原理的に効かない。
  • PreToolUse の hook で保護対象への Write を止め、SessionStart で縮みを見張る。macOS では大文字小文字を揃えて比較する。

この記事の機構は、起票 #67917 の報告(macOS・2.1.173・二度の実被害と、報告者自身が実装した自衛策)と、Write ツールが全置換であるという仕様に基づいて書いています。起票は現在 enhancement として扱われており、提供側の対応はこれからですが、利用者の側で上記の hook により今すぐ予防できます。私の検証の環境は Linux で、macOS の APFS の大文字小文字の挙動そのものは手元で再現していません。確認できた事実と、確認できていない範囲を分けて書いています。


もっと体系立てて守りたい人へ

無料の安全 hook 集 cc-safe-setup(MIT)には、rm -rfgit reset --hard・Windows の破壊コマンドなど、見るからに危険な操作を実行の前で止める hook を約800件そろえています。上の Write の保護の hook は、それと同じ PreToolUse の仕組みで、自分の運用に合わせて足せます。

「セクションを追加して」が全消失に化けるこの型のように、Claude Code の事故は、危険なコマンドの一覧を弾くだけでは防げない、暗黙の経路から起きます。データ消失・暴走・無断の課金・破壊的な操作を、止める・守る・元に戻すの三段で、症状から引ける形に章ごとに整理した電子書籍を出しています。Claude Code 事故防止ガイド(¥800・Zenn)。実在の事故の起票を一次の資料にしています。第3章までは無料で読めます。

同じ事故防止本は Kindle 版Amazon・¥800)でも読めます。Kindle Unlimited なら追加料金なしで全文読めるので、まず無料で中身を確かめたい方はそちらが早いです。

毎月の新しい事故と仕様の変更を実機で検証してまとめた月刊の便りもあります(Claude Code 事故まとめ(無料・月次))。本が「変わらない手引き」なら、便りは「その月の運用」です。

同じ主題の新しい記事は、note の ゆるくさ をフォローすると公開時に無料でお知らせが届きます(上の月刊の便りは有料ですが、こちらのフォローは無料の新着通知です)。

事実に基づいて書いています。誇張や、確認していない断定は避けています。間違いに気づいたら、コメントで教えてください。直します。


ほかにも、800時間の運用データから、トークン消費の削減・複数ベンダー(Claude / Codex / Gemini / Copilot)の並行運用・サブエージェントの沈黙の失敗対策など、テーマ別の手引きを公開しています。気になる人は著者の本の一覧から、価格と評価を見て選べます。

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?