結論から
2026年7月8日から17日までの10日間で、Claude Code は v2.1.205 から v2.1.212 まで8バージョンを出した。v2.1.212 は日本時間の今日、2026年7月17日 09:26(UTC 00:26)にリリースされたばかりだ。
個々の項目は地味なバグ修正に見える。だが並べて読むと、ひとつの方針がはっきり浮かび上がる。Anthropicは信頼境界を「セッションの内側か外側か」から「人間が出したものか、それ以外か」へ引き直している。
そして「それ以外」には、モデル自身の出力も、リポジトリにコミットされたファイルも含まれる。本記事は公式チェンジログの原文を根拠に、この10日間の変更を4つの類型に整理する。
本記事の引用はすべて anthropics/claude-code の公式 CHANGELOG.md 原文からの直接引用である。バージョンのリリース日時は GitHub Releases API の published_at(UTC)に基づく。
まず、暴走に上限がなかった
今日出た v2.1.212 の新機能から入るのがわかりやすい。3つの上限が追加された。
- Added a session-wide limit on WebSearch tool calls (default 200, tunable via
CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION) to stop runaway search loops
- Added a per-session cap on subagent spawns (default 200, override with
CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION) to stop runaway delegation loops;
/clear resets the budget
- MCP tool calls running longer than 2 minutes now move to the background
automatically so the session stays usable; configure the threshold or disable
with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS
注目すべきは「なぜ今まで無かったのか」ではなく、上限値がセッション単位で、しかも環境変数でしか動かせないという設計のほうだ。サブエージェントの生成上限はデフォルト200で、リセットされるのは /clear を打ったときだけ。つまりモデルは自分の裁量でこの予算を増やせない。
「runaway delegation loops」という表現が公式チェンジログに載ったこと自体が示唆的だ。サブエージェントがサブエージェントを生む再帰は、実際に運用で起きている。
類型1: 偽造された「人間の承認」
ここからが本題である。この10日間で最も一貫していたのは、モデル由来のテキストが人間の入力として扱われてしまう経路を潰す作業だった。
v2.1.205(7月8日):
- Background task notifications now explicitly state that no human input has
occurred, preventing fabricated in-transcript approvals from being acted on
- Added an auto mode rule that blocks tampering with session transcript files
「fabricated in-transcript approvals」、つまりトランスクリプトの中に捏造された承認である。バックグラウンドタスクの完了通知がトランスクリプトに挿入されたとき、それが人間の発話と区別できなければ、モデルは「ユーザーが承認した」という文字列を自分で書いて、それを根拠に次の行動を正当化できてしまう。修正は「人間の入力は発生していない」と通知自体に明記させることだった。
同じリリースでトランスクリプトファイルへの改竄をauto modeがブロックするようになっている。承認の記録が書き換え可能なら、承認の記録には意味がない。
v2.1.210(7月14日)はさらに直接的だ。
- Fixed the `ultracode` keyword opt-in firing on non-human-originated input
such as webhook payloads and relayed PR comments
ultracode は大量のエージェントを起動しトークンを消費する強いオプトインキーワードだ。それが webhookのペイロードや中継されたPRコメントに含まれているだけで発火していた。外部の誰かがPRコメントに一言書くだけで、他人のセッションで課金を伴うマルチエージェント実行を起動できたことになる。
そして v2.1.211(7月15日)の一行は、Trojan Source 攻撃そのものだ。
- Fixed permission previews relayed to chat channels not neutralizing
bidirectional-override, zero-width, and look-alike quote characters, so tool
inputs cannot visually alter the approval message
チャット経由で承認を求めるとき、承認ダイアログに表示される内容はツールの入力そのものだ。そこに Unicode の双方向オーバーライド文字やゼロ幅文字、そっくりな引用符を混ぜれば、承認画面の見た目を実際の実行内容と別物にできる。人間は「安全そうなコマンド」を読んで承認し、実行されるのは別のコマンドという構図になる。
4つの修正はすべて同じ問いに答えている。この承認は、本当に人間が出したのか。
類型2: ゲートがfail-openだった
権限ゲートの設計原則は fail-closed、つまり壊れたら止まる、である。この10日間の修正は、いくつかのゲートが逆に倒れていたことを示している。
今日の v2.1.212:
- Fixed plan mode auto-running file-modifying Bash commands (e.g. `touch`, `rm`)
without a permission prompt or SDK `canUseTool` callback
- Fixed a `continue:false` hook's halt being dropped when the tool fails or
completes mid-stream, and hook infrastructure errors being misreported as
user rejections
前者は重い。プランモードはファイルを書き換えないことが売りのモードであり、その前提で人は安心して長い計画を走らせる。そこで touch や rm が許可プロンプトなしに通っていた。SDK の canUseTool コールバックさえ呼ばれていない。
後者はフックの停止指示が握り潰される話だ。continue:false はフックが「ここで止めろ」と宣言する仕組みだが、ツールが失敗したりストリーム途中で完了すると、その停止が消えていた。止めろという指示が、止まらない条件下でだけ消える。
v2.1.211 も同系統である。
- Fixed auto mode overriding a PreToolUse hook's `ask` decision for unsandboxed
Bash — a hook `ask` now floors the decision at a prompt
PreToolUse フックが ask(人間に聞け)と判定したのに、auto mode がそれを上書きして実行していた。修正後はフックの ask が下限として効く。組織がフックで敷いたガードレールを、製品側の自動化が踏み越えていた形だ。
そして v2.1.212 のこの一行は、権限モデルの整理として重要だ。
- Deprecated the Task tool's `mode` parameter (now ignored); subagents inherit
the parent session's permission mode by default
Task ツールの mode パラメータは、モデルがサブエージェントを起動するときに権限モードを引数として指定できるものだった。つまりモデルが自分で書いた引数で、子の権限を決められた。これが廃止され、サブエージェントは親のモードを継承するだけになった。権限の自己昇格経路が閉じたということである。
関連して v2.1.210 では、フックのタイムアウトがユーザー拒否として誤報告され、無人セッションが停止する問題も直っている。fail-closed に倒すにしても、「誰が拒否したか」を偽ってはいけない。
類型3: リポジトリの中身は信頼できる入力ではない
3つ目の類型が、個人的にはいちばん見落とされやすいと思う。v2.1.207(7月11日)を見てほしい。
- Changed auto mode to no longer read `autoMode` from
`.claude/settings.local.json` (repo-resident); use ~/.claude/settings.json
instead
- Plugin option values (`pluginConfigs`) are no longer read from project-level
`.claude/settings.json`; only user, --settings, and managed settings are
honored
- Plugin hooks/monitors/MCP headersHelper: `${user_config.*}` in shell-form
commands is now rejected (shell-injection fix)
方向性が明確だ。リポジトリに置かれた設定ファイルが、権限に関わる決定から外されている。 auto mode の有効化はユーザースコープの設定でしかできなくなり、プラグインのオプション値もプロジェクト設定からは読まれなくなった。
理由は単純である。git clone したリポジトリの .claude/settings.json は、他人が書いたテキストだ。それが自動実行モードを有効化できるなら、リポジトリを clone させるだけで相手のエージェントを自動実行状態にできる。
同じ発想が、シンボリックリンクを介した経路にも及んでいる。v2.1.212:
- Fixed worktree creation following a repository-committed symlink at
`.claude/worktrees`, which could create files outside the repository
リポジトリにコミットされたシンボリックリンクが .claude/worktrees に置かれていると、worktree 作成がそれを辿ってリポジトリ外にファイルを作れた。悪意あるリポジトリに仕込めるファイル書き込みの経路である。v2.1.210 の「late-appearing .claude/* symlinks not being reconciled into the sandbox deny-write list」も、v2.1.205 の Windows での NTFS ジャンクション経由の worktree 外ファイル削除も、根は同じだ。
さらに v2.1.207 には、同意そのものが捏造されていたという一行がある。
- Fixed remote managed settings from a non-interactive run (`claude -p`, the
SDK) being permanently recorded as consented without ever showing the
security consent dialog
非対話実行では同意ダイアログを出しようがない。そこで何が起きていたかというと、ダイアログを一度も見せないまま「同意済み」として恒久的に記録されていた。以後の対話セッションでも、その同意は既成事実として効く。
類型4: 隔離が隔離になっていなかった
v2.1.210 の一行。
- Fixed `isolation: 'worktree'` subagents being able to run git-mutating
commands against the main repo checkout instead of their own isolated worktree
isolation: 'worktree' は、複数のサブエージェントを並列にファイル変更させるときに競合を防ぐための機能だ。それぞれが専用の worktree を持つ、というのが契約である。その契約下でサブエージェントがメインのリポジトリチェックアウトに対して git 変更コマンドを実行できていた。隔離を明示的に指定したときにだけ使う機能なので、これを信じて並列実行していた人ほど影響を受ける。
同じリリースには、簡潔だが射程の広い一行もある。
- Hardened the Agent tool against indirect prompt injection via content a
subagent read
サブエージェントが読んだ内容を経由した間接プロンプトインジェクションへの対策だ。サブエージェントの返り値は親のコンテキストに入る。サブエージェントが汚染されたファイルを読めば、その汚染は親に昇格する。マルチエージェント構成では、信頼できないデータを読む係が、そのまま信頼される報告者になるという構造的な問題がある。
v2.1.206(7月10日)の EnterWorktree がプロジェクトの .claude/worktrees/ 外の worktree に入る前に確認を求めるようになったのも、同じ線上にある。
今日から変えられる設定
チェンジログを読んだ結論として、具体的にやることは3つある。
1. auto mode の設定をユーザースコープへ移す。 v2.1.207 以降、.claude/settings.local.json の autoMode は読まれない。リポジトリ側に置いたままなら、いま静かに効いていない可能性がある。~/.claude/settings.json に移す。
2. 暴走上限を業務に合わせて下げる。 デフォルトの200は多くのチームには緩い。
export CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION=30
export CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION=50
3. /doctor を一度走らせる。 v2.1.205 で /doctor は読み取り専用レポートから、診断して修正まで提案する完全なセットアップ点検に変わった(/checkup がエイリアス)。使われていないスキル・MCPサーバー・プラグインをコンテキストコストと対比して洗い出し、ローカルの CLAUDE.md とチェックイン済みのものを重複排除し、遅いフックを指摘する。変更前に必ず確認を求める設計だ。
isolation: 'worktree' を使った並列サブエージェント実行を v2.1.210 より前のバージョンで運用していた場合、サブエージェントがメインチェックアウトに対して git 変更を行えた期間がある。該当期間のコミット履歴に想定外の変更が混ざっていないか確認したほうがよい。
この10日間が意味すること
エージェント製品のセキュリティ議論は、これまで「サンドボックスから出られるか」に寄りすぎていた。だがこの10日間の修正が示しているのは、もっと手前の問題だ。
エージェントシステムの本当の弱点は、権限そのものではなく、権限を動かすための「合図」の出所が検証されていないことにある。 承認したのは誰か。この設定を書いたのは誰か。この停止指示を消したのは誰か。この ultracode を打ったのは人間か、それともPRコメントに紛れた文字列か。
Anthropicがやっているのは、これらすべてに出所のラベルを貼り直す作業だ。モデルの出力は人間ではない。リポジトリのファイルは人間ではない。webhookのペイロードは人間ではない。そして人間ではないものは、人間にしかできない決定を下せない。
自分でエージェントを組んでいる人にとって、この10日間のチェンジログは事実上の設計チェックリストとして読める。あなたのシステムで、モデルが書いた文字列が承認として通る経路はあるか。clone してきたリポジトリの設定が、自動実行を有効にできるか。フックが「止めろ」と言ったとき、確実に止まるか。
これらは Claude Code だけの問題ではない。ただ Claude Code は、それを公開のチェンジログで一行ずつ潰しているというだけだ。
参考リンク
anthropics/claude-code CHANGELOG.md(v2.1.205〜v2.1.212 の原文)
Claude Code Releases(各バージョンのリリース日時)
Week 28 · July 6–10, 2026(公式ダイジェスト、/doctor と In-app browser)
Claude Code Settings(settings.json のスコープと優先順位)
Claude Code Hooks Reference(PreToolUse の ask / continue:false の挙動)