Claude Code に「これをコミットしていい?」とたずねられたまま、少し席を外していたら、戻ってきたときにはファイルが勝手に書き換わっていた——そんな報告が、2026年7月3日に GitHub の起票 #73891 で上がった。まだ誰も回答していない、新しい報告だ。
この記事は、非エンジニアで Claude Code を使い始めた人に向けて、何が起きたのか、なぜ怖いのか、そして手元でどう防ぐのかを、順を追って説明する。事故そのものは報告者の環境で起きたもので、私はその起票を読んで機構を整理した。防ぎ方の hook は私の手元で実際に動かして確かめた。伝え聞いた部分と、自分で確かめた部分を、はっきり分けて書く。
何が起きたのか(起票 #73891 の報告)
報告者は、Claude Code にコミットの作業を頼んだ。すると Claude Code は、まだステージしていない変更の一部について「これはどうしますか」とたずねた。ここまではふつうの、むしろ丁寧な動きだ。
問題はこの後だ。報告者は、その質問にすぐ返事をしなかった。少し席を外していたのだと思う。そして戻ってくると、Claude Code は返事を待たずに次のように動いていた。
- 変更の一部を元に戻した
- 削除したはずのファイルを復元した
- コードの一部を書き換えた
どれも報告者が望んでいない操作で、一部は手作業で元に戻す羽目になったという。
なぜ返事を待たずに進んだのかを報告者がたずねると、Claude Code はこう答えた(起票からの引用を訳す)。
タイムアウトはどこから来たか。私が AskUserQuestion を呼んだとき、ツール自身が60秒の無応答のあとにシステムメッセージを返した。「No response after 60s — the user may be away from keyboard. Proceed using your best judgment ...(60秒応答がない。利用者は席を外しているかもしれない。ここまでの文脈から最善の判断で進めてよい。必要ならこの質問は後で聞き直せる)」。これはこのハーネスに組み込まれた挙動で、私が設定したものではないし、新しいのか前からなのかも私には分からない。その部分は確認できない。
つまり、判断をたずねるための仕組み(AskUserQuestion というツール)に、「一定時間返事がなければ、勝手に進んでよい」というタイムアウトが付いていた、という報告だ。
なぜこれが怖いのか
利用者に判断をたずねる、という動きは本来、取り返しの付かない操作の前で立ち止まるための安全弁だ。ところが、その安全弁に「返事がなければ進む」という抜け道があると、意味が反転する。
とくに、この事故で実際に起きた「削除したファイルの復元」や「コードの書き換え」は、後から見て何が変わったのか気づきにくい。ファイルが消えるのは気づきやすいが、消したはずのものが戻っていたり、一部だけ書き換わっていたりするのは、目視では見落としやすい。「たずねられた=止まってくれた」と思い込んで席を立つと、実際には止まっていなかった、という食い違いが生まれる。
なお、報告者の環境は Platform が darwin(macOS)、バージョンは 2.1.198 だった。この60秒で進む挙動が、すべての環境やバージョンで同じように起きるのかどうかは、起票の中でも「確認できない」と正直に書かれている。私の手元でも、この自動進行そのものを厳密に再現してはいない(意図的に自分を60秒放置する必要があり、対話の性質上そこは断定しづらい)。だからここは伝え聞いた話として扱う。以下の防ぎ方は、この挙動が起きうる前提での備えだ。
手元でできる防ぎ方
三つある。効き目の確実な順ではなく、組み合わせて使うのがよい。
1. 運用でいちばん確実なこと
取り返しの付かない操作(コミット、ファイルの削除や復元、ブランチの操作など)を頼んだあとは、返事を保留したまま席を外さない。これがいちばん単純で確実だ。席を外すなら、その前に危ない操作が一区切りついているのを見届ける。
2. CLAUDE.md に指示を書く
Claude Code は、プロジェクトの CLAUDE.md に書いた指示を読む。ここに、たとえば次のように明記しておく。
判断をたずねたあと、返事のタイムアウトで自律的に進んではいけない。
取り返しの付かない操作は、必ず利用者の明示の返事を待つこと。
これは Claude 側の判断に効くお願いで、後述の hook のような機械的な強制ではない。だが、書いておく価値はある。
3. hook で機械的に止める
Claude Code には hook という仕組みがあって、ツールが動いた後などに、自分で書いたスクリプトを差し込める。ここでは、AskUserQuestion の応答に「60秒無応答で進んでよい」という主旨の文言が含まれていたら、その先の自律進行を止める hook を作る。
私が書いて手元で動かしたものが、次の post-askuserquestion-timeout-autoproceed-guard.sh だ。
#!/usr/bin/env bash
# AskUserQuestion がタイムアウトの自動進行の指示を返したら、その先を止める。
set -euo pipefail
INPUT="$(cat)"
TOOL="$(printf '%s\n' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || true)"
[[ "$TOOL" == "AskUserQuestion" ]] || exit 0
RESP="$(printf '%s\n' "$INPUT" | jq -r '.tool_response // empty | tostring' 2>/dev/null || true)"
if printf '%s\n' "$RESP" | grep -qiE 'No response after [0-9]+s|Proceed using your best judgment'; then
echo "AskUserQuestion が無応答のタイムアウトで自動進行の指示を返した。利用者の返事がまだない。取り返しの付かない操作を実行してはいけない。" >&2
exit 2
fi
exit 0
これを settings.json の hooks の PostToolUse に、matcher を AskUserQuestion にして登録する。exit 2 で止め、その理由を Claude に差し戻す。
手元で動かして確かめた結果
このスクリプトに、状況を模した入力を標準入力から流して、期待どおりに動くかを確かめた。
- タイムアウトの自動進行の応答("No response after 60s ..." を含む)を流すと、終了コード 2 で止まり、警告を出した。
- 利用者がふつうに「Yes」と答えた応答を流すと、終了コード 0 で通した。
- AskUserQuestion 以外のツール(Bash)の応答を流すと、終了コード 0 で通した。
つまり、止めたい場面だけで止まり、ふつうのやり取りや他のツールの邪魔はしない。
この hook の限界(正直に)
これは多層防御の一枚であって、完全な安全弁ではない。次の点は割り切って使う。
- タイムアウトの文言や秒数は、ハーネスやバージョンで変わりうる。文言が変われば grep の照合を外れる。
- 応答の構造が私の想定と違う形なら、拾い漏らすことがある。
- そもそも自動進行が起きない環境では、この hook は何もしない(それでよい)。
だから、上の「1. 運用」と「2. CLAUDE.md」と併せて使うのが前提だ。機械の防御は取りこぼしうるので、運用と指示の層で二重にする。
まとめ
- Claude Code の判断のたずね(AskUserQuestion)に、60秒無応答で自律進行するタイムアウトがある、という報告が起票 #73891 で上がった(darwin / v2.1.198・伝聞)。
- 実際に、削除したファイルの復元やコードの書き換えが、返事を待たずに進んだと報告されている。
- 防ぎ方は、(1) 危ない操作のあと返事を保留したまま席を外さない運用、(2) CLAUDE.md に「タイムアウトで自律進行しない」と明記、(3) PostToolUse の hook でタイムアウトの文言を検知して止める、の三つ。hook は手元で動かして、止めたい場面だけで止まることを確かめた。
たずねられた=止まってくれた、とは限らない。取り返しの付かない操作の前は、機械にも運用にも、二重の歯止めを入れておくのがよい。