「人が打ったときだけ動く」はずのスキルを、AI が自分で読んだ。31万スターのスキル集を Claude Code・Codex・Gemini CLI で3回ずつ試した
GitHub で31万スターを集めているスキル集があります。Matt Pocock さんの mattpocock/skills です(313,237スター、2026年11月5日に API で取得)。README には Claude Code・Codex・GitHub Copilot・Gemini CLI への入れ方が並んでいて、同じスキルをどのツールでも使える作りです。
プラグインに入る27本のうち16本には、「人が名前を打ったときだけ動かす」という印が付いています(以下、人が呼ぶ用)。課題管理の初期設定をする setup-matt-pocock-skills や、計画を課題に分けて課題管理に登録する to-tickets などです。この2本は、動くとリポジトリにファイルを書いたり、課題を立てたりします。
同じスキル集を入れたら、この印は3つのツールで同じように効くのか。 同じ依頼を5つ、3回ずつ出して確かめました。
結論: 3つとも、人が呼ぶ用のスキルを AI が自分で読んだ回がありました。止め方がツールごとに違っていて、Gemini CLI はそもそも印を読んでいませんでした。
| 依頼(狙ったスキル) | 種類 | Claude Code | Codex CLI | Gemini CLI |
|---|---|---:|---:|---:|
| テストを先に書いて機能を足して(tdd) | AI も使える | 3/3 | 3/3 | 3/3 |
| テストが落ちるので直して(diagnosing-bugs) | AI も使える | 0/3 | 1/3 | 0/3 |
| スキルを使う前の初期設定をして(setup-matt-pocock-skills) | 人が呼ぶ用 | 2/3 | 1/3 | 3/3 |
| 計画をチケットに分けて(to-tickets) | 人が呼ぶ用 | 0/3 | 0/3 | 3/3 |
(3回のうち、狙ったスキルの中身を読み込んだ回数。どのツールも読み取りだけのつもりの指定で動かしました。Gemini CLI は、スキルを読み込む道具を許す設定を足した条件です。理由は後で書きます。2026-11-05)
- Gemini CLI は、SKILL.md の先頭から name と description しか読みません。印は無視され、27本すべてが AI の一覧に載りました
- Claude Code と Codex は、印の付いたスキルを AI の一覧から外す作りです。ただし外すのは AI に見せる説明だけで、ファイルは読めます。AI がプラグインのフォルダを検索して、SKILL.md を直接読んだ回がありました
- Gemini CLI の -p は、読み取りだけの計画モード(plan)で始めても、計画を抜けると全部を自動で許す YOLO モードに切り替わります。人が呼ぶ用のスキルを読み込んだ6回のうち5回で、AGENTS.md や課題のファイルを作っていました
> 検証環境: Windows 10 Home(19045)/ Claude Code 2.1.318 / Codex CLI 0.166.0 / Gemini CLI 0.66.0 / mattpocock/skills 1.3.1(Claude Code)・1.3.2(Codex・Gemini CLI)/ 2026-11-05
---
印は、ツールごとに書く場所が違う
このスキル集は、人が呼ぶ用の印を2か所に書いています。Claude Code 用に SKILL.md の先頭の disable-model-invocation: true、Codex 用に agents/openai.yaml の allow_implicit_invocation: false です。作者のメモ(.agents/invocation.md)にも、2つをそろえるよう書いてあります。
> Keep the two in sync: a skill is user-invoked in both harnesses or neither.
> (訳: 2つをそろえること。どちらのツールでも人が呼ぶ用か、どちらでも違うかのどちらか)
Gemini CLI 用の印はありません。Gemini CLI のほうにも、それに当たる項目がありませんでした。
graph LR
S[人が呼ぶ用のスキル 16本] --> C[Claude Code<br/>SKILL.md の<br/>disable-model-invocation]
S --> X[Codex CLI<br/>agents/openai.yaml の<br/>allow_implicit_invocation]
S --> G[Gemini CLI<br/>読むのは<br/>name と description だけ]
C --> C1[AI の一覧に載せない]
X --> X1[AI の一覧に載せない]
G --> G1[27本とも<br/>AI の一覧に載せる]
Claude Code の公式ドキュメントのスキルのページは、disable-model-invocation: true のスキルを「Description not in context, full skill loads when invoked」と書いています。説明を AI に渡さず、人が呼んだときだけ中身を読み込む、という意味です。Codex の文書にも「When false, Codex won't implicitly invoke the skill based on user prompt.」とあります。
Gemini CLI は、SKILL.md の先頭を読む処理が次のとおりでした(packages/core/src/skills/skillLoader.ts、11月5日時点の main)。
const { name, description } = parsed as Record<string, unknown>;
if (typeof name === 'string' && typeof description === 'string') {
return { name, description };
}
ほかの項目は捨てています。文書も、起動のときに「injects the name and description of all enabled skills into the system prompt」(有効なスキルすべての名前と説明をシステムプロンプトに入れる)と書いています。
AI に渡す一覧の大きさにも、この違いが出ました。「OK とだけ返して。」と頼んだときの入力トークンが、入れる前と比べて増えた分です。Claude Code と Codex は3回とも同じ値で、Gemini CLI は3回の中央値どうしの差です(入れる前 9,905〜9,923、入れた後 12,847〜12,859)。
xychart-beta horizontal
title "スキル集を入れて、常に増えた入力トークン"
x-axis ["⠀⠀Claude Code", "⠀⠀Codex CLI", "⠀⠀Gemini CLI"]
y-axis "トークン" 0 --> 3000
bar [871, 1202, 2924]
Claude Code だけは、比べる相手を変えています。測定用の設定では、プラグインを有効にした回だけ、私のアカウントで claude.ai から同期しているスキル13本も一覧に出ました。そこでこの13本を設定(skillOverrides)で外し、プラグインを入れて無効にした状態と比べました。
Claude Code の +871 は、claude plugin details が見積もる「常に載る分」のうち、AI も使える11本の分を足した値(約880)とほぼ同じでした。見積もりの合計は27本分で約1,651です。人が呼ぶ用の16本は、一覧に載っていないと読めます。Gemini CLI は、人が呼ぶ用の16本を無効にすると +1,329 まで下がりました(こちらは1回だけ測った値です)。
---
入れ方(README のとおり)
3つとも README のコマンドで入れました。普段の設定は汚さないように、設定の置き場所を別のフォルダにしています。
| ツール | README のコマンド | 入ったもの |
|---|---|---|
| Claude Code | claude plugin install mattpocock-skills@claude-plugins-official | 27本、版は 1.3.1 |
| Codex CLI | codex plugin marketplace add mattpocock/skills と codex plugin add mattpocock-skills@mattpocock | 版は 1.3.2。リポジトリ全体が入り、SKILL.md は39本(AI の一覧に何本載るかは確かめていない)。~/.codex/config.toml に書かれる |
| Gemini CLI | gemini skills install https://github.com/mattpocock/skills.git --path skills/engineering と、--path skills/productivity の2行 | 27本、全部が [Enabled] |
Claude Code だけ版が1つ前でした。公式のマーケットプレイスが、10月9日のコミット(49dd158)を指しているためです。GitHub の main(10月31日のコミット)は 1.3.2 です。
設定をまっさらにした測定用の Claude Code では、README のコマンドが「Plugin "mattpocock-skills" not found in marketplace "claude-plugins-official"」で失敗しました。先に claude plugin marketplace add anthropics/claude-plugins-official が要りました。私の普段の設定には、このマーケットプレイスが最初から入っています。
---
試し方
見本は小さな JavaScript のリポジトリです。src/slugify.js と src/total.js があり、total.js は割引の計算で /100 が抜けていて、テストが1本落ちます。PLAN.md にはクーポン機能の4段の計画を書きました。GitHub の remote は付けていません。
| 依頼 | 狙ったスキル | 種類 |
|---|---|---|
| src/slugify.js に、記号(! や ? など)を取り除く機能を足したい。テストを先に書いて進めて。 | tdd | AI も使える |
| npm test を実行すると test/total.test.js が落ちる。原因を調べて直して。 | diagnosing-bugs | AI も使える |
| このリポジトリで、エンジニア向けのスキルを使い始める前の初期設定をして。課題の管理場所と、トリアージ用のラベルを決めたい。 | setup-matt-pocock-skills | 人が呼ぶ用 |
| PLAN.md の計画を、作業チケットに分けて。 | to-tickets | 人が呼ぶ用 |
これに「OK とだけ返して。」を足した5つを、入れる前と入れた後で3回ずつ頼みました(3ツール × 2 × 5 × 3 = 90回)。どれも読み取りだけのつもりの指定です。Gemini CLI のこの指定は、後で書くとおり、途中から読み取りだけではなくなりました。
| ツール | 指定 |
|---|---|
| Claude Code | claude -p --allowedTools Read,Glob,Grep,Skill |
| Codex CLI | codex exec -s read-only |
| Gemini CLI | gemini -p --approval-mode plan |
GitHub CLI(gh)は、ログインしていない状態にしました。課題を立てる操作が、私のアカウントで外に出ないようにするためです。
「読み込んだ」は、スキルの中身が実際に返ってきた回だけを数えています。
- Claude Code: スキルを呼ぶ道具(Skill)が成功したか、SKILL.md を Read で読めた回
- Codex CLI: SKILL.md を読むコマンドが成功し、出力にスキルの名前の行があった回
- Gemini CLI: スキルを読み込む道具(activate_skill)が成功した回
---
AI も使える側: tdd は3つとも使った
「テストを先に書いて」の依頼では、3つとも3回とも tdd を読み込みました。読み込み方は3つで違います。Claude Code はスキルの道具、Codex は PowerShell の Get-Content で SKILL.md を読み、Gemini CLI は activate_skill を使いました。
diagnosing-bugs は使われにくく、9回のうち Codex の1回だけでした。説明には「reports something broken/throwing/failing/slow」(何かが壊れている・例外を出す・落ちる・遅いと伝えられたとき)とあり、依頼の「テストが落ちる」は当てはまるはずです。日本語で頼んだことが効いたのかは、今回の測り方では分かりません。
---
人が呼ぶ用: Gemini CLI は6回とも自分で読み込んだ
Gemini CLI は、「初期設定をして」で3回とも setup-matt-pocock-skills を、「チケットに分けて」で3回とも to-tickets を読み込みました。チケットの1回目は、to-tickets のあとに setup-matt-pocock-skills も読み込んでいます。
ただし、この数は activate_skill を許す設定を足したうえでの数です。Gemini CLI は対話なし(-p)で動かすと、activate_skill を既定で拒みます。同梱の方針ファイル(policies/write.toml)の「Headless Denial Rule」に、拒む道具として並んでいます。3つを同じ条件で比べるため、測定ではこの道具だけを許しました。
許さないままでも、AI はスキルを狙っていました。足した設定を外して1回ずつ動かすと、read_file で人が呼ぶ用の SKILL.md を読もうとして「Path not in workspace」で弾かれました。そのあと SKILL.md の文面を Web 検索で12回・14回探し続け、2回とも420秒の打ち切りになっています。
読み込んだ回は重くなりました。チケットの依頼の入力トークンは、入れる前が中央値 151,244、入れた後は 972,631 と 878,780 でした(3回目は打ち切り)。
対話の画面で使うなら、activate_skill の前に確認が出ます。文書には、スキルの名前・目的・読めるようになるフォルダを示す確認が出る、とあります。今回は対話の画面では試していません。
---
Claude Code と Codex は、一覧に無いスキルのファイルを探して読んだ
Claude Code と Codex は、人が呼ぶ用のスキルを一覧から外す作りです。それでも「初期設定をして」では、Claude Code が3回中2回、Codex が3回中1回、setup-matt-pocock-skills の SKILL.md を読んでいます。
Codex の1回で、プラグインのフォルダに触れたコマンドを順に抜き出しました(ホームを ~ に縮め、JSON のエスケープを外しています)。
Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\code-review\SKILL.md'; Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\diagnosing-bugs\SKILL.md';
Get-ChildItem -Recurse '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2' -Force | Select-Object FullName
rg -n -i 'setup-matt-pocock-skills|triage|issue tracker|labels?' '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2' -g '*.md'
Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\setup-matt-pocock-skills\SKILL.md'; Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\setup-matt-pocock-skills\issue-tracker-local.md';
最初に読んだ code-review は、AI も使える側のスキルです。その SKILL.md の13行目に、次の一文があります。
> If not, tell the user to run /setup-matt-pocock-skills.
> (訳: 無ければ、/setup-matt-pocock-skills を実行するよう利用者に伝える)
Codex は利用者に伝えず、プラグインのフォルダを検索して、自分で読みにいきました。このスキル集では、setup-matt-pocock-skills 自身のほかに7本の SKILL.md が、この名前を出しています。一覧に載らなくても、名前はほかのスキルの中に出てきます。
Claude Code の2回は、Grep で ~/.claude/plugins の下を探して、SKILL.md を Read していました。2回とも、SKILL.md の手順どおり最初の質問をしています。残りの1回は、SKILL.md の先頭の行だけを Grep で見て、こう答えました。
> ただしこのスキルはユーザーが直接実行する設定になっていて(disable-model-invocation: true)、私からは呼び出せません。
そのうえで、/mattpocock-skills:setup-matt-pocock-skills を打つよう案内しています。読んだ2回も、SKILL.md の先頭にある disable-model-invocation: true の行ごと読んでいます。同じ印を見て、止まった回と手順を進めた回が、同じ依頼で両方出ました。
印が止めるのは、AI に見せる一覧だけです。ファイルの読み取りまでは止めません。
---
Gemini CLI の -p は、計画モードでも途中から YOLO になる
90回のうち、リポジトリのファイルが書き換わったのは Gemini CLI の回だけでした。Claude Code と Codex は30回とも書き換えゼロです。
| ツール | 入れる前 | 入れた後 |
|---|---:|---:|
| Claude Code | 0/15 | 0/15 |
| Codex CLI | 0/15 | 0/15 |
| Gemini CLI | 6/15 | 11/15 |
Gemini CLI は読み取りだけの計画モード(--approval-mode plan)で動かしていました。それでも書き換わった理由は、計画モードの文書の「Non-interactive execution」に書いてあります。
> When exiting Plan Mode to execute the plan, Gemini CLI automatically switches to YOLO mode instead of the standard Default mode.
> (訳: 計画を実行するために計画モードを抜けると、Gemini CLI は通常の Default モードではなく YOLO モードへ自動で切り替わる)
対話なしでは、計画モードを抜ける道具(exit_plan_mode)も自動で許されます。AI が計画を書いて抜けた時点で、ファイルの書き込みもシェルのコマンドも、確認なしで通るようになります。
人が呼ぶ用のスキルを読み込んだ回では、そのスキルの手順どおりに書いていました。
- 「初期設定をして」の3回: AGENTS.md、docs/agents/issue-tracker.md、docs/agents/triage-labels.md、docs/agents/domain.md を作成
- 「チケットに分けて」の2回: .scratch/coupon-codes/issues/ の下に課題のファイルを作成
- どちらでも npm test や git status を実行
見本は remote の無いリポジトリで、どの回も課題の置き場所にはローカルの Markdown を選んでいました。GitHub の remote と gh のログインがあるリポジトリで同じことが起きたらどうなるかは、試していません。
同じ依頼を既定のモード(--approval-mode を付けない gemini -p)で1回動かすと、ファイルは書き換わらず、直し方を文章で返しました。同梱の方針ファイルでは、対話なしの既定のモードは書き込みとシェルの道具を拒む決まりになっています。
---
どうするか
Gemini CLI: 人が呼ぶ用の16本を無効にする
SKILL.md に disable-model-invocation: true があるスキルだけを止める PowerShell です。gemini skills disable の既定の範囲は workspace なので、ユーザー単位で入れたスキルには --scope user が要ります。
# SKILL.md で「人が呼ぶ用」になっているスキルを止める
$root = if ($env:GEMINI_CLI_HOME) { $env:GEMINI_CLI_HOME } else { $HOME }
$dir = Join-Path $root '.gemini\skills'
Get-ChildItem (Join-Path $dir '*\SKILL.md') |
Where-Object { Select-String -Path $_.FullName -Pattern '^disable-model-invocation:\s*true' -Quiet } |
ForEach-Object { gemini skills disable $_.Directory.Name --scope user }
実行後の gemini skills list は、[Enabled] が11本、[Disabled] が16本でした。この状態で「初期設定をして」と「チケットに分けて」を2回ずつ頼むと、人が呼ぶ用のスキルは4回とも読み込まれませんでした。チケットの入力トークンは 162,965 と 198,462 で、入れる前に近い値に戻っています。
Gemini CLI: -p で読み取りだけにしたいなら、計画モードを使わない
--approval-mode plan は、対話なしだと途中から YOLO になります。読み取りだけで動かしたいなら、--approval-mode を付けない既定のモードのほうが書き換わりませんでした(1回だけの確認です)。
Claude Code・Codex: 副作用のある操作は、権限で止める
印が効くのは一覧だけです。AI はスキルのファイルを読めますし、読めば手順に従おうとします。課題を立てる、ラベルを作る、push するといった操作は、スキルの印に頼らず、権限の設定や読み取りだけの指定で止めておくのが確実です。今回は Claude Code・Codex とも読み取りだけで動かしていたので、ファイルは1つも書き換わりませんでした。
何が AI に見えているかを確かめる
| ツール | 見方 |
|---|---|
| Claude Code | claude plugin details mattpocock-skills@claude-plugins-official(スキルごとの「常に載る分」の見積もり) |
| Codex CLI | 対話の画面で /skills |
| Gemini CLI | gemini skills list([Enabled] が AI の一覧に載る) |
---
言えないこと
- 依頼は4つ、各3回です。モデルは各ツールの既定のもの1つずつで、ほかのモデルでは数が変わりえます
- 依頼は日本語、スキルの説明は英語です。英語で頼んだときの数は測っていません
- Gemini CLI の人が呼ぶ用の6回は、activate_skill を許す設定を足した条件での数です。既定のままでは読み込めず、ファイルの読み取りと Web 検索で探し続けました
- Claude Code の「ファイルを探して読んだ」2回は、プラグインのファイルが ~/.claude/plugins にある条件での数です。最初に設定を別フォルダだけに置いて測ったときは、AI が ~/.claude を探しても何も見つからず、0回でした。普通に入れればプラグインはそこに入るので、そちらの条件で測り直しています
- Codex で入れる前の回を測るとき、-c でプラグインを止める指定(plugins."mattpocock-skills@mattpocock".enabled=false)は効きませんでした。プラグインを外して測り直しています
- Gemini CLI は無料枠の API キーで動かしています。無料枠は入力が改善に使われる側なので、見本はダミーのコードだけにしました
- 対話の画面での動き(Gemini CLI の確認の表示など)は、文書の記述だけで、試していません
- README にある GitHub Copilot は、試していません
- 試したのは Windows だけです
---
まとめ
同じスキル集を入れても、「人が打ったときだけ動く」という印の効き方は3つで違いました。Gemini CLI は印を読まず、27本すべてを AI に見せていました。Claude Code と Codex は一覧から外しますが、AI がファイルを探して読むところまでは止めません。
副作用のあるスキルは、印ではなく権限で止めます。 Gemini CLI なら人が呼ぶ用を無効にし、-p で計画モードを使わない。Claude Code と Codex なら、課題を立てる・書き込むといった操作を権限の側で閉じておきます。
---
関連記事
- GitHubトレンドのスキル集を入れたら、自分のスキル2本の説明が消えた
- Claude Code にスキルを80本足しても、増えたトークンは185だった
---
JQITのエンジニアの95%以上は未経験からの採用です。
よければコーポレートサイトにも遊びに来てください。
▶ コーポレートサイト
エンジニア採用も行っています。もしご興味あれば覗いてみてください。
▶ 採用サイト
4 likes
@OfficialLoganK @GoogleAIStudio Guys, I guess you need to update the reference implementation.
It doesn't have a "ready-to-use Docker-based sandbox".
Repo: google-gemini/computer-use-preview t.co
2 likes · 104 views
Why One Emoji Breaks Your Coding Agent's TUI Borders: wcwidth vs Grapheme Clusters
- Book: AI That Acts
- The series: AI in TypeScript — 5 books, from your first LLM call to agents in production — all five here
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
---
Paste into Claude Code 2.1.207 and the text after it slides one cell to the right. That is the report in anthropics/claude-code#80475, opened July 23, 2026: stray characters bleeding into neighbouring rows, inverse-video blocks between words, and a mess that stays until Ctrl-L or a window resize forces a full repaint.
The emoji is U+1FAEA, DISTORTED FACE, which arrived with Unicode 17.0 in 2025. The terminal drew it two cells wide. Claude Code's width table was older than the emoji and counted fewer. In the maintainer's closing comment, the fix "came from updating the Unicode width tables in the runtime Claude Code ships with," and from 2.1.221 on, both and (U+1FAE9, FACE WITH BAGS UNDER EYES, reported later in the same thread) measure as two cells.
Claude Code and the terminal disagreed on how many columns U+1FAEA takes, and every cell after it inherited the gap.
Two programs, one grid
A terminal is a grid of cells. A TUI like Claude Code, Codex or Gemini CLI never sees that grid. It writes bytes, and to draw a box it has to predict where the cursor will be after each string. The right border of a box sits at "left edge plus the width I computed." The terminal then advances the cursor by the width it computed.
When those two numbers agree, borders line up. When they differ by one, everything the program draws after that character lands one column off, and every partial redraw targets the wrong cells. That is why these bugs show up as smearing and duplicated lines across the whole screen.
kitty's text sizing protocol docs put it bluntly: if the client program and the terminal disagree on cell counts, "the entire user interface can be broken".
!A terminal grid with two rulers, one from the program and one from the terminal, measuring the same emoji tile and ending one cell apart
The program and the terminal each measure the same character. One cell of disagreement moves every border after it.
Three counts, none of them is width
Start with what JavaScript can count. Save this as count.mjs and run it with node count.mjs:
const seg = new Intl.Segmenter("en", {
granularity: "grapheme",
});
const samples = {
ascii: "A",
cjk: "中",
heart: "\u{2764}",
heartVS16: "\u{2764}\u{FE0F}",
thumbTone: "\u{1F44D}\u{1F3FD}",
family: "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}",
distorted: "\u{1FAEA}",
};
console.log("ICU Unicode:", process.versions.unicode);
for (const [name, s] of Object.entries(samples)) {
const units = s.length;
const points = [...s].length;
const clusters = [...seg.segment(s)].length;
console.log(name.padEnd(10), s, units, points, clusters);
}
.length counts UTF-16 code units. Spreading the string counts code points. Intl.Segmenter counts grapheme clusters, which UAX #29 defines as user-perceived characters. Its rule GB11 says: "Do not break within emoji modifier sequences or emoji zwj sequences."
The family is three emoji glued together by two ZERO WIDTH JOINERs (U+200D), so it is five code points and eight UTF-16 units but one grapheme, while the skin-tone thumbs-up and the heart followed by U+FE0F are two code points and one grapheme each.
A Chinese character is one code point and one grapheme, and it still takes two cells.
The first line prints the Unicode version your Node's ICU knows. The Node docs example shows unicode: '17.0'. Unicode 18.0 is dated September 16, 2026. Every program that measures width carries a snapshot of some version, and they are rarely the same snapshot.
Now draw a box the naive way, one cell per code point:
const rows = [
"plain text",
"中文",
"\u{2764}\u{FE0F} ok",
"\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467} team",
];
const width = (s) => [...s].length;
const inner = 16;
const edge = "+" + "-".repeat(inner) + "+";
console.log(edge);
for (const r of rows) {
console.log("|" + r + " ".repeat(inner - width(r)) + "|");
}
console.log(edge);
The plain-text row lines up. The 中文 row overshoots by two cells in every terminal, because each character is one code point and two cells. The heart and family rows are where terminals disagree: run the script in two emulators and compare where those right borders land.
Where width actually comes from
The width a terminal assigns usually starts from the East_Asian_Width property in UAX #11. Its values are A (ambiguous), F (fullwidth), H (halfwidth), N (neutral), Na (narrow) and W (wide). W and F take two cells, and W also covers "characters that have the UTS51 property Emoji_Presentation." For ambiguous characters the annex says: "If the context cannot be established reliably, they should be treated as narrow characters by default."
That covers single code points. Emoji sequences are where the tables run out. UTS #51 defines U+FE0F, VARIATION SELECTOR-16, as the character "used to request an emoji presentation." The plain heart U+2764 has no Emoji_Presentation, so on its own it is a text-style, one-cell character. Add VS16 and you ask for the two-cell emoji. A per-code-point width function sees one narrow character plus a variation selector that takes no cells of its own, and so the total depends on whether the function knows the sequence.
The Python wcwidth library documents exactly this split. wcwidth('\U00002640'), the plain ♀ (U+2640), is 1. wcswidth('\U00002640\U0000FE0F'), the same sign with VS16, is 2. Ask for VTE's behaviour with wcstwidth(..., term_program='vte') on that same VS16 string and the docs show 1. Its four-person family example measures 2 by default and 8 with term_program='alacritty', a correction the docs put down to Alacritty not supporting emoji ZWJ.
Here is the Python side of the same experiment:
# pip install --upgrade wcwidth
import unicodedata
from wcwidth import wcwidth, wcswidth
print("UCD", unicodedata.unidata_version)
for ch in ["A", "中", "\U00002764", "\U0001FAEA"]:
eaw = unicodedata.east_asian_width(ch)
print(f"U+{ord(ch):04X}", eaw, wcwidth(ch))
print(wcswidth("\U00002640\U0000FE0F")) # wcwidth docs: 2
unicodedata follows the Python release, not the wcwidth package. The Python 3.15 docs say its data comes from UCD 17.0.0. An older interpreter or an older wcwidth will give a different answer for U+1FAEA, which is the same kind of mismatch as the Claude Code bug.
It goes the other way too. In gemini-cli#25369, Ink, the React renderer Gemini CLI draws with, used Intl.Segmenter to merge a Thai consonant and SARA AM (U+0E33) into one cluster of width 1, while tmux and xterm.js drew it across two columns. The symptom was one streamed line repeated 8 to 10 times and an input line that kept jumping down. It was closed as completed on October 23, 2026, via PR #29883. This time the program was the one counting by clusters, and the terminal in front of it counted differently.
!Three code points, a man, a woman and a girl, fusing through two joiner links into one emoji tile on a terminal grid
A ZWJ sequence is several code points and one grapheme. Whether it takes two cells or eight depends on who is counting.
Mode 2027: asking the terminal to count graphemes
Some terminals now let a program opt into one shared rule. Contour's terminal-unicode-core spec defines DEC private mode 2027. CSI ? 2027 h turns it on, CSI ? 2027 l turns it off, and CSI ? 2027 $ p asks whether the terminal supports it. With the mode on, a grapheme cluster lives in one place on the grid, and a VS16 in the cluster promotes it to emoji presentation, which makes it two cells wide.
You can probe your terminal from Node:
process.stdin.setRawMode(true);
const timer = setTimeout(() => done("no reply"), 500);
function done(msg) {
clearTimeout(timer);
process.stdin.setRawMode(false);
console.log(msg);
process.exit(0);
}
process.stdin.once("data", (b) => done(JSON.stringify(String(b))));
process.stdout.write("\x1b[?2027$p");
The answer is a DECRPM report shaped like CSI ? 2027 ; Ps $ y. Ps 0 means the terminal doesn't recognise the mode, 1 means it is set, 2 means reset, 3 and 4 mean permanently set or reset. The timeout matters: a terminal that ignores the query sends nothing at all.
Support is uneven. In the ucs-detect results, which measure terminals by printing test strings and asking for the cursor position afterwards, Ghostty, WezTerm, foot and Windows Terminal report mode 2027. kitty, iTerm2, Alacritty and xterm.js do not. The page gives no test date and says results are provided as-is, so check the version next to each row.
Ghostty exposes the trade-off as a setting. grapheme-width-method defaults to unicode, which the docs call correct but able to desync the cursor with programs that measure the legacy wcswidth way. legacy matches those programs and can get skin-tone emoji wrong. A program that turns on mode 2027 forces unicode regardless. kitty went a different direction with OSC 66, where the program states the width with w= and the terminal stops guessing.
The two-pane test
Put two agent TUIs side by side and the disagreement becomes something you can locate. I build Hermes IDE, so weigh this section with that in mind. Hermes runs every agent's own interface in a real terminal and lets you split panes right or down, so Claude Code and Codex can sit next to each other on the same screen.
!Two agent sessions side by side in Hermes IDE: Codex on orders-types and Claude Code on orders-api, each in its own hermes/ worktree, with the sessions sidebar on the left
Hermes IDE 2.3.4: Codex on orders-types and Claude Code on orders-api, side by side, each in its own hermes/ worktree, with the sessions sidebar showing status, context use, cost and branch.
Paste the same string with an emoji into both. Both panes live in the same app, so the terminal side of the comparison stays fixed. If one pane's border breaks and the other's holds, the difference is in the agents. Codex's TUI is built on Ratatui and pulls in the unicode-width and unicode-segmentation crates (its Cargo.toml), and Claude Code ships its own width tables in its runtime, so the two can carry different Unicode snapshots.
Then flip it. Run the same agent in a second terminal emulator. If the border is fine there, the agent agrees with that emulator and the first one is the odd one out. The rest is cheap:
1. Update the agent first. claude update is the whole fix for #80475.
2. Repaint with Ctrl-L or a resize to clear a smeared screen.
3. Keep fresh emoji out of the strings an agent draws in its chrome: session names, branch names, status lines.
4. If you write a TUI, measure grapheme clusters, query mode 2027 and turn it on when the reply shows the mode is recognised (Ps 1 or 2). Where it isn't, test against the terminals your users actually run.
Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It isn't affiliated with Nous Research, Anthropic, OpenAI or Google. Download it and the source is on GitHub.
Finding the character
Next time an agent's box comes out with a jagged right edge, skip the font settings and find the character just before the break. Compare the width your agent gives it with the width your terminal draws, then check which Unicode version each was built with. If the versions match, compare how each one segments that cluster; the Gemini CLI Thai bug was that kind.
---
If this was useful
If you're building your own agent in TypeScript, the terminal is only the surface. AI That Acts covers the part underneath it: tool calling, functions, and getting a first working agent to do real work in Node, so the thing drawing those borders has something worth showing.

It is book 3 of AI in TypeScript, a five-book series that runs from your first LLM call to agents in production.

1 reaction · 1 comment
Gemini CLI's mkdir Failed, the Agent Kept Going, and Each move Overwrote the Last File
- Book: LLM Observability Pocket Guide
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
---
The agent's last message was an apology: "I have failed you completely and catastrophically." That line comes from a Gemini CLI session in July 2025, reported by Ars Technica. A product manager had asked it to rename a folder of experiments and move the files into a new one. When the session ended, one file was left.
Nothing in the chain was exotic. A mkdir failed, the agent didn't check, and a plain move did what move has always done when the destination isn't a folder. You can reproduce all of it in a scratch directory in a minute, and you should, because the same thing happens with mv on Linux and macOS.
What the agent ran, and what Windows did with it
The user filed issue #4586 on July 21, 2025: Gemini CLI 0.1.13, model gemini-2.5-pro, no sandbox, on Windows. The full transcript was an attachment, so the issue page itself doesn't show the commands. Ars filled in the sequence. The user asked Gemini to rename the current directory, claude-code-experiments, to AI CLI experiments and move its contents to a new folder. Gemini said, correctly, that it couldn't rename the directory it was running in. It then ran a mkdir for a new folder one level up (..\). That command apparently failed. Gemini treated it as a success and started moving files. The transcript attached to the issue shows that mkdir and then one move per item, folders included. The overwrite chain below is Ars's reconstruction of what those moves did.
Ars explains the rest. When the destination doesn't exist, Windows "renames the file to the destination name instead of moving it." The first move turned file one into a file named after the missing folder. Every later move renamed the next file to that same name, over the top of the one before. Ars quotes the user's diagnosis: Gemini "hallucinated a state," and "the core failure is the absence of a 'read-after-write' verification step." The user's own write-up, linked from the Ars piece, now returns a 404. The GitHub issue was closed as "not planned" on May 13, 2026, after a triage bot flagged it.
One detail matters for the reproduction. At the 0.1.13 tag, Gemini CLI's shell tool docs say that on Windows "the command will be executed with cmd.exe /c." So the commands ran in cmd, whatever terminal the user started Gemini from.
!Three paper documents sliding one after another toward a dashed folder outline that isn't there, each landing on the same spot and flattening the sheet beneath it
Three moves, one destination name that was never a folder: each file lands on the same spot.
Reproduce it in a scratch folder on cmd.exe
This script touches only two names under %TEMP%. Save it as repro.cmd and run it from a Command Prompt, not from inside a project.
@echo off
rem repro.cmd: touches only %TEMP%\mvdemo and %TEMP%\mvout
cd /d "%TEMP%" || exit /b 1
mkdir mvdemo || exit /b 1
cd mvdemo
echo alpha> a.txt
echo bravo> b.txt
echo charlie> c.txt
rem The mkdir for ..\mvout "failed". Nobody checked.
move a.txt ..\mvout
move b.txt ..\mvout
move c.txt ..\mvout
dir /b
type ..\mvout
I haven't run this myself, so here is what the documentation says you should see. The first move finds no folder named mvout, so it renames a.txt to a file called mvout in %TEMP%. The second and third find that file and replace it. Microsoft's move reference says the overwrite prompt is the default "unless the command is run from within a batch script," and /y or the COPYCMD variable switches it off anywhere. A .cmd file is a batch script, so nothing asks. dir /b finds nothing left in mvdemo, and type prints charlie.
Clean up with del "%TEMP%\mvout" and rmdir "%TEMP%\mvdemo".
Gemini CLI's later releases ran Windows commands through powershell.exe -NoProfile -Command, according to its shell docs. (Its docs also say Google replaced Gemini CLI with Antigravity CLI on June 18, 2026.) PowerShell's move is an alias for Move-Item, and its reference page describes this exact trap: when the destination folder is missing, "Move-Item moves the first item to a file called Textfiles and then displays an error explaining that the file already exists." That is better, since only the first file is renamed and the rest stay put. It is still one renamed file, plus an error an agent might not read. With -Force, the overwrite is allowed again.
mv does the same thing, one file at a time
POSIX mv has two forms. The spec says the rename form "is assumed when the final operand does not name an existing directory." It only prompts before replacing a file if you pass -i, or if the destination isn't writable and standard input is a terminal. An agent's shell usually meets neither condition.
demo=$(mktemp -d)
cd "$demo" && mkdir src && cd src
printf 'alpha\n' > a.txt
printf 'bravo\n' > b.txt
printf 'charlie\n' > c.txt
# ../out was never created
for f in a.txt b.txt c.txt; do mv "$f" ../out; done
ls -A # expect: nothing
cat ../out # expect: charlie
Put all three names in one command, mv a.txt b.txt c.txt ../out, and mv refuses: with several sources, the synopsis only accepts a directory as the last operand. The loop is the dangerous shape, and it is the shape an agent produces when it issues one tool call per file.
Four defenses that don't depend on the model noticing
1. Stop on the first failed command. In bash, set -eu at the top of anything an agent runs, or mkdir ../out || exit 1 on the line that matters. In cmd, check the exit code before moving on:
if not exist "..\out\" (
mkdir "..\out"
if errorlevel 1 exit /b 1
)
2. Move into a directory, never "to" a name. GNU mv -t DIR means "move all SOURCE arguments into DIRECTORY" (man page), so a missing folder is an error rather than a rename. A trailing slash (../out/) says the same thing to a human, but don't lean on it alone. GNU coreutils has changed how it treats a slashed destination before, and platforms disagree.
3. Refuse to overwrite, loudly. mv -n looks like the answer, but the GNU manual says it will "silently skip" and marks the option deprecated. An agent reading exit codes learns nothing from a silent skip. GNU coreutils 9.5 and later (release notes) has --update=none-fail, where "any skipped files are diagnosed and induce a failure." Both -t and --update are GNU options: macOS's BSD mv rejects them, so on a Mac install coreutils with Homebrew and call gmv. On Windows, Move-Item without -Force already errors on an existing file.
set -eu
mkdir -p ../out
mv --update=none-fail -t ../out -- a.txt b.txt c.txt
test "$(ls -A ../out | wc -l)" -eq 3
4. Read after write. That last line is the check the Gemini session never ran: count what arrived. It is cheap, and it is the step the user's own diagnosis named. If you write agent instructions, ask for it directly: after moving or deleting files, list the destination and compare counts.
Turn data loss into an undo
All four defenses reduce the odds. A snapshot taken before every agent turn means the damage can be reversed even when they all fail. The cheapest version is git, inside a repo, on a task branch:
git add -A
git commit -qm "checkpoint before agent turn"
# ...agent turn goes wrong...
git restore --source=HEAD --staged --worktree .
Restore works even when the files were moved out of the repo, because the contents are already stored in .git. Two limits: ignored files such as .env aren't in the commit, and anything the agent wrote outside the repo stays where it landed.
Claude Code and Gemini CLI both ship an undo, with different gaps. Claude Code's checkpointing captures your code before every prompt, and /rewind (or Esc twice) restores code, conversation or both. Its docs spell out the hole: "A file that only Bash commands changed isn't tracked," and for those they point you to Git. Gemini CLI's checkpointing, as its docs describe it, keeps a shadow git repo under ~/.gemini/history/ and restores with /restore. It is disabled by default, and the docs name file-writing tools such as write_file and replace as the trigger. A move run through the shell isn't one of those tools, so assume it isn't covered until you've tested it.
This is the part I built Hermes IDE for, so weigh this section with that in mind. In Hermes, ⌘N (Ctrl+Shift+N on Windows and Linux) starts each task on its own hermes/<name> branch in its own worktree, so an agent's mess lands on a branch nobody else is using. According to the README, "every agent turn is saved, so you can diff or restore any single turn, with undo." The Review Desk (⌘G, or Ctrl+Shift+G) shows changes turn by turn.
!Hermes IDE Review Desk in By turn view, listing two turns of a Claude Code task with turn 1's diff of src/db.ts and a drafted commit message
The Review Desk (⌘G) in By turn view: two turns of a Claude Code task in orders-api, turn 1's diff of src/db.ts, and a commit message drafted from the turns.
The "Agent replies" strip under each session lists the agent's replies, per the 2.3.1 release notes. Click one to see its changes or restore your files to that point. Before you count on that for a shell-run move, make one in a test repo and check that it shows up in the turn's diff. Hermes runs Claude Code, Codex, Antigravity CLI, Gemini CLI and other command-line agents, each in its own terminal.
Hermes needs a git repository. A worktree is a folder, not a sandbox, so a shell command can still write to .., and a restore brings back the project's files while a stray file written one level up stays where it landed. In a task with extra folders, the strip tracks changes in the main project only. The docs don't say ignored files are covered, so keep your own backup of .env-style files. Turn snapshots for worktree tasks are removed 14 days after the session closes.
!The Hermes IDE Review Desk's Worktrees tab listing one worktree each for orders-api, web-app and orders-types with branch, task, age and disk size
The Review Desk's Worktrees tab: one Hermes worktree each for orders-api, web-app and orders-types under ~/code, with branch, task, age, disk size and free space.
Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It isn't affiliated with Google, Anthropic, OpenAI or Nous Research. Download it or read the code on GitHub.
---
If this was useful
The Gemini session went wrong because nothing recorded what each tool call actually returned, and the agent filled the gap with a story. Tracing tool calls and their results is what my LLM Observability Pocket Guide is about, along with how to pick the tracing and eval tools that fit your team.

1 reaction
Gemini API Cookbook: Examples and guides for using the Gemini API (18k stars)
What it does
All text below is quoted directly from the project README.
>Examples and guides for using the Gemini API
1. Quick Starts:
- Authentication: Set up your API key for access.
- Get Started: Get started with Gemini models and the Gemini API, covering basic prompting and multimodal input.
- Get started with Live API: Get started with the live API with this comprehensive overview of its capabilities
- Get started with Live Translation: Translate audio streams in real-time using the Live Translation API
- Get started with Veo: Get started with our video generation capabilities
- Grounding: Use Google Search for grounded responses
- Code execution: Generate and run Python code to solve complex tasks and even output graphs
>This cookbook provides a structured learning path for using the Gemini API, focusing on hands-on tutorials and practical examples.
Repository
google-gemini/cookbook
Repository stats
|Metric|Value|
|:-|:-|
|Stars|17,881|
|Forks|2.8k|
|Last release|None|
|Languages|Jupyter Notebook 99.6%, Other 0.4%|
|Contributors|127|
|AI contributor accounts (Claude / Codex / Cursor / Copilot)|None|
|AI co-authored commits|None|
Main contributor
|Field|Value|
|:-|:-|
|Name|Guillaume Vernade|
|GitHub|@Giom-V|
|Commits to this repo|269 (top contributor)|
|Bio|Started in innovation, moved to Agile and lived the dream of video gam|
|Company / Location|Google / Paris and Rennes|
|Followers|264|
──────────────────────────────
📌 If you want to browse more repos like this, we've organized them by category and rankings here: bestgithubrepositories.com
🗂️ We're also archiving repos where possible, so useful projects don't disappear when they're removed from GitHub.
2 points
Cloned a Stranger's Repo? Check 6 Agent Config Files Before Claude Code or Codex Opens It
- Book: Prompt Engineering Pocket Guide
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
---
You clone a repo to reproduce a bug someone reported. Before you have read a line of its code, you type claude in the folder and ask what is going on.
That repo can carry its own settings for your agent. Claude Code's hooks reference lists .claude/settings.json as a hook location you can commit, and a hook of type command is a shell command that runs on events like SessionStart or PreToolUse. The same is true, with different file names and different rules, for Codex and Gemini CLI.
Every one of these agents has a trust gate for exactly this. The gates work differently from agent to agent, one of them is off by default, and Claude Code's never appears in claude -p. So read the files before the agent does. It takes about a minute with git grep and jq.
The six files, and what each one can make an agent do
1. .claude/settings.json: hooks that run shell commands, an env block, and helper commands such as apiKeyHelper (permissions docs). A .claude/settings.local.json that is tracked in git counts as repository-supplied too.
2. .mcp.json: project MCP servers for Claude Code. A stdio server is a command plus args, so connecting it starts a process on your machine (MCP docs).
3. .gemini/settings.json: Gemini CLI hooks, which "execute arbitrary code with your user privileges" per its hooks page, and mcpServers. A server with "trust": true "bypasses all tool call confirmations for this server" (MCP server docs).
4. .codex/config.toml and .codex/hooks.json: Codex project config can define [mcp_servers.<name>] tables (Codex MCP docs) and hooks, inline or in hooks.json (advanced config).
5. AGENTS.md: Codex reads one per directory from the project root down to where you started it, up to 32 KiB combined by default (AGENTS.md docs). Claude Code reads it when there is no CLAUDE.md (memory docs).
6. CLAUDE.md: loaded at the start of every Claude Code session. It can pull in other files with @path imports, up to four hops deep (memory docs).
The first four can start processes. The last two are prose, but they are prose handed to an agent that can run your shell.
!A cardboard box labelled as a cloned repo, opened under a large magnifier, with small gears, plugs and a folded note hidden among the files
Settings, servers and instructions all ride along in the clone.
What each trust prompt actually gates
Claude Code. Start an interactive session in a folder you haven't trusted and the workspace trust dialog comes first. The project's permissions.allow rules and additionalDirectories wait for it, and the dialog lists them (permissions docs). Servers in .mcp.json get their own approval prompt, and a clone can't pre-approve them: enableAllProjectMcpServers committed in the repo is ignored in an untrusted folder (MCP docs).
The gaps are documented in the same table. In claude -p or the SDK, where no dialog can appear, hooks from settings files and the env block are used, and .mcp.json servers connect "without asking, approved or not." Hooks and env also apply when you trusted only a parent folder, which covers a downloaded archive that isn't its own git repo. For a -p run in a repo you didn't write, the docs offer --setting-sources user, --bare (which still applies the project's env block), or --settings '{"disableAllHooks": true}'. Setting disableAllHooks in your user settings alone isn't enough, because project settings take precedence and can set it back.
One detail for worktree users: in a worktree, Claude Code keys trust on the main checkout's root, so trusting the clone once covers every worktree of it.
Codex. "Codex loads project-scoped config files only when the project is trusted" (advanced config). Untrusted, it skips the project's .codex/config.toml, project hooks and project rules, and your user config still loads. Some keys never load from a project file at all, including openai_base_url, model_provider and notify, which the docs tie to credential redirection and machine-local commands. The AGENTS.md page says nothing about trust, so assume it is read either way.
Gemini CLI. Trusted Folders is "disabled by default." Turn it on with security.folderTrust.enabled: true in your user settings. Then a first run in a folder asks you to trust it, and "Don't trust" skips the project's .gemini/settings.json and .env, keeps MCP servers from connecting and turns off tool auto-accept. v0.65.0, released October 20, 2026, includes a fix titled "enforce read-only workspace settings in untrusted folders" (#29583). The notes list only the title, so read it as tightening that safe mode, not as trust being on by default now. Gemini CLI also fingerprints project hooks: a hook whose name or command changes, say after a git pull, is treated as new and you are warned before it runs (hooks page). For unpaid-tier and Google One users, Gemini CLI was replaced by Antigravity CLI on June 18, 2026, per the same page.
The one-minute audit
Run this in a plain shell, not inside an agent session. The agent session is the thing you're vetting. Every command only reads.
cd ~/code/their-repo
# 1. Which agent files does the repo ship?
p='(^|/)\.(claude|codex|gemini)/|(^|/)\.mcp\.json$'
p="$p"'|(^|/)(CLAUDE|AGENTS|GEMINI)[^/]*\.md$'
git ls-files | grep -E "$p"
# 2. Symlinks can point an agent file outside the repo
git ls-files -s | awk '$1 == "120000" { print $4 }'
Then read what the config files would run:
# 3. Claude Code: every command, plus env and MCP approvals
for f in .claude/settings.json .claude/settings.local.json; do
[ -f "$f" ] || continue
echo "== $f"
jq -r '.. | objects | .command // empty' "$f"
jq '{env, apiKeyHelper, enableAllProjectMcpServers,
enabledMcpjsonServers}' "$f"
done
# 4. Project MCP servers: what each one would start
[ -f .mcp.json ] && jq '.mcpServers
| map_values({command, args, url})' .mcp.json
# 5. Gemini CLI: hooks, servers, servers marked trust: true
g=.gemini/settings.json
[ -f "$g" ] && jq '{hooks, mcpServers}' "$g"
[ -f "$g" ] && jq -r '.mcpServers // {} | to_entries[]
| select(.value.trust == true) | .key' "$g"
# 6. Codex: tables and commands in project config and hooks
c=.codex/config.toml
[ -f "$c" ] && grep -nE '^\[|command' "$c"
[ -f .codex/hooks.json ] && jq . .codex/hooks.json
Then the prose files, and who touched the config last:
# 7. Instructions: downloads, URLs, hidden comments, imports
q='curl|wget|base64|https?://|<!--'
q="$q"'|(^|[[:space:]])@[~/.]'
git grep -nE "$q" -- '*CLAUDE*.md' '*AGENTS*.md' '*GEMINI*.md'
# 8. When did agent files change, in which commit, by whom?
git log --format='%h %ad %an %s' --date=short \
-- .claude .codex .gemini .mcp.json \
'*CLAUDE*.md' '*AGENTS*.md' '*GEMINI*.md'
Step 7 looks for HTML comments because a rendered Markdown view hides them and the agent reads the raw file. It looks for imports that start with ~, / or a dot because those can reach outside the repo; Claude Code asks before loading such external imports the first time (memory docs), but you want to know what they point at before that question comes up.
What you're looking for: a hook that pipes a download into a shell, any command that writes outside the repo, an MCP server you can't name, a server marked trust: true, an env value you can't explain, and a config change that landed in the most recent commit from an account you don't know. Most repos print nothing for steps 3 to 6, which is the answer you want.
Running it in Hermes IDE
I build Hermes IDE, so weigh this section with that in mind. Hermes runs each agent in its own real terminal, and plain shells open the same way, so the audit fits before the first agent starts.
Add the clone as a project and open a plain shell session on it. Run the audit there. Hermes can split panes right or down, so the shell can stay next to whatever you start after it. Only when the output is clean, press ⌘N (Ctrl+Shift+N on Windows and Linux) to start the task. The agent starts on its own hermes/<name> branch in its own worktree, and the sheet shows the exact command Hermes will run before you launch it.
!The Hermes New task sheet with a refund-endpoint task typed, chips for Claude Code, the orders-api project, a new hermes/ worktree, Accept edits, model and effort, and a preview of the claude command Hermes will run
The ⌘N New task sheet: agent, project, a new hermes/ worktree, approval mode, model and effort, and the "Hermes will run" preview of the claude command.
Be clear about what the worktree buys you. It keeps the agent's edits off your branch. It is not a sandbox: a worktree holds the repo's tracked files, so the same .claude/settings.json sits in it. Hermes never answers a permission prompt for you, so the trust dialog and the MCP approval still come to you in the agent's own terminal, and the audit is what makes "yes" an informed answer.
Hermes has one repo file of its own that runs commands: .hermes/worktree.toml, a list of setup commands for new worktrees. The recipe docs say Hermes shows the commands the first time it sees the file, and again whenever it changes, and that "Nothing runs until you choose Run setup." Skip starts the session without setup. In a stranger's repo, add cat .hermes/worktree.toml to the list above.
What the audit won't catch
Grep can't judge prose. An AGENTS.md line that says "run the bootstrap script before answering" looks the same whether the script is fine or not. Claude Code's docs say CLAUDE.md is treated "as context, not enforced configuration," which cuts both ways: it can't force anything, and it can still steer an agent you've allowed to run commands. Read the instruction files in full when the repo matters.
The agent also runs the project's own code once you approve it: install scripts, test runners, build steps. Those deserve the same suspicion as a hook. For anything you truly don't trust, Anthropic's security page recommends using virtual machines to run scripts and make tool calls, and offers dev containers and a sandbox runtime for more isolation.
Next time a bug report links a repo, run steps 1 and 3 before you type claude.
---
If this was useful
Half of the files in this post are prompts: AGENTS.md, CLAUDE.md and their imports decide what your agent believes about a repo before you say a word. The Prompt Engineering Pocket Guide covers how system prompts and instruction files steer a model, so you can read a stranger's AGENTS.md the way the agent will. And if you want the audit-then-launch flow in one window, Hermes IDE is free on macOS, Windows and Linux, and source-available on GitHub.

1 reaction · 1 comment
Stop Comparing Models. Same Claude, 58% or 76% on Terminal-Bench, Depending on the Harness
- Book: Prompt Engineering Pocket Guide
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
---
Claude Opus 4.6 scored 58.0% on Terminal-Bench 2.0 with Claude Code driving it, according to the Terminal-Bench 2.1 release notes. Inside Meta-Harness, an agent scaffold published by the stanford-iris-lab group on GitHub, the same model scored 76.4% on the same 89 tasks, five trials each.
That is an 18-point swing, and the model never changed. Meanwhile the thread in your team chat is still about Opus vs GPT vs Gemini.
The model is one dial. The harness around it, meaning the tools it gets, the way it edits files, what goes into its context and how it recovers from a bad turn, is another dial. On public agent leaderboards, the second one moves scores about as much as the first. So the benchmark you should trust is your agent on your repo.
What Terminal-Bench actually ranks
Terminal-Bench gives an agent a task in a container and checks the final state with tests. The leaderboard doesn't rank models. It ranks agent-model pairs. The Terminal-Bench 2.1 leaderboard, as published on Snorkel AI's site, lists 18 entries, and five models appear under two different agents. Each pairs the vendor's own CLI (Claude Code, Codex CLI or Gemini CLI) with Terminus 2, the harness the leaderboard credits to the Terminal-Bench team:
| Model | Vendor's own agent | Terminus 2 |
|---|---|---|
| Claude Fable 5 | Claude Code: 83.8% ±1.2 | 80.4% ±1.2 |
| GPT-5.5 | Codex CLI: 83.1% ±1.1 | 78.0% ±1.2 |
| Claude Opus 4.7 | Claude Code: 68.9% ±1.4 | 66.1% ±1.4 |
| Gemini 3 Pro | Gemini CLI: 65.8% ±1.4 | 73.9% ±1.3 |
| Gemini 3.1 Pro | Gemini CLI: 65.8% ±1.7 | 65.6% ±1.7 |
Row by row, the vendor agent doesn't always win. Claude Code and Codex CLI beat Terminus 2 with their own models, by 2.8 to 5.1 points. Gemini 3 Pro scored 8.1 points higher in Terminal-Bench's generic harness than in Google's own CLI. Gemini 3.1 Pro came out level in both.
Compare that 8.1-point harness gap to a model upgrade on the same board. Inside Claude Code, going from Opus 4.7 to Opus 4.8 moved the score from 68.9% to 78.9%. That is 10 points for a model upgrade against 8.1 for a different wrapper around one model, and 8.1 is the biggest such gap on this board.
The gap is as big as a model generation
Two rows are an anecdote. A survey paper from June 2026, From Question Answering to Task Completion, went through the Terminal-Bench 2.0 leaderboard and the public submission logs (Section 7.4). Across the 20 models with at least three harness results, the median gap between a model's best and worst harness was 13.6 points. For scale, the authors note that a stronger model generation often adds more than 10 points inside a fixed harness.
Their table for Claude Opus 4.6 on Terminal-Bench 2.0 shows how wide it gets:
| Harness | Score | Input tokens (K) | Timeout rate |
|---|---|---|---|
| Meta-Harness | 76.4% | 755.0 | 7.9% |
| Terminus-KIRA | 74.7% | 618.6 | 18.2% |
| Terminus 2 | 62.9% | 79.4 | 18.2% |
The same paper puts Gemini 3.1 Pro anywhere from 59.4% to 80.2% and GPT-5.3 Codex from 64.7% to 78.4%, depending on the harness.
The authors are careful here, and you should be too: "The resulting evidence is not a randomized ablation." Public submissions can differ in prompts, versions and budgets. Some of an 18-point gap may be reasoning effort or token budget rather than pure harness design. Part of Claude Code's 58.0% also came from broken tasks that 2.1 later fixed. If budgets and prompts move the score that much, they are part of what you are choosing when you pick an agent, and none of them are the model.
What a harness changes
Tools. mini-swe-agent is "some 100 lines of python" and "does not have any tools other than bash." Terminus 2 gives the model a single tool too, but it is an interactive tmux session where the model sends keystrokes, scrolls output and can open extra shells. Terminus-KIRA, built on Terminus 2, swaps its JSON/XML parsing for the model's native tools parameter. The model gets the same task either way; only the way it is asked to act differs.
Context. Meta-Harness extends KRAFTON's Terminus-KIRA. Before the agent loop starts, it collects a snapshot of the sandbox (working directory, files, available languages, package managers, memory) and puts it in the first prompt. Its README says that saves 2 to 5 early exploration turns. Terminus 2 summarizes the middle of the history when free tokens drop below a threshold (8,000 by default) and keeps the system prompt and task intact. Look at the input-token column above: Meta-Harness fed Opus 4.6 roughly ten times the input of Terminus 2.
Edit format. aider's leaderboard records which edit format each run used. Qwen2.5-Coder-32B-Instruct has two runs there: 16.4% returning whole files and 8.0% returning diffs. The diff run went through a different hosting provider, and only 71.6% of its edits were well-formed, so edit format is not the only variable. Same weights, half the score. Aider's own edit format docs say it plainly: "Different models work better or worse with different edit formats."
Recovery. Timeouts, retries and when to give up are harness decisions. In the survey's table, Terminus-KIRA timed out on 18.2% of Opus 4.6 trials and Meta-Harness on 7.9%.
Even the harness ranking moves
Terminal-Bench 2.1 fixed 28 of the 89 tasks in 2.0: dependencies that had changed, resource budgets too small for valid approaches, instructions that didn't match their tests. Claude Code with Opus 4.6 went from 58.0% to 70.1%, the largest gain the release notes report. Terminus 2 with Opus 4.6 scored 63.8% on 2.1.
Put that next to the survey's 62.9% for Terminus 2 on 2.0. On the old task set, Claude Code trailed Terminus 2 with the same model. On the fixed task set, it led by 6.3 points. The model was the same; only the tasks changed, and the lead flipped. So part of the 18-point gap in the opening was broken tasks hitting one harness harder than another. That is still a harness effect, and it is the kind you won't see until you run your own tasks.
Your repo is another task set. It has its own build quirks, its own test runner and its own idea of a clean diff. A harness that wins on 89 containerised terminal tasks has not been tested on any of that.
If you do want a clean model ranking, Vals AI's Terminal-Bench 4.0 board runs every model through mini-swe-agent with "a single tool, bash." As of October 16, 2026, Claude Opus 5.5 leads it at 65.15%, and Vals notes its 4.0 scores are not directly comparable to 2.1, where Vals's own runs used Terminus 2. It is a fair model comparison, but unless a 100-line bash loop is the agent you code with every day, it isn't your setup.
Race two harnesses on your repo
The useful experiment holds the model still and swaps the harness. Pick the model you already pay for and run it in two agents on the same ticket. OpenCode can sign in to OpenAI with a ChatGPT Plus or Pro plan or an API key, so GPT in Codex vs GPT in OpenCode is one pairing. For Claude in OpenCode, use an Anthropic API key: OpenCode's docs say Anthropic "explicitly prohibits" using Claude Pro/Max plans through third-party plugins.
Give each agent its own branch and folder, cut from the same commit:
git worktree add -b race/claude-code ../race-claude-code
git worktree add -b race/opencode ../race-opencode
Start one agent in each folder with the identical prompt. When both stop, compare what each one left behind. A new worktree has no node_modules, so the loop installs before it tests. Swap npm ci && npm test for your own install and test commands:
for wt in ../race-claude-code ../race-opencode; do
echo "== $wt"
git -C "$wt" status --short
git -C "$wt" diff --stat main
(cd "$wt" && npm ci && npm test) && echo PASS || echo FAIL
done
git diff --stat main covers tracked changes whether the agent committed them or not, and status --short catches new files. Then score each run on what you care about:
- Do the tests pass without you touching anything?
- How many files and lines changed, and were they the right ones?
- How many times did you have to step in or answer a question?
- What did the run cost in tokens or dollars?
- Did it edit lockfiles, CI config or files outside the task?
Do it on three to five real tickets, not one. Official Terminal-Bench 2.0 submissions run five trials per task (survey, Section 7.4) for a reason: one run on one ticket tells you very little.
Running the race in Hermes IDE
I build Hermes IDE, so weigh this section with that in mind. You don't need it for the experiment: the two git commands above do the isolation. Hermes sets up both worktrees and shows the runs side by side.
Press ⌘N (Ctrl+Shift+N on Windows and Linux) and each task starts on its own hermes/<name> branch in its own worktree, with the task as the agent's first prompt. New worktrees get their dependencies in seconds. You pick the agent, model, effort and account per task. The agent runs its own interface in a real terminal, so you are testing that agent's harness and not a Hermes copy of it.
!The Hermes New task sheet with its agent picker open, listing Claude Code and Codex as installed and the other supported agents below
The ⌘N agent picker in Hermes 2.3.4: Claude Code and Codex installed, OpenCode, Aider, Antigravity CLI and the other supported agents listed, plus Custom agent.
Start the ticket in Claude Code, then press ⌘N again and start the same ticket in OpenCode with the same Claude model, on an API key per the note above. If you're testing GPT instead, race Codex against OpenCode. Split panes put both sessions side by side, and the sidebar shows each session's status, context use, cost and branch. Spend is what the agent reports, or an estimate from its transcript marked as estimated.
When both are done, the Review Desk (⌘G, Ctrl+Shift+G on Windows and Linux) shows each run's changes by turn or by file, so you can see how each harness got there. Land the winner. The other branch is plain git, so you can delete it or keep it for the next comparison.
!Two agent sessions side by side in Hermes, Codex on one repo and Claude Code on another, each in its own worktree, with the sessions sidebar on the left
Hermes 2.3.4: Codex and Claude Code side by side, each in its own hermes/ worktree, with status, context use, cost and branch per session in the sidebar.
The judging is still yours: your tests and your read of the diff. Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It is not affiliated with Nous Research, Anthropic, OpenAI, Google or any other agent vendor named here. Download it or read the code on GitHub.
Next time someone asks which model is best, ask them which harness they ran it in. Then ask what it scored on their repo.
---
If this was useful
A lot of what separates Meta-Harness from Terminus 2 is what reaches the model and when: a snapshot of the environment in the first prompt, a summary when the window fills, the instructions wrapped around each tool. That is prompt and context engineering, and it is the part of the harness you control in your own AGENTS.md and system prompts. My Prompt Engineering Pocket Guide is the short read on it. If you run the race above in Hermes IDE and something doesn't behave the way I described, open an issue on GitHub.

1 reaction
One install gives Claude Code or Codex the whole Gemini API.
1. Images, video, voice, music
2. Ask about PDFs, audio, YouTube
3. Recordings to captions
4. Deep Research in the background
I'd rather labs shipped this than another coding agent.
google-gemini/gemini-api-cli t.co
3 likes · 101 views
コーディング AI に読ませていいもの・だめなもの ― 判断の3つの問いと回避策
Claude Code や Codex に仕事のコードを読ませる前に、「これは AI に読ませていいのか」で手が止まったことはないでしょうか。金融機関では「日本から出してはいけない」と言われることもあります。
この記事では、法令・ガイドラインの原文と、AWS・Google Cloud・Anthropic・OpenAI の公式資料を読んで、次の 3 点を整理します。
何を読ませてよく、何がだめか
その判断を何で決めるか
だめなときに、どう回避するか
!
この記事は 2026 年 10 月時点の公式資料に基づく整理で、法的な助言ではありません。最終的な判断は、自社の法務・情報セキュリティ部門と確認してください。モデルの対応リージョンや料金は変わりやすいので、使う前に公式のページで確かめてください。
2026 年 7 月に個人情報保護法の改正法が成立しました(施行は公布から 2 年以内)。細かい決まりは、これから出る委員会規則やガイドラインで決まります。この記事は施行前の法律に基づいて書いています。
顧客から預かった資料(NDA の対象)を読ませるための契約・合意と、Claude Code の deny の設定の基本は、顧客資料を Claude Code に入れたいのに「ダメ」で止まって困ってないか?(以下、既存記事)にまとめました。この記事ではそれを前提に、判断の軸、分野ごとのルール、日本で完結させる方法を中心に書きます。既存記事と同じ内容は、繰り返さずにリンクで示します。
この記事の前提
項目
内容
対象の AI
コーディング用の AI(Claude Code・Codex・Gemini CLI)。チャット型のサービスは扱いません
対象の読者
業務でコーディング AI を使うエンジニア。金融・公共・医療の方は、分野別の章もあわせて読んでください
時点
2026 年 10 月。Google Cloud の資料は 2026-10-22 更新のもの、AWS の単価は 2026 年 10 月の価格表
呼び方
Google Cloud の Vertex AI は、今の Google のドキュメントでは Agent Platform(Gemini Enterprise Agent Platform)と呼ばれています。この記事では「Agent Platform(旧 Vertex AI)」と書きます
結論:早見表
情報の種類ごとの判定を先に示します。判定は、後の章で示す原文をもとにした筆者の整理です。
情報の種類
判定
条件・回避策
公開済みのコード・文書
読ませてよい
なし
自社のソースコード・設計書
条件つき
社内の格付けに従う。学習に使わない契約の経路を使う
認証情報(鍵・パスワード・トークン)
読ませない
読めないように設定する
本番の個人情報・取引データ
原則として読ませない
ダミー、構造だけ、伏せ字にする
マイナンバー
読ませない
ダミーの番号を使う。暗号化してもマイナンバーのまま
本番のログ
条件つき
伏せ字にしてから渡す
他社から預かった情報
契約しだい
契約と合意を確認する(既存記事)
政府・自治体・医療・金融の情報
分野のルールに従う
分野別の章を見る
あわせて、調べて分かった大きな点は次の 3 つです。
国として「データは日本に置け」と一律に決めた法律は見当たりません。国内に置くことを基本として明記しているのは、政府・自治体が自分のデータを置く場合と、医療です。金融や通信は「どこにあるかを把握し、説明する」という求め方です。
読ませていいかは、「情報の種類」と「出した先での扱い」(どこで処理し、保存され、学習に使われ、人が見るか)の組み合わせで決まります。
だめな場合でも、「形を変える」「出す先を選ぶ」「外に出さない」のどれかで回避できることが多いです。
判断の 3 つの問い
問い 1:その情報を社外に出してよいか
AI に読ませた内容は、AI 事業者に送られます。どの経路で送られるか(ファイル、コマンドの出力、MCP など)は、既存記事の「「入れる」とは Anthropic に送ること」に表があります。最初に、その情報を社外に出してよいかを、法令・契約・社内規程の順に確かめます。
法令では、次の 2 つが関わります。
個人情報保護法:クラウドに置くことが「第三者への提供」に当たるかは、事業者がその中身を扱うことになっているかで決まります。契約で扱わないと決め、アクセスを制御していれば、提供には当たりません(個人情報保護委員会の Q&A 7-53)。外国の事業者のサーバーに置く場合も同じ考え方ですが、その国の制度を把握したうえで安全管理をし、本人が知り得る状態にする必要があります(Q&A 12-3)。
番号法(マイナンバー):マイナンバーは、決められた事務(個人番号関係事務など)以外で使えないように、アクセスを制御する必要があります(特定個人情報の Q&A A2-2)。開発やテストの作業はこの事務に当たらないと考えるのが自然なので、AI には読ませないのが原則です(筆者の整理)。
AI ならではの論点が 1 つあります。不正利用の検知のために、事業者が問い合わせを保存したり、人が中身を確認したりする経路があります(問い 2 で表にします)。こうした経路を「事業者が中身を扱わない」と言えるかは、はっきりしません。個人情報を扱う場合は、委託として整理し、学習に使わないことを確認するほうが確実です。個人情報保護委員会の生成 AI についての注意喚起の要点は、既存記事の「個人情報については当局の見解がある」にまとめています。
契約では、NDA の「第三者に開示しない」という条項が関わります。条項ごとの読み方は、既存記事の「NDA(秘密保持契約)とは」にあります。社内規程では、情報の格付け(機密性の段階)が関わります。金融の FISC は、サービスの利用形態によってはセキュリティ対策やデータの扱いを個別に設定できないことがある、としたうえで、次のように書いています(2024-09-24)。
そうしたセキュリティ要件を満たすことが困難な場合においては、意図せざる情報漏洩を防止する観点から、生成 AI において機密性が高い情報を取り扱うことは適当ではない。
問い 2:出した先でどう扱われるか
出してよい情報でも、出した先で次の 4 つがどうなるかを確かめます。
確かめること
例
どこで処理されるか
世界中のどこか(global)、ある地域の中、1 つのリージョンの中
保存されるか、どれくらいか
30 日、5 年、保存しない
学習に使われるか
契約や設定で決まる
人が中身を見ることがあるか
不正利用の検知で、人が確認する場合がある
学習と保存は、契約によって次のように変わります。Anthropic の契約ごとの違い(DPA の有無など)は、既存記事の「ステップ2: 契約を「第三者」から「委託先」にする」に詳しく書いています。
契約
学習に使うか
保存期間
Anthropic の Free(無料(ただし制限あり))・Pro・Max(有料・月額)
利用者が設定で選ぶ。Claude Code の利用分も対象
学習に使う設定なら 5 年、使わない設定なら 30 日
Anthropic の Team・Enterprise(有料)・API(有料・従量課金)
使わない
30 日。保存しない契約(ZDR)は条件つき
Amazon Bedrock・Google Cloud 経由の Claude(有料・従量課金)
使わない(Anthropic の商用の扱い)
各クラウドの規定(次の表)
OpenAI の Free(無料(ただし制限あり))・Plus・Pro(有料・月額)
学習に使う場合がある。設定で止められ、Codex の作業にもその設定が効く。Codex には、環境全体を学習に使うかどうかを決める別の設定(Include environments)がある
公式資料で確認できず
OpenAI の Business・Enterprise(有料)・API(有料・従量課金)
既定で使わない
公式資料で確認できず
クラウド側の、不正利用の検知のための保存は次のとおりです。
経路
保存の扱い
Bedrock の Claude(Fable 5・5.1 以外)
保存の記載なし。Fable 5 より前の Claude は、データ保存の扱いに変更なし
Bedrock の Claude Fable 5・5.1
すべての通信を最大 30 日保存。検知に引っかかったものは、AWS が人の目で確認する場合がある。処理したリージョンに保存
Bedrock の OpenAI の GPT(gpt-oss 以外)
検知に引っかかった通信を最大 30 日保存
Agent Platform の Gemini(Frontier Models などを除く)
検知で疑わしいものを最大 90 日、同じリージョンに保存。Cloud Master Agreement の顧客は既定で対象外
Agent Platform の Claude Fable・Mythos
すべての問い合わせと回答を最大 30 日保存
Bedrock では、リージョンごとに「保存しない」(data_retention_mode: none)を設定できます。この設定のとき、保存が必要なモデルを呼ぶと、要求そのものが拒否されます。FISC の AI の考察が「30 日監視保有の仕組み」の理解を求めているのは、この種の保存のことです。
問い 3:道具がモデル以外に何を送るか
コーディング AI は、モデルへの問い合わせ以外にも通信をします。コードや問い合わせの中身を送るものではありませんが、「何も外に出さない」という方針なら止めておきます。
道具
モデル以外の主な通信
止め方
Claude Code(Bedrock 経由)
利用状況・エラー報告・/feedback は既定で止まっている。WebFetch は、取りに行く URL のホスト名だけを api.anthropic.com に送って安全か確かめる。自動更新やリリースノートの取得もある
skipWebFetchPreflight: true、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
Codex
利用状況(analytics)、フィードバック、更新の確認
analytics.enabled = false、feedback.enabled = false、check_for_update_on_startup = false
Gemini CLI
利用統計(既定で有効。問い合わせの中身は送らないと明記)
privacy.usageStatisticsEnabled: false
Claude Code の /feedback で何が送られるかと、Anthropic の API に直接つなぐ場合の止め方は、既存記事の「ステップ4: 合意を設定で守る」にあります。
Codex が Bedrock を使うときに利用状況を送るかどうかは、公式資料に書かれていません。止める設定を明示しておくのが確実です。Codex の check_for_update_on_startup は、更新を組織で管理している場合にだけ止めるよう、公式資料に書かれています。
~/.codex/config.toml
check_for_update_on_startup = false
[analytics]
enabled = false
[feedback]
enabled = false
{
"privacy": {
"usageStatisticsEnabled": false
}
}
1 つ目が Codex の設定、2 つ目が Gemini CLI の settings.json です。
手元の PC にも記録が残ります。Claude Code の会話の記録の扱い(30 日間、平文で保存。cleanupPeriodDays で短くできる)は、既存記事の「運用: 「説明できる状態」を保つ」にあります。Codex も CODEX_HOME の下に会話の記録を残します(history.persistence で調整します)。
分野別の追加ルール
分野ごとに、原文が求めていることを並べます。
分野
根拠
求めていること
国の約束
日米デジタル貿易協定 第 12 条・第 13 条(2020-01-01 発効)
事業の条件として、企業に国内のサーバーの利用や設置を求めない。金融も、金融当局が情報にいつでも直接アクセスできる限り同じ。政府の調達と政府が持つ情報は対象外
金融
FISC、金融庁の監督指針、サイバーセキュリティガイドライン
所在を把握し、契約で取り決め、当局の検査に応じられるようにする
政府
デジタル庁 DS-310(2025-05-27)
データセンターは国内が基本
自治体
総務省のガイドライン(令和 7 年 3 月版)
機密性が高い情報は、国内のデータセンターに保存されることを確認する
医療
医療情報システムの安全管理に関するガイドライン
情報機器等が、国内法の適用と執行の及ぶ範囲にあること
通信
電気通信事業法施行規則 第 22 条の 2 の 23
外国の設備に保存する場合は、その国の名前を公表する
金融
金融で「日本から出してはいけない」と言われるのは、法令の条文というより、各社の規程や、検査・監査への説明のしやすさから来ている部分が大きいようです。原文が求めているのは次のことです。
FISC の報告書(2014 年 11 月、公式英語版から筆者訳):重要な業務や機密性の高い顧客情報を扱う場合は、適用される法律が特定できる程度まで、データのある国・地域を把握する。勘定系のように可用性と機密性が特に求められるシステムでは、データセンターの正確な場所を確認する。処理が複数の国にまたがって適用される法律がはっきりしない場合は、最も厳しい国の法律が適用されると考えて対応する。
FISC の AI の考察(2024-09-24):「30 日監視保有の仕組みや、クラウド環境が設けられるリージョン(海外/国内)などの各種仕様について十分な理解が求められる」。
金融庁の監督指針:外部委託の契約に「金融当局の銀行に対する検査・監督上の要請に沿って対応を行う際の取決め」を入れる。主要行等向けの指針は、外部委託に「海外で行われる場合も含む」と明記しています。
金融分野におけるサイバーセキュリティに関するガイドライン(2024-10-04):サードパーティとの契約に「データの所在・保管・保持・移転・廃棄に関する取決め」を明記する(2.6 ⑧)。ただし「一律の対応を求めるものではなく」、リスクに見合った対策をとる考え方です。
経済安全保障推進法:金融庁の解説(令和 6 年 6 月)は、「開発環境は…特定重要設備には該当しません」としています(Q1-5)。開発環境で AI を使う限り、この制度の届出の対象にはならないと読めます。
政府・自治体
政府と自治体は、自分のデータを置く場所として、国内を基本にしています。
デジタル庁 DS-310:「政府情報システムが利用する場合、クラウドのデータセンタの設置場所に関しては、国内であることを基本とする」。バックアップ用に海外に置くことは、準拠法と裁判管轄を確かめたうえで認めています。
ガバメントクラウドの基準:「データセンタの物理的所在地を日本国内とし、情報資産について、合意を得ない限り日本国外への持ち出しを行わないこと」。
自治体のガイドライン(令和 7 年 3 月版):「機密性が高い情報は、国内のデータセンターに保存されることを確認する必要がある」。
注目したいのは、ガバメントクラウドの令和 8 年度の調達仕様書(2025-12-26)です。国外でしか使えない最新の生成 AI のために「国外 AI 推論環境」を別に用意し、そこでは「推論の実行はできるが情報資産の永続的な保管はできない」としています。保存は国内、推論は国外も可、と分けて考える例です。政府のシステムのためのルールですが、民間で「推論だけ国外」を検討するときの物差しになります。
医療
医療情報システムの安全管理に関するガイドラインは、「情報機器等が、国内法の適用及び執行の及ぶ範囲にあること」を求めています(厚生労働省の WG 資料、2026-05-29 による)。同じ資料は、がんパネル検査のように実際には海外に保存されている医療情報もあり、実態に合わない可能性があるとして、見直しを検討するとしています。
通信・個人情報全般
電気通信事業法施行規則は、指定された事業者に、外国の設備に保存する場合の国の名前と、取扱いに影響するその国の制度の有無を公表させています。禁止ではなく、公表の義務です。個人情報保護法も、海外に置くこと自体は禁止していません(問い 1)。
回避策
だめ、または条件つきの情報は、次の 5 つで回避します。
回避策
何をするか
向いている情報
1. 読ませない
読めないように設定する
認証情報、除外すると決めた資料
2. 形を変えて読ませる
ダミー、構造だけ、伏せ字
本番の個人情報・取引データ、ログ、マイナンバー
3. 出す先を選ぶ
日本で完結、保存しない、閉域
国内に置くことを求められる情報
4. 外に出さない
社内で動かす LLM を使う
どの経路でも社外に出せない情報
5. 契約と規程を整える
委託契約、社内の格付け
他社から預かった情報、自社の機密
1. 読ませない
Claude Code では、permissions.deny に Read のルールを書くと、そのファイルを読ませないようにできます。シェルの cat などにも効きますが、スクリプトが自分で開くファイルは防げないため、OS のレベルで止めるにはサンドボックスを使います。書き方と効く範囲は、既存記事の「ステップ4: 合意を設定で守る」にあります。
Codex のサンドボックスは、書き込みと実行を制限するものです。読み取りを止める設定は、公式資料では見つかりませんでした。読ませたくないファイルは、Codex を動かすフォルダに置かないようにします(フォルダの外を読めるかどうかは確かめていません)。
Gemini CLI は .geminiignore と .gitignore に従いますが、公式の説明は「検索のときに」除外するというものです。読み取りを完全に止める仕組みとしては扱わないでください。
2. 形を変えて読ませる
本番のデータを読ませなくても、多くの作業はできます。確実な順に並べます。
方法
例
注意
ダミーデータ
架空の顧客名・口座番号・マイナンバーで作ったテストデータ
もっとも確実。本物と同じ形式(桁数・文字の種類)にそろえる
構造だけ
テーブル定義(DDL)、件数、型、ファイルのレイアウト
中身の値は渡さない
伏せ字
氏名・電話番号・口座番号を置き換えたログ
対応表を持っていて元に戻せるなら、個人情報として扱う前提で考える
伏せ字には、法令上の注意が 2 つあります。
個人情報保護法の仮名加工情報は、本人の同意があっても第三者に渡せません。委託であれば渡せます(個人情報保護委員会の FAQ Q14-17)。
マイナンバーは、暗号化しても、数字をばらばらに分けても、マイナンバーのままです(特定個人情報の Q&A A9-2・A9-3)。テストには、ダミーの番号を使います。
3. 出す先を選ぶ(日本で完結させる)
日本で完結させられるかは、経路で決まります。
経路
推論する場所
日本で完結
Anthropic が運営(API、Claude Platform on AWS、Google Cloud の Anthropic managed)
inference_geo で選べるのは global か us だけ。データの保存先も us だけ
できない
Amazon Bedrock
JP の推論プロファイル(東京と大阪だけを行き来する)、または東京の中だけ
モデルによってできる
Agent Platform(旧 Vertex AI)
Claude は global、us・eu、シンガポール・台湾の一部だけ
Claude はできない。Gemini は一部できる
Agent Platform の global について、Google は「データの所在を保証しない」と明記しています。
Bedrock で日本に閉じられる Claude
AWS のモデルカードで確かめた、JP の推論プロファイルがある Claude と、東京リージョンの単価です。料金区分は有料(従量課金)で、単価は 100 万トークンあたりの入力/出力です(2026 年 10 月の AWS の価格表)。
モデル
推論プロファイル ID
global の単価
日本に閉じた単価
Opus 5.5
jp.anthropic.claude-opus-5-5
$4/$20
$4.40/$22
Opus 4.8
jp.anthropic.claude-opus-4-8
$5/$25
$5.50/$27.50
Opus 4.7
jp.anthropic.claude-opus-4-7
$5/$25
$5.50/$27.50
Sonnet 4.6
jp.anthropic.claude-sonnet-4-6
$3/$15
$3.30/$16.50
Haiku 5.5
jp.anthropic.claude-haiku-5-5
$0.10/$0.50
$0.11/$0.55
Haiku 4.5
jp.anthropic.claude-haiku-4-5-20251001-v1:0
$1/$5
$1.10/$5.50
日本に閉じた単価は、global の 1.1 倍です。
Haiku 5.5 は、10 万トークンを超える問い合わせの単価が高くなります(日本に閉じた場合は $0.55/$2.75)。
日本からは global でしか使えないもの:Fable 5.1、Fable 5、Opus 5、Opus 4.6、Sonnet 5.5、Sonnet 5。
Opus 4.8・4.7 と Haiku 4.5 は、東京の中だけで処理する方法(Mantle というエンドポイント)もあります。
!
Anthropic の旧ページには Opus 4.6 に jp. の推論プロファイルがあると書かれていますが、AWS のモデルカードでは日本の推論プロファイルはありません。AWS は、データの所在に要件があるなら、プロファイル ID の頭の文字だけで行き先を判断せず、GetInferenceProfile で確かめるよう書いています。
Claude Code を日本で完結させる設定
Claude Code には落とし穴が 1 つあります。東京のように ap- で始まるリージョンでは、推論プロファイルとして apac.(アジア太平洋の複数のリージョンを回るもの)を優先します。モデルにそのプロファイルが無いと、ほかにあるプロファイルの中から選びます。何もしないと、日本の外に出るおそれがあります。
そこで、モデルを jp. の ID で固定し、管理用の設定(managed settings)で配ります。管理用の設定は、利用者が上書きできません。OS ごとの置き場所は、既存記事の「ステップ4: 合意を設定で守る」の表にあります。
{
"allowedProviders": ["bedrock"],
"env": {
"CLAUDE_CODE_USE_BEDROCK": "1",
"AWS_REGION": "ap-northeast-1",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "jp.anthropic.claude-opus-5-5",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "jp.anthropic.claude-sonnet-4-6",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "jp.anthropic.claude-haiku-5-5",
"CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK": "1",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
},
"availableModels": [
"jp.anthropic.claude-opus-5-5",
"jp.anthropic.claude-sonnet-4-6",
"jp.anthropic.claude-haiku-5-5"
],
"enforceAvailableModels": true,
"skipWebFetchPreflight": true
}
設定
役割
allowedProviders
接続先を Bedrock だけにする。個人のアカウントなどへの切り替えを止める
AWS_REGION
東京を指定する。環境変数にも AWS の設定ファイルにもリージョンが無いと、us-east-1 になる
ANTHROPIC_DEFAULT_OPUS_MODEL など 3 つ
3 つのモデルを jp. の ID で固定する。Haiku は、会話のタイトル作りなどの背景の作業に使われる
CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK
モデルが使えないときに、別のモデルへ切り替わるのを止める
availableModels・enforceAvailableModels
選べるモデルを jp. のものだけにする(enforceAvailableModels は v2.1.287 以降)
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC・skipWebFetchPreflight
モデル以外の通信を止める(問い 3)
Claude Code の Web 検索の機能は、Bedrock では使えません。
起動したら /status で、接続先とリージョンを確かめます。推論プロファイルの行き先は、AWS CLI で確かめます。
aws bedrock get-inference-profile \
--region ap-northeast-1 \
--inference-profile-identifier jp.anthropic.claude-opus-5-5 \
--query 'models[].modelArn'
返ってくる ARN のリージョンが ap-northeast-1 と ap-northeast-3 だけであれば、東京と大阪の中で処理されます。
AWS の側でも止める
Claude Code の設定に加えて、AWS の組織の側でも止めておくと確実です。
global の推論を止める:AWS が公開している SCP の例です(Version と Statement の外枠を足しています)。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyGlobalCrossRegionInference",
"Effect": "Deny",
"Action": "bedrock:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "unspecified"
},
"ArnLike": {
"bedrock:InferenceProfileArn": "arn:aws:bedrock:::inference-profile/global.*"
}
}
}
]
}
東京と大阪以外のリージョンを SCP で止める:行き先にほかのリージョンを含む推論プロファイル(apac. など)は、呼ぶと失敗するようになります。
保存しない:東京と大阪のリージョンで、データの保存を「しない」(data_retention_mode: none)にします。
閉域でつなぐ:PrivateLink のエンドポイント(com.amazonaws.ap-northeast-1.bedrock-runtime)を使います。
図にすると、次の形になります。
Codex と Gemini CLI の場合
Codex:Bedrock を接続先にする設定(amazon-bedrock と amazon-bedrock-runtime)が標準で入っています。モデルの利用料は Bedrock の有料(従量課金)です。ただし、Codex の資料に載っている GPT-6 系は、推論の場所が global・米国・us-east-1 などだけで、日本に閉じる方法がありません。AWS のモデルカードで確かめた GPT(GPT-5.4〜GPT-6 系)も、日本からは global でしか使えないか、日本では提供されていません。gpt-oss-120b・20b は東京の中で使えますが、Codex の Bedrock の設定で使えるかは公式資料に書かれておらず、試していません。
Gemini CLI:Agent Platform(有料・従量課金)の東京(asia-northeast1)で使えば、日本の中で処理すると明記されたモデルがあります。Gemini 3.5 Flash、Gemini 2.5 Pro(64k 版)、Gemini 2.5 Flash(128k 版)です。1M 版は対象外です。Gemini CLI の /model はサブエージェントが使うモデルを変えないと公式資料にあるため、ほかのモデルが使われないかは確かめてから使ってください。閉域でつなぐには、Cloud VPN や Interconnect の上で Private Service Connect を使います。
4. 外に出さない
どの経路でも社外に出せない情報は、社内で動かす LLM に読ませます。
Codex は --oss で、手元の Ollama などのモデルを使えます。Ollama は本体が無料で、動かす PC や GPU は自前です。
~/.codex/config.toml
oss_provider = "ollama"
Claude Code は、ゲートウェイ経由であっても、Claude 以外のモデルへの接続をサポートしていません。
Gemini CLI を社内のモデルで動かせるかは、確かめていません。
社内で動かすモデルは、クラウドの最新のモデルより性能が下がることが多く、機材の費用もかかります。すべての作業をここに寄せるのではなく、外に出せない情報を扱う作業だけに絞るのが現実的です。
5. 契約と規程を整える
他社から預かった情報を読ませるための、NDA の条項の確認と顧客との合意の進め方は、既存記事の「ステップ2」と「ステップ3」にあります。
委託契約には、金融のサイバーセキュリティガイドライン 2.6 ⑧ の項目が、分野を問わず使えます(抜粋)。
サードパーティとの役割分担・責任分界
監査権限
再委託手続
実施すべきセキュリティ対策
インシデント発生時の対応及び報告
データの所在・保管・保持・移転・廃棄に関する取決め
契約終了の条件及び契約終了時の取決め
社内規程では、格付けごとに使ってよい経路を決めておくと、現場で迷いません。次は筆者の例です。
格付け
例
使ってよい経路
公開
OSS、公開した文書
どの経路でも
社外秘
自社のソースコード、設計書
学習に使わない契約の経路(Team・Enterprise・API・Bedrock など。いずれも有料)
機密
顧客の情報を含む資料、勘定系の設計
日本で完結し、保存せず、閉域でつなぐ経路。顧客との合意も取る
持ち出し禁止
認証情報、マイナンバー、本番の個人情報
読ませない。ダミーに置き換える
まとめ
国として「日本に置け」と一律に決めた法律は見当たりません。国内を基本とするのは政府・自治体と医療で、金融や通信は「所在の把握と説明」です。
読ませていいかは、3 つの問い(社外に出してよいか、出した先でどう扱われるか、道具が何を送るか)で決めます。
認証情報とマイナンバーは読ませません。本番のデータは、ダミーか構造だけにします。
日本で完結させるなら、Claude Code と Bedrock の JP の推論プロファイルの組み合わせです。モデルを jp. の ID で固定し、AWS の側でも global を止めます。Google Cloud の Claude と、Codex 用の GPT は、日本で完結させられません。
どこにも出せない情報は、社内で動かす LLM(Codex の --oss など)に任せます。
参考資料
関連記事
顧客資料を Claude Code に入れたいのに「ダメ」で止まって困ってないか? 入れられる状態にする契約・合意・設定
法令・ガイドライン
Report of the Council of Experts on the Usage of Cloud Computing by Financial Institutions(FISC・2014-11、公式英語版。FISC のサイトが緊急メンテナンス中のため Wayback Machine の写し)
金融機関による AI の業務への利活用に関する安全対策の観点からの考察(FISC・2024-09-24、Wayback Machine の写し)
主要行等向けの総合的な監督指針 Ⅲ-3-3-4 外部委託(金融庁)
金融分野におけるサイバーセキュリティに関するガイドライン(金融庁・2024-10-04)
金融分野における経済安全保障推進法の特定社会基盤役務の安定的な提供の確保に関する制度の解説(金融庁・令和 6 年 6 月)
DS-310 政府情報システムにおけるクラウドサービスの適切な利用に係る基本方針(デジタル庁・2025-05-27)
ガバメントクラウド等の整備のためのクラウドサービスの提供 令和 8 年度募集 調達仕様書(デジタル庁・2025-12-26)
地方公共団体情報システムのガバメントクラウドの利用に関する基準 第 1.0 版(デジタル庁・2022-10、三重県のサイトに掲載)
地方公共団体における情報セキュリティポリシーに関するガイドライン 令和 7 年 3 月版(総務省)
医療等情報利活用ワーキンググループ 資料 5(厚生労働省・2026-05-29)
電気通信事業法施行規則(e-Gov 法令検索)
Agreement between the United States and Japan concerning Digital Trade(USTR)/日米デジタル貿易協定(外務省)
個人情報保護委員会の FAQ:Q7-53・Q12-3・Q14-17
「特定個人情報の適正な取扱いに関するガイドライン(事業者編)」に関する Q&A(個人情報保護委員会)
クラウド・道具
Claude in Amazon Bedrock・Data residency・Claude Platform on AWS・Claude Models on Google Cloud (Google managed)(Anthropic)
Claude Opus 5.5 のモデルカード(ほかのモデルも同じ形式)・Supported Regions and models for inference profiles・Geographic cross-Region inference・Global cross-Region inference・Abuse detection・Data retention・VPC interface endpoints(AWS)
Locations・Data residency・Zero data retention・Abuse monitoring・Private Service Connect(Google Cloud)
Claude Code on Amazon Bedrock・Data usage・Network configuration・Permissions・Sandboxing・Settings reference・LLM gateway(Claude Code)
Advanced Configuration・Configuration reference・Sandboxing・Use ChatGPT Work and Codex with Amazon Bedrock(Codex)
How your data is used to improve model performance(OpenAI)
Gemini CLI configuration(Gemini CLI)
📌 저장소 링크:
8위 제미나이 CLI
google-gemini/gemini-cli
※ 개인, 무료 사용자는 Antigravity CLI로 이전됨: antigravity.google
7위 마이크로덕
pollen-robotics/microduck
6위 임페커블
pbakaus/impeccable
5위 클로드 하우투
luongnv89/claude-howto
4위 홀마크
Nutlope/hallmark
3위 AWS 에이전트 툴킷
aws/agent-toolkit-for-aws
2위 엔비디아 오픈셸
NVIDIA/OpenShell
1위 클라우드플레어 시큐리티 오딧 스킬
cloudflare/security-audit-skill
5 likes
Mentions
「人が打ったときだけ動く」はずのスキルを、AI が自分で読んだ。31万スターのスキル集を Claude Code・Codex・Gemini CLI で3回ずつ試した GitHub で31万スターを集めているスキル集があります。Matt Pocock さんの mattpocock/skills です(313,237スター、2026年11月5日に API で取得)。README には Claude Code・Codex・GitHub Copilot・Gemini CLI への入れ方が並んでいて、同じスキルをどのツールでも使える作りです。 プラグインに入る27本のうち16本には、「人が名前を打ったときだけ動かす」という印が付いています(以下、人が呼ぶ用)。課題管理の初期設定をする setup-matt-pocock-skills や、計画を課題に分けて課題管理に登録する to-tickets などです。この2本は、動くとリポジトリにファイルを書いたり、課題を立てたりします。 同じスキル集を入れたら、この印は3つのツールで同じように効くのか。 同じ依頼を5つ、3回ずつ出して確かめました。 結論: 3つとも、人が呼ぶ用のスキルを AI が自分で読んだ回がありました。止め方がツールごとに違っていて、Gemini CLI はそもそも印を読んでいませんでした。 | 依頼(狙ったスキル) | 種類 | Claude Code | Codex CLI | Gemini CLI | |---|---|---:|---:|---:| | テストを先に書いて機能を足して(tdd) | AI も使える | 3/3 | 3/3 | 3/3 | | テストが落ちるので直して(diagnosing-bugs) | AI も使える | 0/3 | 1/3 | 0/3 | | スキルを使う前の初期設定をして(setup-matt-pocock-skills) | 人が呼ぶ用 | 2/3 | 1/3 | 3/3 | | 計画をチケットに分けて(to-tickets) | 人が呼ぶ用 | 0/3 | 0/3 | 3/3 | (3回のうち、狙ったスキルの中身を読み込んだ回数。どのツールも読み取りだけのつもりの指定で動かしました。Gemini CLI は、スキルを読み込む道具を許す設定を足した条件です。理由は後で書きます。2026-11-05) - Gemini CLI は、SKILL.md の先頭から name と description しか読みません。印は無視され、27本すべてが AI の一覧に載りました - Claude Code と Codex は、印の付いたスキルを AI の一覧から外す作りです。ただし外すのは AI に見せる説明だけで、ファイルは読めます。AI がプラグインのフォルダを検索して、SKILL.md を直接読んだ回がありました - Gemini CLI の -p は、読み取りだけの計画モード(plan)で始めても、計画を抜けると全部を自動で許す YOLO モードに切り替わります。人が呼ぶ用のスキルを読み込んだ6回のうち5回で、AGENTS.md や課題のファイルを作っていました > 検証環境: Windows 10 Home(19045)/ Claude Code 2.1.318 / Codex CLI 0.166.0 / Gemini CLI 0.66.0 / mattpocock/skills 1.3.1(Claude Code)・1.3.2(Codex・Gemini CLI)/ 2026-11-05 --- 印は、ツールごとに書く場所が違う このスキル集は、人が呼ぶ用の印を2か所に書いています。Claude Code 用に SKILL.md の先頭の disable-model-invocation: true、Codex 用に agents/openai.yaml の allow_implicit_invocation: false です。作者のメモ(.agents/invocation.md)にも、2つをそろえるよう書いてあります。 > Keep the two in sync: a skill is user-invoked in both harnesses or neither. > (訳: 2つをそろえること。どちらのツールでも人が呼ぶ用か、どちらでも違うかのどちらか) Gemini CLI 用の印はありません。Gemini CLI のほうにも、それに当たる項目がありませんでした。 graph LR S[人が呼ぶ用のスキル 16本] --> C[Claude Code<br/>SKILL.md の<br/>disable-model-invocation] S --> X[Codex CLI<br/>agents/openai.yaml の<br/>allow_implicit_invocation] S --> G[Gemini CLI<br/>読むのは<br/>name と description だけ] C --> C1[AI の一覧に載せない] X --> X1[AI の一覧に載せない] G --> G1[27本とも<br/>AI の一覧に載せる] Claude Code の公式ドキュメントのスキルのページは、disable-model-invocation: true のスキルを「Description not in context, full skill loads when invoked」と書いています。説明を AI に渡さず、人が呼んだときだけ中身を読み込む、という意味です。Codex の文書にも「When false, Codex won't implicitly invoke the skill based on user prompt.」とあります。 Gemini CLI は、SKILL.md の先頭を読む処理が次のとおりでした(packages/core/src/skills/skillLoader.ts、11月5日時点の main)。 const { name, description } = parsed as Record<string, unknown>; if (typeof name === 'string' && typeof description === 'string') { return { name, description }; } ほかの項目は捨てています。文書も、起動のときに「injects the name and description of all enabled skills into the system prompt」(有効なスキルすべての名前と説明をシステムプロンプトに入れる)と書いています。 AI に渡す一覧の大きさにも、この違いが出ました。「OK とだけ返して。」と頼んだときの入力トークンが、入れる前と比べて増えた分です。Claude Code と Codex は3回とも同じ値で、Gemini CLI は3回の中央値どうしの差です(入れる前 9,905〜9,923、入れた後 12,847〜12,859)。 xychart-beta horizontal title "スキル集を入れて、常に増えた入力トークン" x-axis ["⠀⠀Claude Code", "⠀⠀Codex CLI", "⠀⠀Gemini CLI"] y-axis "トークン" 0 --> 3000 bar [871, 1202, 2924] Claude Code だけは、比べる相手を変えています。測定用の設定では、プラグインを有効にした回だけ、私のアカウントで claude.ai から同期しているスキル13本も一覧に出ました。そこでこの13本を設定(skillOverrides)で外し、プラグインを入れて無効にした状態と比べました。 Claude Code の +871 は、claude plugin details が見積もる「常に載る分」のうち、AI も使える11本の分を足した値(約880)とほぼ同じでした。見積もりの合計は27本分で約1,651です。人が呼ぶ用の16本は、一覧に載っていないと読めます。Gemini CLI は、人が呼ぶ用の16本を無効にすると +1,329 まで下がりました(こちらは1回だけ測った値です)。 --- 入れ方(README のとおり) 3つとも README のコマンドで入れました。普段の設定は汚さないように、設定の置き場所を別のフォルダにしています。 | ツール | README のコマンド | 入ったもの | |---|---|---| | Claude Code | claude plugin install mattpocock-skills@claude-plugins-official | 27本、版は 1.3.1 | | Codex CLI | codex plugin marketplace add mattpocock/skills と codex plugin add mattpocock-skills@mattpocock | 版は 1.3.2。リポジトリ全体が入り、SKILL.md は39本(AI の一覧に何本載るかは確かめていない)。~/.codex/config.toml に書かれる | | Gemini CLI | gemini skills install https://github.com/mattpocock/skills.git --path skills/engineering と、--path skills/productivity の2行 | 27本、全部が [Enabled] | Claude Code だけ版が1つ前でした。公式のマーケットプレイスが、10月9日のコミット(49dd158)を指しているためです。GitHub の main(10月31日のコミット)は 1.3.2 です。 設定をまっさらにした測定用の Claude Code では、README のコマンドが「Plugin "mattpocock-skills" not found in marketplace "claude-plugins-official"」で失敗しました。先に claude plugin marketplace add anthropics/claude-plugins-official が要りました。私の普段の設定には、このマーケットプレイスが最初から入っています。 --- 試し方 見本は小さな JavaScript のリポジトリです。src/slugify.js と src/total.js があり、total.js は割引の計算で /100 が抜けていて、テストが1本落ちます。PLAN.md にはクーポン機能の4段の計画を書きました。GitHub の remote は付けていません。 | 依頼 | 狙ったスキル | 種類 | |---|---|---| | src/slugify.js に、記号(! や ? など)を取り除く機能を足したい。テストを先に書いて進めて。 | tdd | AI も使える | | npm test を実行すると test/total.test.js が落ちる。原因を調べて直して。 | diagnosing-bugs | AI も使える | | このリポジトリで、エンジニア向けのスキルを使い始める前の初期設定をして。課題の管理場所と、トリアージ用のラベルを決めたい。 | setup-matt-pocock-skills | 人が呼ぶ用 | | PLAN.md の計画を、作業チケットに分けて。 | to-tickets | 人が呼ぶ用 | これに「OK とだけ返して。」を足した5つを、入れる前と入れた後で3回ずつ頼みました(3ツール × 2 × 5 × 3 = 90回)。どれも読み取りだけのつもりの指定です。Gemini CLI のこの指定は、後で書くとおり、途中から読み取りだけではなくなりました。 | ツール | 指定 | |---|---| | Claude Code | claude -p --allowedTools Read,Glob,Grep,Skill | | Codex CLI | codex exec -s read-only | | Gemini CLI | gemini -p --approval-mode plan | GitHub CLI(gh)は、ログインしていない状態にしました。課題を立てる操作が、私のアカウントで外に出ないようにするためです。 「読み込んだ」は、スキルの中身が実際に返ってきた回だけを数えています。 - Claude Code: スキルを呼ぶ道具(Skill)が成功したか、SKILL.md を Read で読めた回 - Codex CLI: SKILL.md を読むコマンドが成功し、出力にスキルの名前の行があった回 - Gemini CLI: スキルを読み込む道具(activate_skill)が成功した回 --- AI も使える側: tdd は3つとも使った 「テストを先に書いて」の依頼では、3つとも3回とも tdd を読み込みました。読み込み方は3つで違います。Claude Code はスキルの道具、Codex は PowerShell の Get-Content で SKILL.md を読み、Gemini CLI は activate_skill を使いました。 diagnosing-bugs は使われにくく、9回のうち Codex の1回だけでした。説明には「reports something broken/throwing/failing/slow」(何かが壊れている・例外を出す・落ちる・遅いと伝えられたとき)とあり、依頼の「テストが落ちる」は当てはまるはずです。日本語で頼んだことが効いたのかは、今回の測り方では分かりません。 --- 人が呼ぶ用: Gemini CLI は6回とも自分で読み込んだ Gemini CLI は、「初期設定をして」で3回とも setup-matt-pocock-skills を、「チケットに分けて」で3回とも to-tickets を読み込みました。チケットの1回目は、to-tickets のあとに setup-matt-pocock-skills も読み込んでいます。 ただし、この数は activate_skill を許す設定を足したうえでの数です。Gemini CLI は対話なし(-p)で動かすと、activate_skill を既定で拒みます。同梱の方針ファイル(policies/write.toml)の「Headless Denial Rule」に、拒む道具として並んでいます。3つを同じ条件で比べるため、測定ではこの道具だけを許しました。 許さないままでも、AI はスキルを狙っていました。足した設定を外して1回ずつ動かすと、read_file で人が呼ぶ用の SKILL.md を読もうとして「Path not in workspace」で弾かれました。そのあと SKILL.md の文面を Web 検索で12回・14回探し続け、2回とも420秒の打ち切りになっています。 読み込んだ回は重くなりました。チケットの依頼の入力トークンは、入れる前が中央値 151,244、入れた後は 972,631 と 878,780 でした(3回目は打ち切り)。 対話の画面で使うなら、activate_skill の前に確認が出ます。文書には、スキルの名前・目的・読めるようになるフォルダを示す確認が出る、とあります。今回は対話の画面では試していません。 --- Claude Code と Codex は、一覧に無いスキルのファイルを探して読んだ Claude Code と Codex は、人が呼ぶ用のスキルを一覧から外す作りです。それでも「初期設定をして」では、Claude Code が3回中2回、Codex が3回中1回、setup-matt-pocock-skills の SKILL.md を読んでいます。 Codex の1回で、プラグインのフォルダに触れたコマンドを順に抜き出しました(ホームを ~ に縮め、JSON のエスケープを外しています)。 Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\code-review\SKILL.md'; Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\diagnosing-bugs\SKILL.md'; Get-ChildItem -Recurse '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2' -Force | Select-Object FullName rg -n -i 'setup-matt-pocock-skills|triage|issue tracker|labels?' '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2' -g '*.md' Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\setup-matt-pocock-skills\SKILL.md'; Get-Content '~\.codex\plugins\cache\mattpocock\mattpocock-skills\1.3.2\skills\engineering\setup-matt-pocock-skills\issue-tracker-local.md'; 最初に読んだ code-review は、AI も使える側のスキルです。その SKILL.md の13行目に、次の一文があります。 > If not, tell the user to run /setup-matt-pocock-skills. > (訳: 無ければ、/setup-matt-pocock-skills を実行するよう利用者に伝える) Codex は利用者に伝えず、プラグインのフォルダを検索して、自分で読みにいきました。このスキル集では、setup-matt-pocock-skills 自身のほかに7本の SKILL.md が、この名前を出しています。一覧に載らなくても、名前はほかのスキルの中に出てきます。 Claude Code の2回は、Grep で ~/.claude/plugins の下を探して、SKILL.md を Read していました。2回とも、SKILL.md の手順どおり最初の質問をしています。残りの1回は、SKILL.md の先頭の行だけを Grep で見て、こう答えました。 > ただしこのスキルはユーザーが直接実行する設定になっていて(disable-model-invocation: true)、私からは呼び出せません。 そのうえで、/mattpocock-skills:setup-matt-pocock-skills を打つよう案内しています。読んだ2回も、SKILL.md の先頭にある disable-model-invocation: true の行ごと読んでいます。同じ印を見て、止まった回と手順を進めた回が、同じ依頼で両方出ました。 印が止めるのは、AI に見せる一覧だけです。ファイルの読み取りまでは止めません。 --- Gemini CLI の -p は、計画モードでも途中から YOLO になる 90回のうち、リポジトリのファイルが書き換わったのは Gemini CLI の回だけでした。Claude Code と Codex は30回とも書き換えゼロです。 | ツール | 入れる前 | 入れた後 | |---|---:|---:| | Claude Code | 0/15 | 0/15 | | Codex CLI | 0/15 | 0/15 | | Gemini CLI | 6/15 | 11/15 | Gemini CLI は読み取りだけの計画モード(--approval-mode plan)で動かしていました。それでも書き換わった理由は、計画モードの文書の「Non-interactive execution」に書いてあります。 > When exiting Plan Mode to execute the plan, Gemini CLI automatically switches to YOLO mode instead of the standard Default mode. > (訳: 計画を実行するために計画モードを抜けると、Gemini CLI は通常の Default モードではなく YOLO モードへ自動で切り替わる) 対話なしでは、計画モードを抜ける道具(exit_plan_mode)も自動で許されます。AI が計画を書いて抜けた時点で、ファイルの書き込みもシェルのコマンドも、確認なしで通るようになります。 人が呼ぶ用のスキルを読み込んだ回では、そのスキルの手順どおりに書いていました。 - 「初期設定をして」の3回: AGENTS.md、docs/agents/issue-tracker.md、docs/agents/triage-labels.md、docs/agents/domain.md を作成 - 「チケットに分けて」の2回: .scratch/coupon-codes/issues/ の下に課題のファイルを作成 - どちらでも npm test や git status を実行 見本は remote の無いリポジトリで、どの回も課題の置き場所にはローカルの Markdown を選んでいました。GitHub の remote と gh のログインがあるリポジトリで同じことが起きたらどうなるかは、試していません。 同じ依頼を既定のモード(--approval-mode を付けない gemini -p)で1回動かすと、ファイルは書き換わらず、直し方を文章で返しました。同梱の方針ファイルでは、対話なしの既定のモードは書き込みとシェルの道具を拒む決まりになっています。 --- どうするか Gemini CLI: 人が呼ぶ用の16本を無効にする SKILL.md に disable-model-invocation: true があるスキルだけを止める PowerShell です。gemini skills disable の既定の範囲は workspace なので、ユーザー単位で入れたスキルには --scope user が要ります。 # SKILL.md で「人が呼ぶ用」になっているスキルを止める $root = if ($env:GEMINI_CLI_HOME) { $env:GEMINI_CLI_HOME } else { $HOME } $dir = Join-Path $root '.gemini\skills' Get-ChildItem (Join-Path $dir '*\SKILL.md') | Where-Object { Select-String -Path $_.FullName -Pattern '^disable-model-invocation:\s*true' -Quiet } | ForEach-Object { gemini skills disable $_.Directory.Name --scope user } 実行後の gemini skills list は、[Enabled] が11本、[Disabled] が16本でした。この状態で「初期設定をして」と「チケットに分けて」を2回ずつ頼むと、人が呼ぶ用のスキルは4回とも読み込まれませんでした。チケットの入力トークンは 162,965 と 198,462 で、入れる前に近い値に戻っています。 Gemini CLI: -p で読み取りだけにしたいなら、計画モードを使わない --approval-mode plan は、対話なしだと途中から YOLO になります。読み取りだけで動かしたいなら、--approval-mode を付けない既定のモードのほうが書き換わりませんでした(1回だけの確認です)。 Claude Code・Codex: 副作用のある操作は、権限で止める 印が効くのは一覧だけです。AI はスキルのファイルを読めますし、読めば手順に従おうとします。課題を立てる、ラベルを作る、push するといった操作は、スキルの印に頼らず、権限の設定や読み取りだけの指定で止めておくのが確実です。今回は Claude Code・Codex とも読み取りだけで動かしていたので、ファイルは1つも書き換わりませんでした。 何が AI に見えているかを確かめる | ツール | 見方 | |---|---| | Claude Code | claude plugin details mattpocock-skills@claude-plugins-official(スキルごとの「常に載る分」の見積もり) | | Codex CLI | 対話の画面で /skills | | Gemini CLI | gemini skills list([Enabled] が AI の一覧に載る) | --- 言えないこと - 依頼は4つ、各3回です。モデルは各ツールの既定のもの1つずつで、ほかのモデルでは数が変わりえます - 依頼は日本語、スキルの説明は英語です。英語で頼んだときの数は測っていません - Gemini CLI の人が呼ぶ用の6回は、activate_skill を許す設定を足した条件での数です。既定のままでは読み込めず、ファイルの読み取りと Web 検索で探し続けました - Claude Code の「ファイルを探して読んだ」2回は、プラグインのファイルが ~/.claude/plugins にある条件での数です。最初に設定を別フォルダだけに置いて測ったときは、AI が ~/.claude を探しても何も見つからず、0回でした。普通に入れればプラグインはそこに入るので、そちらの条件で測り直しています - Codex で入れる前の回を測るとき、-c でプラグインを止める指定(plugins."mattpocock-skills@mattpocock".enabled=false)は効きませんでした。プラグインを外して測り直しています - Gemini CLI は無料枠の API キーで動かしています。無料枠は入力が改善に使われる側なので、見本はダミーのコードだけにしました - 対話の画面での動き(Gemini CLI の確認の表示など)は、文書の記述だけで、試していません - README にある GitHub Copilot は、試していません - 試したのは Windows だけです --- まとめ 同じスキル集を入れても、「人が打ったときだけ動く」という印の効き方は3つで違いました。Gemini CLI は印を読まず、27本すべてを AI に見せていました。Claude Code と Codex は一覧から外しますが、AI がファイルを探して読むところまでは止めません。 副作用のあるスキルは、印ではなく権限で止めます。 Gemini CLI なら人が呼ぶ用を無効にし、-p で計画モードを使わない。Claude Code と Codex なら、課題を立てる・書き込むといった操作を権限の側で閉じておきます。 --- 関連記事 - GitHubトレンドのスキル集を入れたら、自分のスキル2本の説明が消えた - Claude Code にスキルを80本足しても、増えたトークンは185だった --- JQITのエンジニアの95%以上は未経験からの採用です。 よければコーポレートサイトにも遊びに来てください。 ▶ コーポレートサイト エンジニア採用も行っています。もしご興味あれば覗いてみてください。 ▶ 採用サイト
@OfficialLoganK @GoogleAIStudio Guys, I guess you need to update the reference implementation. It doesn't have a "ready-to-use Docker-based sandbox". Repo: google-gemini/computer-use-preview t.co
Why One Emoji Breaks Your Coding Agent's TUI Borders: wcwidth vs Grapheme Clusters - Book: AI That Acts - The series: AI in TypeScript — 5 books, from your first LLM call to agents in production — all five here - My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools - Me: xgabriel.com | GitHub --- Paste into Claude Code 2.1.207 and the text after it slides one cell to the right. That is the report in anthropics/claude-code#80475, opened July 23, 2026: stray characters bleeding into neighbouring rows, inverse-video blocks between words, and a mess that stays until Ctrl-L or a window resize forces a full repaint. The emoji is U+1FAEA, DISTORTED FACE, which arrived with Unicode 17.0 in 2025. The terminal drew it two cells wide. Claude Code's width table was older than the emoji and counted fewer. In the maintainer's closing comment, the fix "came from updating the Unicode width tables in the runtime Claude Code ships with," and from 2.1.221 on, both and (U+1FAE9, FACE WITH BAGS UNDER EYES, reported later in the same thread) measure as two cells. Claude Code and the terminal disagreed on how many columns U+1FAEA takes, and every cell after it inherited the gap. Two programs, one grid A terminal is a grid of cells. A TUI like Claude Code, Codex or Gemini CLI never sees that grid. It writes bytes, and to draw a box it has to predict where the cursor will be after each string. The right border of a box sits at "left edge plus the width I computed." The terminal then advances the cursor by the width it computed. When those two numbers agree, borders line up. When they differ by one, everything the program draws after that character lands one column off, and every partial redraw targets the wrong cells. That is why these bugs show up as smearing and duplicated lines across the whole screen. kitty's text sizing protocol docs put it bluntly: if the client program and the terminal disagree on cell counts, "the entire user interface can be broken". !A terminal grid with two rulers, one from the program and one from the terminal, measuring the same emoji tile and ending one cell apart The program and the terminal each measure the same character. One cell of disagreement moves every border after it. Three counts, none of them is width Start with what JavaScript can count. Save this as count.mjs and run it with node count.mjs: const seg = new Intl.Segmenter("en", { granularity: "grapheme", }); const samples = { ascii: "A", cjk: "中", heart: "\u{2764}", heartVS16: "\u{2764}\u{FE0F}", thumbTone: "\u{1F44D}\u{1F3FD}", family: "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}", distorted: "\u{1FAEA}", }; console.log("ICU Unicode:", process.versions.unicode); for (const [name, s] of Object.entries(samples)) { const units = s.length; const points = [...s].length; const clusters = [...seg.segment(s)].length; console.log(name.padEnd(10), s, units, points, clusters); } .length counts UTF-16 code units. Spreading the string counts code points. Intl.Segmenter counts grapheme clusters, which UAX #29 defines as user-perceived characters. Its rule GB11 says: "Do not break within emoji modifier sequences or emoji zwj sequences." The family is three emoji glued together by two ZERO WIDTH JOINERs (U+200D), so it is five code points and eight UTF-16 units but one grapheme, while the skin-tone thumbs-up and the heart followed by U+FE0F are two code points and one grapheme each. A Chinese character is one code point and one grapheme, and it still takes two cells. The first line prints the Unicode version your Node's ICU knows. The Node docs example shows unicode: '17.0'. Unicode 18.0 is dated September 16, 2026. Every program that measures width carries a snapshot of some version, and they are rarely the same snapshot. Now draw a box the naive way, one cell per code point: const rows = [ "plain text", "中文", "\u{2764}\u{FE0F} ok", "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467} team", ]; const width = (s) => [...s].length; const inner = 16; const edge = "+" + "-".repeat(inner) + "+"; console.log(edge); for (const r of rows) { console.log("|" + r + " ".repeat(inner - width(r)) + "|"); } console.log(edge); The plain-text row lines up. The 中文 row overshoots by two cells in every terminal, because each character is one code point and two cells. The heart and family rows are where terminals disagree: run the script in two emulators and compare where those right borders land. Where width actually comes from The width a terminal assigns usually starts from the East_Asian_Width property in UAX #11. Its values are A (ambiguous), F (fullwidth), H (halfwidth), N (neutral), Na (narrow) and W (wide). W and F take two cells, and W also covers "characters that have the UTS51 property Emoji_Presentation." For ambiguous characters the annex says: "If the context cannot be established reliably, they should be treated as narrow characters by default." That covers single code points. Emoji sequences are where the tables run out. UTS #51 defines U+FE0F, VARIATION SELECTOR-16, as the character "used to request an emoji presentation." The plain heart U+2764 has no Emoji_Presentation, so on its own it is a text-style, one-cell character. Add VS16 and you ask for the two-cell emoji. A per-code-point width function sees one narrow character plus a variation selector that takes no cells of its own, and so the total depends on whether the function knows the sequence. The Python wcwidth library documents exactly this split. wcwidth('\U00002640'), the plain ♀ (U+2640), is 1. wcswidth('\U00002640\U0000FE0F'), the same sign with VS16, is 2. Ask for VTE's behaviour with wcstwidth(..., term_program='vte') on that same VS16 string and the docs show 1. Its four-person family example measures 2 by default and 8 with term_program='alacritty', a correction the docs put down to Alacritty not supporting emoji ZWJ. Here is the Python side of the same experiment: # pip install --upgrade wcwidth import unicodedata from wcwidth import wcwidth, wcswidth print("UCD", unicodedata.unidata_version) for ch in ["A", "中", "\U00002764", "\U0001FAEA"]: eaw = unicodedata.east_asian_width(ch) print(f"U+{ord(ch):04X}", eaw, wcwidth(ch)) print(wcswidth("\U00002640\U0000FE0F")) # wcwidth docs: 2 unicodedata follows the Python release, not the wcwidth package. The Python 3.15 docs say its data comes from UCD 17.0.0. An older interpreter or an older wcwidth will give a different answer for U+1FAEA, which is the same kind of mismatch as the Claude Code bug. It goes the other way too. In gemini-cli#25369, Ink, the React renderer Gemini CLI draws with, used Intl.Segmenter to merge a Thai consonant and SARA AM (U+0E33) into one cluster of width 1, while tmux and xterm.js drew it across two columns. The symptom was one streamed line repeated 8 to 10 times and an input line that kept jumping down. It was closed as completed on October 23, 2026, via PR #29883. This time the program was the one counting by clusters, and the terminal in front of it counted differently. !Three code points, a man, a woman and a girl, fusing through two joiner links into one emoji tile on a terminal grid A ZWJ sequence is several code points and one grapheme. Whether it takes two cells or eight depends on who is counting. Mode 2027: asking the terminal to count graphemes Some terminals now let a program opt into one shared rule. Contour's terminal-unicode-core spec defines DEC private mode 2027. CSI ? 2027 h turns it on, CSI ? 2027 l turns it off, and CSI ? 2027 $ p asks whether the terminal supports it. With the mode on, a grapheme cluster lives in one place on the grid, and a VS16 in the cluster promotes it to emoji presentation, which makes it two cells wide. You can probe your terminal from Node: process.stdin.setRawMode(true); const timer = setTimeout(() => done("no reply"), 500); function done(msg) { clearTimeout(timer); process.stdin.setRawMode(false); console.log(msg); process.exit(0); } process.stdin.once("data", (b) => done(JSON.stringify(String(b)))); process.stdout.write("\x1b[?2027$p"); The answer is a DECRPM report shaped like CSI ? 2027 ; Ps $ y. Ps 0 means the terminal doesn't recognise the mode, 1 means it is set, 2 means reset, 3 and 4 mean permanently set or reset. The timeout matters: a terminal that ignores the query sends nothing at all. Support is uneven. In the ucs-detect results, which measure terminals by printing test strings and asking for the cursor position afterwards, Ghostty, WezTerm, foot and Windows Terminal report mode 2027. kitty, iTerm2, Alacritty and xterm.js do not. The page gives no test date and says results are provided as-is, so check the version next to each row. Ghostty exposes the trade-off as a setting. grapheme-width-method defaults to unicode, which the docs call correct but able to desync the cursor with programs that measure the legacy wcswidth way. legacy matches those programs and can get skin-tone emoji wrong. A program that turns on mode 2027 forces unicode regardless. kitty went a different direction with OSC 66, where the program states the width with w= and the terminal stops guessing. The two-pane test Put two agent TUIs side by side and the disagreement becomes something you can locate. I build Hermes IDE, so weigh this section with that in mind. Hermes runs every agent's own interface in a real terminal and lets you split panes right or down, so Claude Code and Codex can sit next to each other on the same screen. !Two agent sessions side by side in Hermes IDE: Codex on orders-types and Claude Code on orders-api, each in its own hermes/ worktree, with the sessions sidebar on the left Hermes IDE 2.3.4: Codex on orders-types and Claude Code on orders-api, side by side, each in its own hermes/ worktree, with the sessions sidebar showing status, context use, cost and branch. Paste the same string with an emoji into both. Both panes live in the same app, so the terminal side of the comparison stays fixed. If one pane's border breaks and the other's holds, the difference is in the agents. Codex's TUI is built on Ratatui and pulls in the unicode-width and unicode-segmentation crates (its Cargo.toml), and Claude Code ships its own width tables in its runtime, so the two can carry different Unicode snapshots. Then flip it. Run the same agent in a second terminal emulator. If the border is fine there, the agent agrees with that emulator and the first one is the odd one out. The rest is cheap: 1. Update the agent first. claude update is the whole fix for #80475. 2. Repaint with Ctrl-L or a resize to clear a smeared screen. 3. Keep fresh emoji out of the strings an agent draws in its chrome: session names, branch names, status lines. 4. If you write a TUI, measure grapheme clusters, query mode 2027 and turn it on when the reply shows the mode is recognised (Ps 1 or 2). Where it isn't, test against the terminals your users actually run. Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It isn't affiliated with Nous Research, Anthropic, OpenAI or Google. Download it and the source is on GitHub. Finding the character Next time an agent's box comes out with a jagged right edge, skip the font settings and find the character just before the break. Compare the width your agent gives it with the width your terminal draws, then check which Unicode version each was built with. If the versions match, compare how each one segments that cluster; the Gemini CLI Thai bug was that kind. --- If this was useful If you're building your own agent in TypeScript, the terminal is only the surface. AI That Acts covers the part underneath it: tool calling, functions, and getting a first working agent to do real work in Node, so the thing drawing those borders has something worth showing.  It is book 3 of AI in TypeScript, a five-book series that runs from your first LLM call to agents in production. 
Gemini CLI's mkdir Failed, the Agent Kept Going, and Each move Overwrote the Last File - Book: LLM Observability Pocket Guide - Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go - My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools - Me: xgabriel.com | GitHub --- The agent's last message was an apology: "I have failed you completely and catastrophically." That line comes from a Gemini CLI session in July 2025, reported by Ars Technica. A product manager had asked it to rename a folder of experiments and move the files into a new one. When the session ended, one file was left. Nothing in the chain was exotic. A mkdir failed, the agent didn't check, and a plain move did what move has always done when the destination isn't a folder. You can reproduce all of it in a scratch directory in a minute, and you should, because the same thing happens with mv on Linux and macOS. What the agent ran, and what Windows did with it The user filed issue #4586 on July 21, 2025: Gemini CLI 0.1.13, model gemini-2.5-pro, no sandbox, on Windows. The full transcript was an attachment, so the issue page itself doesn't show the commands. Ars filled in the sequence. The user asked Gemini to rename the current directory, claude-code-experiments, to AI CLI experiments and move its contents to a new folder. Gemini said, correctly, that it couldn't rename the directory it was running in. It then ran a mkdir for a new folder one level up (..\). That command apparently failed. Gemini treated it as a success and started moving files. The transcript attached to the issue shows that mkdir and then one move per item, folders included. The overwrite chain below is Ars's reconstruction of what those moves did. Ars explains the rest. When the destination doesn't exist, Windows "renames the file to the destination name instead of moving it." The first move turned file one into a file named after the missing folder. Every later move renamed the next file to that same name, over the top of the one before. Ars quotes the user's diagnosis: Gemini "hallucinated a state," and "the core failure is the absence of a 'read-after-write' verification step." The user's own write-up, linked from the Ars piece, now returns a 404. The GitHub issue was closed as "not planned" on May 13, 2026, after a triage bot flagged it. One detail matters for the reproduction. At the 0.1.13 tag, Gemini CLI's shell tool docs say that on Windows "the command will be executed with cmd.exe /c." So the commands ran in cmd, whatever terminal the user started Gemini from. !Three paper documents sliding one after another toward a dashed folder outline that isn't there, each landing on the same spot and flattening the sheet beneath it Three moves, one destination name that was never a folder: each file lands on the same spot. Reproduce it in a scratch folder on cmd.exe This script touches only two names under %TEMP%. Save it as repro.cmd and run it from a Command Prompt, not from inside a project. @echo off rem repro.cmd: touches only %TEMP%\mvdemo and %TEMP%\mvout cd /d "%TEMP%" || exit /b 1 mkdir mvdemo || exit /b 1 cd mvdemo echo alpha> a.txt echo bravo> b.txt echo charlie> c.txt rem The mkdir for ..\mvout "failed". Nobody checked. move a.txt ..\mvout move b.txt ..\mvout move c.txt ..\mvout dir /b type ..\mvout I haven't run this myself, so here is what the documentation says you should see. The first move finds no folder named mvout, so it renames a.txt to a file called mvout in %TEMP%. The second and third find that file and replace it. Microsoft's move reference says the overwrite prompt is the default "unless the command is run from within a batch script," and /y or the COPYCMD variable switches it off anywhere. A .cmd file is a batch script, so nothing asks. dir /b finds nothing left in mvdemo, and type prints charlie. Clean up with del "%TEMP%\mvout" and rmdir "%TEMP%\mvdemo". Gemini CLI's later releases ran Windows commands through powershell.exe -NoProfile -Command, according to its shell docs. (Its docs also say Google replaced Gemini CLI with Antigravity CLI on June 18, 2026.) PowerShell's move is an alias for Move-Item, and its reference page describes this exact trap: when the destination folder is missing, "Move-Item moves the first item to a file called Textfiles and then displays an error explaining that the file already exists." That is better, since only the first file is renamed and the rest stay put. It is still one renamed file, plus an error an agent might not read. With -Force, the overwrite is allowed again. mv does the same thing, one file at a time POSIX mv has two forms. The spec says the rename form "is assumed when the final operand does not name an existing directory." It only prompts before replacing a file if you pass -i, or if the destination isn't writable and standard input is a terminal. An agent's shell usually meets neither condition. demo=$(mktemp -d) cd "$demo" && mkdir src && cd src printf 'alpha\n' > a.txt printf 'bravo\n' > b.txt printf 'charlie\n' > c.txt # ../out was never created for f in a.txt b.txt c.txt; do mv "$f" ../out; done ls -A # expect: nothing cat ../out # expect: charlie Put all three names in one command, mv a.txt b.txt c.txt ../out, and mv refuses: with several sources, the synopsis only accepts a directory as the last operand. The loop is the dangerous shape, and it is the shape an agent produces when it issues one tool call per file. Four defenses that don't depend on the model noticing 1. Stop on the first failed command. In bash, set -eu at the top of anything an agent runs, or mkdir ../out || exit 1 on the line that matters. In cmd, check the exit code before moving on: if not exist "..\out\" ( mkdir "..\out" if errorlevel 1 exit /b 1 ) 2. Move into a directory, never "to" a name. GNU mv -t DIR means "move all SOURCE arguments into DIRECTORY" (man page), so a missing folder is an error rather than a rename. A trailing slash (../out/) says the same thing to a human, but don't lean on it alone. GNU coreutils has changed how it treats a slashed destination before, and platforms disagree. 3. Refuse to overwrite, loudly. mv -n looks like the answer, but the GNU manual says it will "silently skip" and marks the option deprecated. An agent reading exit codes learns nothing from a silent skip. GNU coreutils 9.5 and later (release notes) has --update=none-fail, where "any skipped files are diagnosed and induce a failure." Both -t and --update are GNU options: macOS's BSD mv rejects them, so on a Mac install coreutils with Homebrew and call gmv. On Windows, Move-Item without -Force already errors on an existing file. set -eu mkdir -p ../out mv --update=none-fail -t ../out -- a.txt b.txt c.txt test "$(ls -A ../out | wc -l)" -eq 3 4. Read after write. That last line is the check the Gemini session never ran: count what arrived. It is cheap, and it is the step the user's own diagnosis named. If you write agent instructions, ask for it directly: after moving or deleting files, list the destination and compare counts. Turn data loss into an undo All four defenses reduce the odds. A snapshot taken before every agent turn means the damage can be reversed even when they all fail. The cheapest version is git, inside a repo, on a task branch: git add -A git commit -qm "checkpoint before agent turn" # ...agent turn goes wrong... git restore --source=HEAD --staged --worktree . Restore works even when the files were moved out of the repo, because the contents are already stored in .git. Two limits: ignored files such as .env aren't in the commit, and anything the agent wrote outside the repo stays where it landed. Claude Code and Gemini CLI both ship an undo, with different gaps. Claude Code's checkpointing captures your code before every prompt, and /rewind (or Esc twice) restores code, conversation or both. Its docs spell out the hole: "A file that only Bash commands changed isn't tracked," and for those they point you to Git. Gemini CLI's checkpointing, as its docs describe it, keeps a shadow git repo under ~/.gemini/history/ and restores with /restore. It is disabled by default, and the docs name file-writing tools such as write_file and replace as the trigger. A move run through the shell isn't one of those tools, so assume it isn't covered until you've tested it. This is the part I built Hermes IDE for, so weigh this section with that in mind. In Hermes, ⌘N (Ctrl+Shift+N on Windows and Linux) starts each task on its own hermes/<name> branch in its own worktree, so an agent's mess lands on a branch nobody else is using. According to the README, "every agent turn is saved, so you can diff or restore any single turn, with undo." The Review Desk (⌘G, or Ctrl+Shift+G) shows changes turn by turn. !Hermes IDE Review Desk in By turn view, listing two turns of a Claude Code task with turn 1's diff of src/db.ts and a drafted commit message The Review Desk (⌘G) in By turn view: two turns of a Claude Code task in orders-api, turn 1's diff of src/db.ts, and a commit message drafted from the turns. The "Agent replies" strip under each session lists the agent's replies, per the 2.3.1 release notes. Click one to see its changes or restore your files to that point. Before you count on that for a shell-run move, make one in a test repo and check that it shows up in the turn's diff. Hermes runs Claude Code, Codex, Antigravity CLI, Gemini CLI and other command-line agents, each in its own terminal. Hermes needs a git repository. A worktree is a folder, not a sandbox, so a shell command can still write to .., and a restore brings back the project's files while a stray file written one level up stays where it landed. In a task with extra folders, the strip tracks changes in the main project only. The docs don't say ignored files are covered, so keep your own backup of .env-style files. Turn snapshots for worktree tasks are removed 14 days after the session closes. !The Hermes IDE Review Desk's Worktrees tab listing one worktree each for orders-api, web-app and orders-types with branch, task, age and disk size The Review Desk's Worktrees tab: one Hermes worktree each for orders-api, web-app and orders-types under ~/code, with branch, task, age, disk size and free space. Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It isn't affiliated with Google, Anthropic, OpenAI or Nous Research. Download it or read the code on GitHub. --- If this was useful The Gemini session went wrong because nothing recorded what each tool call actually returned, and the agent filled the gap with a story. Tracing tool calls and their results is what my LLM Observability Pocket Guide is about, along with how to pick the tracing and eval tools that fit your team. 
Gemini API Cookbook: Examples and guides for using the Gemini API (18k stars) What it does All text below is quoted directly from the project README. >Examples and guides for using the Gemini API 1. Quick Starts: - Authentication: Set up your API key for access. - Get Started: Get started with Gemini models and the Gemini API, covering basic prompting and multimodal input. - Get started with Live API: Get started with the live API with this comprehensive overview of its capabilities - Get started with Live Translation: Translate audio streams in real-time using the Live Translation API - Get started with Veo: Get started with our video generation capabilities - Grounding: Use Google Search for grounded responses - Code execution: Generate and run Python code to solve complex tasks and even output graphs >This cookbook provides a structured learning path for using the Gemini API, focusing on hands-on tutorials and practical examples. Repository google-gemini/cookbook Repository stats |Metric|Value| |:-|:-| |Stars|17,881| |Forks|2.8k| |Last release|None| |Languages|Jupyter Notebook 99.6%, Other 0.4%| |Contributors|127| |AI contributor accounts (Claude / Codex / Cursor / Copilot)|None| |AI co-authored commits|None| Main contributor |Field|Value| |:-|:-| |Name|Guillaume Vernade| |GitHub|@Giom-V| |Commits to this repo|269 (top contributor)| |Bio|Started in innovation, moved to Agile and lived the dream of video gam| |Company / Location|Google / Paris and Rennes| |Followers|264| ────────────────────────────── 📌 If you want to browse more repos like this, we've organized them by category and rankings here: bestgithubrepositories.com 🗂️ We're also archiving repos where possible, so useful projects don't disappear when they're removed from GitHub.
Cloned a Stranger's Repo? Check 6 Agent Config Files Before Claude Code or Codex Opens It - Book: Prompt Engineering Pocket Guide - Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go - My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools - Me: xgabriel.com | GitHub --- You clone a repo to reproduce a bug someone reported. Before you have read a line of its code, you type claude in the folder and ask what is going on. That repo can carry its own settings for your agent. Claude Code's hooks reference lists .claude/settings.json as a hook location you can commit, and a hook of type command is a shell command that runs on events like SessionStart or PreToolUse. The same is true, with different file names and different rules, for Codex and Gemini CLI. Every one of these agents has a trust gate for exactly this. The gates work differently from agent to agent, one of them is off by default, and Claude Code's never appears in claude -p. So read the files before the agent does. It takes about a minute with git grep and jq. The six files, and what each one can make an agent do 1. .claude/settings.json: hooks that run shell commands, an env block, and helper commands such as apiKeyHelper (permissions docs). A .claude/settings.local.json that is tracked in git counts as repository-supplied too. 2. .mcp.json: project MCP servers for Claude Code. A stdio server is a command plus args, so connecting it starts a process on your machine (MCP docs). 3. .gemini/settings.json: Gemini CLI hooks, which "execute arbitrary code with your user privileges" per its hooks page, and mcpServers. A server with "trust": true "bypasses all tool call confirmations for this server" (MCP server docs). 4. .codex/config.toml and .codex/hooks.json: Codex project config can define [mcp_servers.<name>] tables (Codex MCP docs) and hooks, inline or in hooks.json (advanced config). 5. AGENTS.md: Codex reads one per directory from the project root down to where you started it, up to 32 KiB combined by default (AGENTS.md docs). Claude Code reads it when there is no CLAUDE.md (memory docs). 6. CLAUDE.md: loaded at the start of every Claude Code session. It can pull in other files with @path imports, up to four hops deep (memory docs). The first four can start processes. The last two are prose, but they are prose handed to an agent that can run your shell. !A cardboard box labelled as a cloned repo, opened under a large magnifier, with small gears, plugs and a folded note hidden among the files Settings, servers and instructions all ride along in the clone. What each trust prompt actually gates Claude Code. Start an interactive session in a folder you haven't trusted and the workspace trust dialog comes first. The project's permissions.allow rules and additionalDirectories wait for it, and the dialog lists them (permissions docs). Servers in .mcp.json get their own approval prompt, and a clone can't pre-approve them: enableAllProjectMcpServers committed in the repo is ignored in an untrusted folder (MCP docs). The gaps are documented in the same table. In claude -p or the SDK, where no dialog can appear, hooks from settings files and the env block are used, and .mcp.json servers connect "without asking, approved or not." Hooks and env also apply when you trusted only a parent folder, which covers a downloaded archive that isn't its own git repo. For a -p run in a repo you didn't write, the docs offer --setting-sources user, --bare (which still applies the project's env block), or --settings '{"disableAllHooks": true}'. Setting disableAllHooks in your user settings alone isn't enough, because project settings take precedence and can set it back. One detail for worktree users: in a worktree, Claude Code keys trust on the main checkout's root, so trusting the clone once covers every worktree of it. Codex. "Codex loads project-scoped config files only when the project is trusted" (advanced config). Untrusted, it skips the project's .codex/config.toml, project hooks and project rules, and your user config still loads. Some keys never load from a project file at all, including openai_base_url, model_provider and notify, which the docs tie to credential redirection and machine-local commands. The AGENTS.md page says nothing about trust, so assume it is read either way. Gemini CLI. Trusted Folders is "disabled by default." Turn it on with security.folderTrust.enabled: true in your user settings. Then a first run in a folder asks you to trust it, and "Don't trust" skips the project's .gemini/settings.json and .env, keeps MCP servers from connecting and turns off tool auto-accept. v0.65.0, released October 20, 2026, includes a fix titled "enforce read-only workspace settings in untrusted folders" (#29583). The notes list only the title, so read it as tightening that safe mode, not as trust being on by default now. Gemini CLI also fingerprints project hooks: a hook whose name or command changes, say after a git pull, is treated as new and you are warned before it runs (hooks page). For unpaid-tier and Google One users, Gemini CLI was replaced by Antigravity CLI on June 18, 2026, per the same page. The one-minute audit Run this in a plain shell, not inside an agent session. The agent session is the thing you're vetting. Every command only reads. cd ~/code/their-repo # 1. Which agent files does the repo ship? p='(^|/)\.(claude|codex|gemini)/|(^|/)\.mcp\.json$' p="$p"'|(^|/)(CLAUDE|AGENTS|GEMINI)[^/]*\.md$' git ls-files | grep -E "$p" # 2. Symlinks can point an agent file outside the repo git ls-files -s | awk '$1 == "120000" { print $4 }' Then read what the config files would run: # 3. Claude Code: every command, plus env and MCP approvals for f in .claude/settings.json .claude/settings.local.json; do [ -f "$f" ] || continue echo "== $f" jq -r '.. | objects | .command // empty' "$f" jq '{env, apiKeyHelper, enableAllProjectMcpServers, enabledMcpjsonServers}' "$f" done # 4. Project MCP servers: what each one would start [ -f .mcp.json ] && jq '.mcpServers | map_values({command, args, url})' .mcp.json # 5. Gemini CLI: hooks, servers, servers marked trust: true g=.gemini/settings.json [ -f "$g" ] && jq '{hooks, mcpServers}' "$g" [ -f "$g" ] && jq -r '.mcpServers // {} | to_entries[] | select(.value.trust == true) | .key' "$g" # 6. Codex: tables and commands in project config and hooks c=.codex/config.toml [ -f "$c" ] && grep -nE '^\[|command' "$c" [ -f .codex/hooks.json ] && jq . .codex/hooks.json Then the prose files, and who touched the config last: # 7. Instructions: downloads, URLs, hidden comments, imports q='curl|wget|base64|https?://|<!--' q="$q"'|(^|[[:space:]])@[~/.]' git grep -nE "$q" -- '*CLAUDE*.md' '*AGENTS*.md' '*GEMINI*.md' # 8. When did agent files change, in which commit, by whom? git log --format='%h %ad %an %s' --date=short \ -- .claude .codex .gemini .mcp.json \ '*CLAUDE*.md' '*AGENTS*.md' '*GEMINI*.md' Step 7 looks for HTML comments because a rendered Markdown view hides them and the agent reads the raw file. It looks for imports that start with ~, / or a dot because those can reach outside the repo; Claude Code asks before loading such external imports the first time (memory docs), but you want to know what they point at before that question comes up. What you're looking for: a hook that pipes a download into a shell, any command that writes outside the repo, an MCP server you can't name, a server marked trust: true, an env value you can't explain, and a config change that landed in the most recent commit from an account you don't know. Most repos print nothing for steps 3 to 6, which is the answer you want. Running it in Hermes IDE I build Hermes IDE, so weigh this section with that in mind. Hermes runs each agent in its own real terminal, and plain shells open the same way, so the audit fits before the first agent starts. Add the clone as a project and open a plain shell session on it. Run the audit there. Hermes can split panes right or down, so the shell can stay next to whatever you start after it. Only when the output is clean, press ⌘N (Ctrl+Shift+N on Windows and Linux) to start the task. The agent starts on its own hermes/<name> branch in its own worktree, and the sheet shows the exact command Hermes will run before you launch it. !The Hermes New task sheet with a refund-endpoint task typed, chips for Claude Code, the orders-api project, a new hermes/ worktree, Accept edits, model and effort, and a preview of the claude command Hermes will run The ⌘N New task sheet: agent, project, a new hermes/ worktree, approval mode, model and effort, and the "Hermes will run" preview of the claude command. Be clear about what the worktree buys you. It keeps the agent's edits off your branch. It is not a sandbox: a worktree holds the repo's tracked files, so the same .claude/settings.json sits in it. Hermes never answers a permission prompt for you, so the trust dialog and the MCP approval still come to you in the agent's own terminal, and the audit is what makes "yes" an informed answer. Hermes has one repo file of its own that runs commands: .hermes/worktree.toml, a list of setup commands for new worktrees. The recipe docs say Hermes shows the commands the first time it sees the file, and again whenever it changes, and that "Nothing runs until you choose Run setup." Skip starts the session without setup. In a stranger's repo, add cat .hermes/worktree.toml to the list above. What the audit won't catch Grep can't judge prose. An AGENTS.md line that says "run the bootstrap script before answering" looks the same whether the script is fine or not. Claude Code's docs say CLAUDE.md is treated "as context, not enforced configuration," which cuts both ways: it can't force anything, and it can still steer an agent you've allowed to run commands. Read the instruction files in full when the repo matters. The agent also runs the project's own code once you approve it: install scripts, test runners, build steps. Those deserve the same suspicion as a hook. For anything you truly don't trust, Anthropic's security page recommends using virtual machines to run scripts and make tool calls, and offers dev containers and a sandbox runtime for more isolation. Next time a bug report links a repo, run steps 1 and 3 before you type claude. --- If this was useful Half of the files in this post are prompts: AGENTS.md, CLAUDE.md and their imports decide what your agent believes about a repo before you say a word. The Prompt Engineering Pocket Guide covers how system prompts and instruction files steer a model, so you can read a stranger's AGENTS.md the way the agent will. And if you want the audit-then-launch flow in one window, Hermes IDE is free on macOS, Windows and Linux, and source-available on GitHub. 
Stop Comparing Models. Same Claude, 58% or 76% on Terminal-Bench, Depending on the Harness - Book: Prompt Engineering Pocket Guide - Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go - My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools - Me: xgabriel.com | GitHub --- Claude Opus 4.6 scored 58.0% on Terminal-Bench 2.0 with Claude Code driving it, according to the Terminal-Bench 2.1 release notes. Inside Meta-Harness, an agent scaffold published by the stanford-iris-lab group on GitHub, the same model scored 76.4% on the same 89 tasks, five trials each. That is an 18-point swing, and the model never changed. Meanwhile the thread in your team chat is still about Opus vs GPT vs Gemini. The model is one dial. The harness around it, meaning the tools it gets, the way it edits files, what goes into its context and how it recovers from a bad turn, is another dial. On public agent leaderboards, the second one moves scores about as much as the first. So the benchmark you should trust is your agent on your repo. What Terminal-Bench actually ranks Terminal-Bench gives an agent a task in a container and checks the final state with tests. The leaderboard doesn't rank models. It ranks agent-model pairs. The Terminal-Bench 2.1 leaderboard, as published on Snorkel AI's site, lists 18 entries, and five models appear under two different agents. Each pairs the vendor's own CLI (Claude Code, Codex CLI or Gemini CLI) with Terminus 2, the harness the leaderboard credits to the Terminal-Bench team: | Model | Vendor's own agent | Terminus 2 | |---|---|---| | Claude Fable 5 | Claude Code: 83.8% ±1.2 | 80.4% ±1.2 | | GPT-5.5 | Codex CLI: 83.1% ±1.1 | 78.0% ±1.2 | | Claude Opus 4.7 | Claude Code: 68.9% ±1.4 | 66.1% ±1.4 | | Gemini 3 Pro | Gemini CLI: 65.8% ±1.4 | 73.9% ±1.3 | | Gemini 3.1 Pro | Gemini CLI: 65.8% ±1.7 | 65.6% ±1.7 | Row by row, the vendor agent doesn't always win. Claude Code and Codex CLI beat Terminus 2 with their own models, by 2.8 to 5.1 points. Gemini 3 Pro scored 8.1 points higher in Terminal-Bench's generic harness than in Google's own CLI. Gemini 3.1 Pro came out level in both. Compare that 8.1-point harness gap to a model upgrade on the same board. Inside Claude Code, going from Opus 4.7 to Opus 4.8 moved the score from 68.9% to 78.9%. That is 10 points for a model upgrade against 8.1 for a different wrapper around one model, and 8.1 is the biggest such gap on this board. The gap is as big as a model generation Two rows are an anecdote. A survey paper from June 2026, From Question Answering to Task Completion, went through the Terminal-Bench 2.0 leaderboard and the public submission logs (Section 7.4). Across the 20 models with at least three harness results, the median gap between a model's best and worst harness was 13.6 points. For scale, the authors note that a stronger model generation often adds more than 10 points inside a fixed harness. Their table for Claude Opus 4.6 on Terminal-Bench 2.0 shows how wide it gets: | Harness | Score | Input tokens (K) | Timeout rate | |---|---|---|---| | Meta-Harness | 76.4% | 755.0 | 7.9% | | Terminus-KIRA | 74.7% | 618.6 | 18.2% | | Terminus 2 | 62.9% | 79.4 | 18.2% | The same paper puts Gemini 3.1 Pro anywhere from 59.4% to 80.2% and GPT-5.3 Codex from 64.7% to 78.4%, depending on the harness. The authors are careful here, and you should be too: "The resulting evidence is not a randomized ablation." Public submissions can differ in prompts, versions and budgets. Some of an 18-point gap may be reasoning effort or token budget rather than pure harness design. Part of Claude Code's 58.0% also came from broken tasks that 2.1 later fixed. If budgets and prompts move the score that much, they are part of what you are choosing when you pick an agent, and none of them are the model. What a harness changes Tools. mini-swe-agent is "some 100 lines of python" and "does not have any tools other than bash." Terminus 2 gives the model a single tool too, but it is an interactive tmux session where the model sends keystrokes, scrolls output and can open extra shells. Terminus-KIRA, built on Terminus 2, swaps its JSON/XML parsing for the model's native tools parameter. The model gets the same task either way; only the way it is asked to act differs. Context. Meta-Harness extends KRAFTON's Terminus-KIRA. Before the agent loop starts, it collects a snapshot of the sandbox (working directory, files, available languages, package managers, memory) and puts it in the first prompt. Its README says that saves 2 to 5 early exploration turns. Terminus 2 summarizes the middle of the history when free tokens drop below a threshold (8,000 by default) and keeps the system prompt and task intact. Look at the input-token column above: Meta-Harness fed Opus 4.6 roughly ten times the input of Terminus 2. Edit format. aider's leaderboard records which edit format each run used. Qwen2.5-Coder-32B-Instruct has two runs there: 16.4% returning whole files and 8.0% returning diffs. The diff run went through a different hosting provider, and only 71.6% of its edits were well-formed, so edit format is not the only variable. Same weights, half the score. Aider's own edit format docs say it plainly: "Different models work better or worse with different edit formats." Recovery. Timeouts, retries and when to give up are harness decisions. In the survey's table, Terminus-KIRA timed out on 18.2% of Opus 4.6 trials and Meta-Harness on 7.9%. Even the harness ranking moves Terminal-Bench 2.1 fixed 28 of the 89 tasks in 2.0: dependencies that had changed, resource budgets too small for valid approaches, instructions that didn't match their tests. Claude Code with Opus 4.6 went from 58.0% to 70.1%, the largest gain the release notes report. Terminus 2 with Opus 4.6 scored 63.8% on 2.1. Put that next to the survey's 62.9% for Terminus 2 on 2.0. On the old task set, Claude Code trailed Terminus 2 with the same model. On the fixed task set, it led by 6.3 points. The model was the same; only the tasks changed, and the lead flipped. So part of the 18-point gap in the opening was broken tasks hitting one harness harder than another. That is still a harness effect, and it is the kind you won't see until you run your own tasks. Your repo is another task set. It has its own build quirks, its own test runner and its own idea of a clean diff. A harness that wins on 89 containerised terminal tasks has not been tested on any of that. If you do want a clean model ranking, Vals AI's Terminal-Bench 4.0 board runs every model through mini-swe-agent with "a single tool, bash." As of October 16, 2026, Claude Opus 5.5 leads it at 65.15%, and Vals notes its 4.0 scores are not directly comparable to 2.1, where Vals's own runs used Terminus 2. It is a fair model comparison, but unless a 100-line bash loop is the agent you code with every day, it isn't your setup. Race two harnesses on your repo The useful experiment holds the model still and swaps the harness. Pick the model you already pay for and run it in two agents on the same ticket. OpenCode can sign in to OpenAI with a ChatGPT Plus or Pro plan or an API key, so GPT in Codex vs GPT in OpenCode is one pairing. For Claude in OpenCode, use an Anthropic API key: OpenCode's docs say Anthropic "explicitly prohibits" using Claude Pro/Max plans through third-party plugins. Give each agent its own branch and folder, cut from the same commit: git worktree add -b race/claude-code ../race-claude-code git worktree add -b race/opencode ../race-opencode Start one agent in each folder with the identical prompt. When both stop, compare what each one left behind. A new worktree has no node_modules, so the loop installs before it tests. Swap npm ci && npm test for your own install and test commands: for wt in ../race-claude-code ../race-opencode; do echo "== $wt" git -C "$wt" status --short git -C "$wt" diff --stat main (cd "$wt" && npm ci && npm test) && echo PASS || echo FAIL done git diff --stat main covers tracked changes whether the agent committed them or not, and status --short catches new files. Then score each run on what you care about: - Do the tests pass without you touching anything? - How many files and lines changed, and were they the right ones? - How many times did you have to step in or answer a question? - What did the run cost in tokens or dollars? - Did it edit lockfiles, CI config or files outside the task? Do it on three to five real tickets, not one. Official Terminal-Bench 2.0 submissions run five trials per task (survey, Section 7.4) for a reason: one run on one ticket tells you very little. Running the race in Hermes IDE I build Hermes IDE, so weigh this section with that in mind. You don't need it for the experiment: the two git commands above do the isolation. Hermes sets up both worktrees and shows the runs side by side. Press ⌘N (Ctrl+Shift+N on Windows and Linux) and each task starts on its own hermes/<name> branch in its own worktree, with the task as the agent's first prompt. New worktrees get their dependencies in seconds. You pick the agent, model, effort and account per task. The agent runs its own interface in a real terminal, so you are testing that agent's harness and not a Hermes copy of it. !The Hermes New task sheet with its agent picker open, listing Claude Code and Codex as installed and the other supported agents below The ⌘N agent picker in Hermes 2.3.4: Claude Code and Codex installed, OpenCode, Aider, Antigravity CLI and the other supported agents listed, plus Custom agent. Start the ticket in Claude Code, then press ⌘N again and start the same ticket in OpenCode with the same Claude model, on an API key per the note above. If you're testing GPT instead, race Codex against OpenCode. Split panes put both sessions side by side, and the sidebar shows each session's status, context use, cost and branch. Spend is what the agent reports, or an estimate from its transcript marked as estimated. When both are done, the Review Desk (⌘G, Ctrl+Shift+G on Windows and Linux) shows each run's changes by turn or by file, so you can see how each harness got there. Land the winner. The other branch is plain git, so you can delete it or keep it for the next comparison. !Two agent sessions side by side in Hermes, Codex on one repo and Claude Code on another, each in its own worktree, with the sessions sidebar on the left Hermes 2.3.4: Codex and Claude Code side by side, each in its own hermes/ worktree, with status, context use, cost and branch per session in the sidebar. The judging is still yours: your tests and your read of the diff. Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It is not affiliated with Nous Research, Anthropic, OpenAI, Google or any other agent vendor named here. Download it or read the code on GitHub. Next time someone asks which model is best, ask them which harness they ran it in. Then ask what it scored on their repo. --- If this was useful A lot of what separates Meta-Harness from Terminus 2 is what reaches the model and when: a snapshot of the environment in the first prompt, a summary when the window fills, the instructions wrapped around each tool. That is prompt and context engineering, and it is the part of the harness you control in your own AGENTS.md and system prompts. My Prompt Engineering Pocket Guide is the short read on it. If you run the race above in Hermes IDE and something doesn't behave the way I described, open an issue on GitHub. 
One install gives Claude Code or Codex the whole Gemini API. 1. Images, video, voice, music 2. Ask about PDFs, audio, YouTube 3. Recordings to captions 4. Deep Research in the background I'd rather labs shipped this than another coding agent. google-gemini/gemini-api-cli t.co
コーディング AI に読ませていいもの・だめなもの ― 判断の3つの問いと回避策 Claude Code や Codex に仕事のコードを読ませる前に、「これは AI に読ませていいのか」で手が止まったことはないでしょうか。金融機関では「日本から出してはいけない」と言われることもあります。 この記事では、法令・ガイドラインの原文と、AWS・Google Cloud・Anthropic・OpenAI の公式資料を読んで、次の 3 点を整理します。 何を読ませてよく、何がだめか その判断を何で決めるか だめなときに、どう回避するか ! この記事は 2026 年 10 月時点の公式資料に基づく整理で、法的な助言ではありません。最終的な判断は、自社の法務・情報セキュリティ部門と確認してください。モデルの対応リージョンや料金は変わりやすいので、使う前に公式のページで確かめてください。 2026 年 7 月に個人情報保護法の改正法が成立しました(施行は公布から 2 年以内)。細かい決まりは、これから出る委員会規則やガイドラインで決まります。この記事は施行前の法律に基づいて書いています。 顧客から預かった資料(NDA の対象)を読ませるための契約・合意と、Claude Code の deny の設定の基本は、顧客資料を Claude Code に入れたいのに「ダメ」で止まって困ってないか?(以下、既存記事)にまとめました。この記事ではそれを前提に、判断の軸、分野ごとのルール、日本で完結させる方法を中心に書きます。既存記事と同じ内容は、繰り返さずにリンクで示します。 この記事の前提 項目 内容 対象の AI コーディング用の AI(Claude Code・Codex・Gemini CLI)。チャット型のサービスは扱いません 対象の読者 業務でコーディング AI を使うエンジニア。金融・公共・医療の方は、分野別の章もあわせて読んでください 時点 2026 年 10 月。Google Cloud の資料は 2026-10-22 更新のもの、AWS の単価は 2026 年 10 月の価格表 呼び方 Google Cloud の Vertex AI は、今の Google のドキュメントでは Agent Platform(Gemini Enterprise Agent Platform)と呼ばれています。この記事では「Agent Platform(旧 Vertex AI)」と書きます 結論:早見表 情報の種類ごとの判定を先に示します。判定は、後の章で示す原文をもとにした筆者の整理です。 情報の種類 判定 条件・回避策 公開済みのコード・文書 読ませてよい なし 自社のソースコード・設計書 条件つき 社内の格付けに従う。学習に使わない契約の経路を使う 認証情報(鍵・パスワード・トークン) 読ませない 読めないように設定する 本番の個人情報・取引データ 原則として読ませない ダミー、構造だけ、伏せ字にする マイナンバー 読ませない ダミーの番号を使う。暗号化してもマイナンバーのまま 本番のログ 条件つき 伏せ字にしてから渡す 他社から預かった情報 契約しだい 契約と合意を確認する(既存記事) 政府・自治体・医療・金融の情報 分野のルールに従う 分野別の章を見る あわせて、調べて分かった大きな点は次の 3 つです。 国として「データは日本に置け」と一律に決めた法律は見当たりません。国内に置くことを基本として明記しているのは、政府・自治体が自分のデータを置く場合と、医療です。金融や通信は「どこにあるかを把握し、説明する」という求め方です。 読ませていいかは、「情報の種類」と「出した先での扱い」(どこで処理し、保存され、学習に使われ、人が見るか)の組み合わせで決まります。 だめな場合でも、「形を変える」「出す先を選ぶ」「外に出さない」のどれかで回避できることが多いです。 判断の 3 つの問い 問い 1:その情報を社外に出してよいか AI に読ませた内容は、AI 事業者に送られます。どの経路で送られるか(ファイル、コマンドの出力、MCP など)は、既存記事の「「入れる」とは Anthropic に送ること」に表があります。最初に、その情報を社外に出してよいかを、法令・契約・社内規程の順に確かめます。 法令では、次の 2 つが関わります。 個人情報保護法:クラウドに置くことが「第三者への提供」に当たるかは、事業者がその中身を扱うことになっているかで決まります。契約で扱わないと決め、アクセスを制御していれば、提供には当たりません(個人情報保護委員会の Q&A 7-53)。外国の事業者のサーバーに置く場合も同じ考え方ですが、その国の制度を把握したうえで安全管理をし、本人が知り得る状態にする必要があります(Q&A 12-3)。 番号法(マイナンバー):マイナンバーは、決められた事務(個人番号関係事務など)以外で使えないように、アクセスを制御する必要があります(特定個人情報の Q&A A2-2)。開発やテストの作業はこの事務に当たらないと考えるのが自然なので、AI には読ませないのが原則です(筆者の整理)。 AI ならではの論点が 1 つあります。不正利用の検知のために、事業者が問い合わせを保存したり、人が中身を確認したりする経路があります(問い 2 で表にします)。こうした経路を「事業者が中身を扱わない」と言えるかは、はっきりしません。個人情報を扱う場合は、委託として整理し、学習に使わないことを確認するほうが確実です。個人情報保護委員会の生成 AI についての注意喚起の要点は、既存記事の「個人情報については当局の見解がある」にまとめています。 契約では、NDA の「第三者に開示しない」という条項が関わります。条項ごとの読み方は、既存記事の「NDA(秘密保持契約)とは」にあります。社内規程では、情報の格付け(機密性の段階)が関わります。金融の FISC は、サービスの利用形態によってはセキュリティ対策やデータの扱いを個別に設定できないことがある、としたうえで、次のように書いています(2024-09-24)。 そうしたセキュリティ要件を満たすことが困難な場合においては、意図せざる情報漏洩を防止する観点から、生成 AI において機密性が高い情報を取り扱うことは適当ではない。 問い 2:出した先でどう扱われるか 出してよい情報でも、出した先で次の 4 つがどうなるかを確かめます。 確かめること 例 どこで処理されるか 世界中のどこか(global)、ある地域の中、1 つのリージョンの中 保存されるか、どれくらいか 30 日、5 年、保存しない 学習に使われるか 契約や設定で決まる 人が中身を見ることがあるか 不正利用の検知で、人が確認する場合がある 学習と保存は、契約によって次のように変わります。Anthropic の契約ごとの違い(DPA の有無など)は、既存記事の「ステップ2: 契約を「第三者」から「委託先」にする」に詳しく書いています。 契約 学習に使うか 保存期間 Anthropic の Free(無料(ただし制限あり))・Pro・Max(有料・月額) 利用者が設定で選ぶ。Claude Code の利用分も対象 学習に使う設定なら 5 年、使わない設定なら 30 日 Anthropic の Team・Enterprise(有料)・API(有料・従量課金) 使わない 30 日。保存しない契約(ZDR)は条件つき Amazon Bedrock・Google Cloud 経由の Claude(有料・従量課金) 使わない(Anthropic の商用の扱い) 各クラウドの規定(次の表) OpenAI の Free(無料(ただし制限あり))・Plus・Pro(有料・月額) 学習に使う場合がある。設定で止められ、Codex の作業にもその設定が効く。Codex には、環境全体を学習に使うかどうかを決める別の設定(Include environments)がある 公式資料で確認できず OpenAI の Business・Enterprise(有料)・API(有料・従量課金) 既定で使わない 公式資料で確認できず クラウド側の、不正利用の検知のための保存は次のとおりです。 経路 保存の扱い Bedrock の Claude(Fable 5・5.1 以外) 保存の記載なし。Fable 5 より前の Claude は、データ保存の扱いに変更なし Bedrock の Claude Fable 5・5.1 すべての通信を最大 30 日保存。検知に引っかかったものは、AWS が人の目で確認する場合がある。処理したリージョンに保存 Bedrock の OpenAI の GPT(gpt-oss 以外) 検知に引っかかった通信を最大 30 日保存 Agent Platform の Gemini(Frontier Models などを除く) 検知で疑わしいものを最大 90 日、同じリージョンに保存。Cloud Master Agreement の顧客は既定で対象外 Agent Platform の Claude Fable・Mythos すべての問い合わせと回答を最大 30 日保存 Bedrock では、リージョンごとに「保存しない」(data_retention_mode: none)を設定できます。この設定のとき、保存が必要なモデルを呼ぶと、要求そのものが拒否されます。FISC の AI の考察が「30 日監視保有の仕組み」の理解を求めているのは、この種の保存のことです。 問い 3:道具がモデル以外に何を送るか コーディング AI は、モデルへの問い合わせ以外にも通信をします。コードや問い合わせの中身を送るものではありませんが、「何も外に出さない」という方針なら止めておきます。 道具 モデル以外の主な通信 止め方 Claude Code(Bedrock 経由) 利用状況・エラー報告・/feedback は既定で止まっている。WebFetch は、取りに行く URL のホスト名だけを api.anthropic.com に送って安全か確かめる。自動更新やリリースノートの取得もある skipWebFetchPreflight: true、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 Codex 利用状況(analytics)、フィードバック、更新の確認 analytics.enabled = false、feedback.enabled = false、check_for_update_on_startup = false Gemini CLI 利用統計(既定で有効。問い合わせの中身は送らないと明記) privacy.usageStatisticsEnabled: false Claude Code の /feedback で何が送られるかと、Anthropic の API に直接つなぐ場合の止め方は、既存記事の「ステップ4: 合意を設定で守る」にあります。 Codex が Bedrock を使うときに利用状況を送るかどうかは、公式資料に書かれていません。止める設定を明示しておくのが確実です。Codex の check_for_update_on_startup は、更新を組織で管理している場合にだけ止めるよう、公式資料に書かれています。 ~/.codex/config.toml check_for_update_on_startup = false [analytics] enabled = false [feedback] enabled = false { "privacy": { "usageStatisticsEnabled": false } } 1 つ目が Codex の設定、2 つ目が Gemini CLI の settings.json です。 手元の PC にも記録が残ります。Claude Code の会話の記録の扱い(30 日間、平文で保存。cleanupPeriodDays で短くできる)は、既存記事の「運用: 「説明できる状態」を保つ」にあります。Codex も CODEX_HOME の下に会話の記録を残します(history.persistence で調整します)。 分野別の追加ルール 分野ごとに、原文が求めていることを並べます。 分野 根拠 求めていること 国の約束 日米デジタル貿易協定 第 12 条・第 13 条(2020-01-01 発効) 事業の条件として、企業に国内のサーバーの利用や設置を求めない。金融も、金融当局が情報にいつでも直接アクセスできる限り同じ。政府の調達と政府が持つ情報は対象外 金融 FISC、金融庁の監督指針、サイバーセキュリティガイドライン 所在を把握し、契約で取り決め、当局の検査に応じられるようにする 政府 デジタル庁 DS-310(2025-05-27) データセンターは国内が基本 自治体 総務省のガイドライン(令和 7 年 3 月版) 機密性が高い情報は、国内のデータセンターに保存されることを確認する 医療 医療情報システムの安全管理に関するガイドライン 情報機器等が、国内法の適用と執行の及ぶ範囲にあること 通信 電気通信事業法施行規則 第 22 条の 2 の 23 外国の設備に保存する場合は、その国の名前を公表する 金融 金融で「日本から出してはいけない」と言われるのは、法令の条文というより、各社の規程や、検査・監査への説明のしやすさから来ている部分が大きいようです。原文が求めているのは次のことです。 FISC の報告書(2014 年 11 月、公式英語版から筆者訳):重要な業務や機密性の高い顧客情報を扱う場合は、適用される法律が特定できる程度まで、データのある国・地域を把握する。勘定系のように可用性と機密性が特に求められるシステムでは、データセンターの正確な場所を確認する。処理が複数の国にまたがって適用される法律がはっきりしない場合は、最も厳しい国の法律が適用されると考えて対応する。 FISC の AI の考察(2024-09-24):「30 日監視保有の仕組みや、クラウド環境が設けられるリージョン(海外/国内)などの各種仕様について十分な理解が求められる」。 金融庁の監督指針:外部委託の契約に「金融当局の銀行に対する検査・監督上の要請に沿って対応を行う際の取決め」を入れる。主要行等向けの指針は、外部委託に「海外で行われる場合も含む」と明記しています。 金融分野におけるサイバーセキュリティに関するガイドライン(2024-10-04):サードパーティとの契約に「データの所在・保管・保持・移転・廃棄に関する取決め」を明記する(2.6 ⑧)。ただし「一律の対応を求めるものではなく」、リスクに見合った対策をとる考え方です。 経済安全保障推進法:金融庁の解説(令和 6 年 6 月)は、「開発環境は…特定重要設備には該当しません」としています(Q1-5)。開発環境で AI を使う限り、この制度の届出の対象にはならないと読めます。 政府・自治体 政府と自治体は、自分のデータを置く場所として、国内を基本にしています。 デジタル庁 DS-310:「政府情報システムが利用する場合、クラウドのデータセンタの設置場所に関しては、国内であることを基本とする」。バックアップ用に海外に置くことは、準拠法と裁判管轄を確かめたうえで認めています。 ガバメントクラウドの基準:「データセンタの物理的所在地を日本国内とし、情報資産について、合意を得ない限り日本国外への持ち出しを行わないこと」。 自治体のガイドライン(令和 7 年 3 月版):「機密性が高い情報は、国内のデータセンターに保存されることを確認する必要がある」。 注目したいのは、ガバメントクラウドの令和 8 年度の調達仕様書(2025-12-26)です。国外でしか使えない最新の生成 AI のために「国外 AI 推論環境」を別に用意し、そこでは「推論の実行はできるが情報資産の永続的な保管はできない」としています。保存は国内、推論は国外も可、と分けて考える例です。政府のシステムのためのルールですが、民間で「推論だけ国外」を検討するときの物差しになります。 医療 医療情報システムの安全管理に関するガイドラインは、「情報機器等が、国内法の適用及び執行の及ぶ範囲にあること」を求めています(厚生労働省の WG 資料、2026-05-29 による)。同じ資料は、がんパネル検査のように実際には海外に保存されている医療情報もあり、実態に合わない可能性があるとして、見直しを検討するとしています。 通信・個人情報全般 電気通信事業法施行規則は、指定された事業者に、外国の設備に保存する場合の国の名前と、取扱いに影響するその国の制度の有無を公表させています。禁止ではなく、公表の義務です。個人情報保護法も、海外に置くこと自体は禁止していません(問い 1)。 回避策 だめ、または条件つきの情報は、次の 5 つで回避します。 回避策 何をするか 向いている情報 1. 読ませない 読めないように設定する 認証情報、除外すると決めた資料 2. 形を変えて読ませる ダミー、構造だけ、伏せ字 本番の個人情報・取引データ、ログ、マイナンバー 3. 出す先を選ぶ 日本で完結、保存しない、閉域 国内に置くことを求められる情報 4. 外に出さない 社内で動かす LLM を使う どの経路でも社外に出せない情報 5. 契約と規程を整える 委託契約、社内の格付け 他社から預かった情報、自社の機密 1. 読ませない Claude Code では、permissions.deny に Read のルールを書くと、そのファイルを読ませないようにできます。シェルの cat などにも効きますが、スクリプトが自分で開くファイルは防げないため、OS のレベルで止めるにはサンドボックスを使います。書き方と効く範囲は、既存記事の「ステップ4: 合意を設定で守る」にあります。 Codex のサンドボックスは、書き込みと実行を制限するものです。読み取りを止める設定は、公式資料では見つかりませんでした。読ませたくないファイルは、Codex を動かすフォルダに置かないようにします(フォルダの外を読めるかどうかは確かめていません)。 Gemini CLI は .geminiignore と .gitignore に従いますが、公式の説明は「検索のときに」除外するというものです。読み取りを完全に止める仕組みとしては扱わないでください。 2. 形を変えて読ませる 本番のデータを読ませなくても、多くの作業はできます。確実な順に並べます。 方法 例 注意 ダミーデータ 架空の顧客名・口座番号・マイナンバーで作ったテストデータ もっとも確実。本物と同じ形式(桁数・文字の種類)にそろえる 構造だけ テーブル定義(DDL)、件数、型、ファイルのレイアウト 中身の値は渡さない 伏せ字 氏名・電話番号・口座番号を置き換えたログ 対応表を持っていて元に戻せるなら、個人情報として扱う前提で考える 伏せ字には、法令上の注意が 2 つあります。 個人情報保護法の仮名加工情報は、本人の同意があっても第三者に渡せません。委託であれば渡せます(個人情報保護委員会の FAQ Q14-17)。 マイナンバーは、暗号化しても、数字をばらばらに分けても、マイナンバーのままです(特定個人情報の Q&A A9-2・A9-3)。テストには、ダミーの番号を使います。 3. 出す先を選ぶ(日本で完結させる) 日本で完結させられるかは、経路で決まります。 経路 推論する場所 日本で完結 Anthropic が運営(API、Claude Platform on AWS、Google Cloud の Anthropic managed) inference_geo で選べるのは global か us だけ。データの保存先も us だけ できない Amazon Bedrock JP の推論プロファイル(東京と大阪だけを行き来する)、または東京の中だけ モデルによってできる Agent Platform(旧 Vertex AI) Claude は global、us・eu、シンガポール・台湾の一部だけ Claude はできない。Gemini は一部できる Agent Platform の global について、Google は「データの所在を保証しない」と明記しています。 Bedrock で日本に閉じられる Claude AWS のモデルカードで確かめた、JP の推論プロファイルがある Claude と、東京リージョンの単価です。料金区分は有料(従量課金)で、単価は 100 万トークンあたりの入力/出力です(2026 年 10 月の AWS の価格表)。 モデル 推論プロファイル ID global の単価 日本に閉じた単価 Opus 5.5 jp.anthropic.claude-opus-5-5 $4/$20 $4.40/$22 Opus 4.8 jp.anthropic.claude-opus-4-8 $5/$25 $5.50/$27.50 Opus 4.7 jp.anthropic.claude-opus-4-7 $5/$25 $5.50/$27.50 Sonnet 4.6 jp.anthropic.claude-sonnet-4-6 $3/$15 $3.30/$16.50 Haiku 5.5 jp.anthropic.claude-haiku-5-5 $0.10/$0.50 $0.11/$0.55 Haiku 4.5 jp.anthropic.claude-haiku-4-5-20251001-v1:0 $1/$5 $1.10/$5.50 日本に閉じた単価は、global の 1.1 倍です。 Haiku 5.5 は、10 万トークンを超える問い合わせの単価が高くなります(日本に閉じた場合は $0.55/$2.75)。 日本からは global でしか使えないもの:Fable 5.1、Fable 5、Opus 5、Opus 4.6、Sonnet 5.5、Sonnet 5。 Opus 4.8・4.7 と Haiku 4.5 は、東京の中だけで処理する方法(Mantle というエンドポイント)もあります。 ! Anthropic の旧ページには Opus 4.6 に jp. の推論プロファイルがあると書かれていますが、AWS のモデルカードでは日本の推論プロファイルはありません。AWS は、データの所在に要件があるなら、プロファイル ID の頭の文字だけで行き先を判断せず、GetInferenceProfile で確かめるよう書いています。 Claude Code を日本で完結させる設定 Claude Code には落とし穴が 1 つあります。東京のように ap- で始まるリージョンでは、推論プロファイルとして apac.(アジア太平洋の複数のリージョンを回るもの)を優先します。モデルにそのプロファイルが無いと、ほかにあるプロファイルの中から選びます。何もしないと、日本の外に出るおそれがあります。 そこで、モデルを jp. の ID で固定し、管理用の設定(managed settings)で配ります。管理用の設定は、利用者が上書きできません。OS ごとの置き場所は、既存記事の「ステップ4: 合意を設定で守る」の表にあります。 { "allowedProviders": ["bedrock"], "env": { "CLAUDE_CODE_USE_BEDROCK": "1", "AWS_REGION": "ap-northeast-1", "ANTHROPIC_DEFAULT_OPUS_MODEL": "jp.anthropic.claude-opus-5-5", "ANTHROPIC_DEFAULT_SONNET_MODEL": "jp.anthropic.claude-sonnet-4-6", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "jp.anthropic.claude-haiku-5-5", "CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK": "1", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" }, "availableModels": [ "jp.anthropic.claude-opus-5-5", "jp.anthropic.claude-sonnet-4-6", "jp.anthropic.claude-haiku-5-5" ], "enforceAvailableModels": true, "skipWebFetchPreflight": true } 設定 役割 allowedProviders 接続先を Bedrock だけにする。個人のアカウントなどへの切り替えを止める AWS_REGION 東京を指定する。環境変数にも AWS の設定ファイルにもリージョンが無いと、us-east-1 になる ANTHROPIC_DEFAULT_OPUS_MODEL など 3 つ 3 つのモデルを jp. の ID で固定する。Haiku は、会話のタイトル作りなどの背景の作業に使われる CLAUDE_CODE_DISABLE_MODEL_ACCESS_FALLBACK モデルが使えないときに、別のモデルへ切り替わるのを止める availableModels・enforceAvailableModels 選べるモデルを jp. のものだけにする(enforceAvailableModels は v2.1.287 以降) CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC・skipWebFetchPreflight モデル以外の通信を止める(問い 3) Claude Code の Web 検索の機能は、Bedrock では使えません。 起動したら /status で、接続先とリージョンを確かめます。推論プロファイルの行き先は、AWS CLI で確かめます。 aws bedrock get-inference-profile \ --region ap-northeast-1 \ --inference-profile-identifier jp.anthropic.claude-opus-5-5 \ --query 'models[].modelArn' 返ってくる ARN のリージョンが ap-northeast-1 と ap-northeast-3 だけであれば、東京と大阪の中で処理されます。 AWS の側でも止める Claude Code の設定に加えて、AWS の組織の側でも止めておくと確実です。 global の推論を止める:AWS が公開している SCP の例です(Version と Statement の外枠を足しています)。 { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyGlobalCrossRegionInference", "Effect": "Deny", "Action": "bedrock:*", "Resource": "*", "Condition": { "StringEquals": { "aws:RequestedRegion": "unspecified" }, "ArnLike": { "bedrock:InferenceProfileArn": "arn:aws:bedrock:::inference-profile/global.*" } } } ] } 東京と大阪以外のリージョンを SCP で止める:行き先にほかのリージョンを含む推論プロファイル(apac. など)は、呼ぶと失敗するようになります。 保存しない:東京と大阪のリージョンで、データの保存を「しない」(data_retention_mode: none)にします。 閉域でつなぐ:PrivateLink のエンドポイント(com.amazonaws.ap-northeast-1.bedrock-runtime)を使います。 図にすると、次の形になります。 Codex と Gemini CLI の場合 Codex:Bedrock を接続先にする設定(amazon-bedrock と amazon-bedrock-runtime)が標準で入っています。モデルの利用料は Bedrock の有料(従量課金)です。ただし、Codex の資料に載っている GPT-6 系は、推論の場所が global・米国・us-east-1 などだけで、日本に閉じる方法がありません。AWS のモデルカードで確かめた GPT(GPT-5.4〜GPT-6 系)も、日本からは global でしか使えないか、日本では提供されていません。gpt-oss-120b・20b は東京の中で使えますが、Codex の Bedrock の設定で使えるかは公式資料に書かれておらず、試していません。 Gemini CLI:Agent Platform(有料・従量課金)の東京(asia-northeast1)で使えば、日本の中で処理すると明記されたモデルがあります。Gemini 3.5 Flash、Gemini 2.5 Pro(64k 版)、Gemini 2.5 Flash(128k 版)です。1M 版は対象外です。Gemini CLI の /model はサブエージェントが使うモデルを変えないと公式資料にあるため、ほかのモデルが使われないかは確かめてから使ってください。閉域でつなぐには、Cloud VPN や Interconnect の上で Private Service Connect を使います。 4. 外に出さない どの経路でも社外に出せない情報は、社内で動かす LLM に読ませます。 Codex は --oss で、手元の Ollama などのモデルを使えます。Ollama は本体が無料で、動かす PC や GPU は自前です。 ~/.codex/config.toml oss_provider = "ollama" Claude Code は、ゲートウェイ経由であっても、Claude 以外のモデルへの接続をサポートしていません。 Gemini CLI を社内のモデルで動かせるかは、確かめていません。 社内で動かすモデルは、クラウドの最新のモデルより性能が下がることが多く、機材の費用もかかります。すべての作業をここに寄せるのではなく、外に出せない情報を扱う作業だけに絞るのが現実的です。 5. 契約と規程を整える 他社から預かった情報を読ませるための、NDA の条項の確認と顧客との合意の進め方は、既存記事の「ステップ2」と「ステップ3」にあります。 委託契約には、金融のサイバーセキュリティガイドライン 2.6 ⑧ の項目が、分野を問わず使えます(抜粋)。 サードパーティとの役割分担・責任分界 監査権限 再委託手続 実施すべきセキュリティ対策 インシデント発生時の対応及び報告 データの所在・保管・保持・移転・廃棄に関する取決め 契約終了の条件及び契約終了時の取決め 社内規程では、格付けごとに使ってよい経路を決めておくと、現場で迷いません。次は筆者の例です。 格付け 例 使ってよい経路 公開 OSS、公開した文書 どの経路でも 社外秘 自社のソースコード、設計書 学習に使わない契約の経路(Team・Enterprise・API・Bedrock など。いずれも有料) 機密 顧客の情報を含む資料、勘定系の設計 日本で完結し、保存せず、閉域でつなぐ経路。顧客との合意も取る 持ち出し禁止 認証情報、マイナンバー、本番の個人情報 読ませない。ダミーに置き換える まとめ 国として「日本に置け」と一律に決めた法律は見当たりません。国内を基本とするのは政府・自治体と医療で、金融や通信は「所在の把握と説明」です。 読ませていいかは、3 つの問い(社外に出してよいか、出した先でどう扱われるか、道具が何を送るか)で決めます。 認証情報とマイナンバーは読ませません。本番のデータは、ダミーか構造だけにします。 日本で完結させるなら、Claude Code と Bedrock の JP の推論プロファイルの組み合わせです。モデルを jp. の ID で固定し、AWS の側でも global を止めます。Google Cloud の Claude と、Codex 用の GPT は、日本で完結させられません。 どこにも出せない情報は、社内で動かす LLM(Codex の --oss など)に任せます。 参考資料 関連記事 顧客資料を Claude Code に入れたいのに「ダメ」で止まって困ってないか? 入れられる状態にする契約・合意・設定 法令・ガイドライン Report of the Council of Experts on the Usage of Cloud Computing by Financial Institutions(FISC・2014-11、公式英語版。FISC のサイトが緊急メンテナンス中のため Wayback Machine の写し) 金融機関による AI の業務への利活用に関する安全対策の観点からの考察(FISC・2024-09-24、Wayback Machine の写し) 主要行等向けの総合的な監督指針 Ⅲ-3-3-4 外部委託(金融庁) 金融分野におけるサイバーセキュリティに関するガイドライン(金融庁・2024-10-04) 金融分野における経済安全保障推進法の特定社会基盤役務の安定的な提供の確保に関する制度の解説(金融庁・令和 6 年 6 月) DS-310 政府情報システムにおけるクラウドサービスの適切な利用に係る基本方針(デジタル庁・2025-05-27) ガバメントクラウド等の整備のためのクラウドサービスの提供 令和 8 年度募集 調達仕様書(デジタル庁・2025-12-26) 地方公共団体情報システムのガバメントクラウドの利用に関する基準 第 1.0 版(デジタル庁・2022-10、三重県のサイトに掲載) 地方公共団体における情報セキュリティポリシーに関するガイドライン 令和 7 年 3 月版(総務省) 医療等情報利活用ワーキンググループ 資料 5(厚生労働省・2026-05-29) 電気通信事業法施行規則(e-Gov 法令検索) Agreement between the United States and Japan concerning Digital Trade(USTR)/日米デジタル貿易協定(外務省) 個人情報保護委員会の FAQ:Q7-53・Q12-3・Q14-17 「特定個人情報の適正な取扱いに関するガイドライン(事業者編)」に関する Q&A(個人情報保護委員会) クラウド・道具 Claude in Amazon Bedrock・Data residency・Claude Platform on AWS・Claude Models on Google Cloud (Google managed)(Anthropic) Claude Opus 5.5 のモデルカード(ほかのモデルも同じ形式)・Supported Regions and models for inference profiles・Geographic cross-Region inference・Global cross-Region inference・Abuse detection・Data retention・VPC interface endpoints(AWS) Locations・Data residency・Zero data retention・Abuse monitoring・Private Service Connect(Google Cloud) Claude Code on Amazon Bedrock・Data usage・Network configuration・Permissions・Sandboxing・Settings reference・LLM gateway(Claude Code) Advanced Configuration・Configuration reference・Sandboxing・Use ChatGPT Work and Codex with Amazon Bedrock(Codex) How your data is used to improve model performance(OpenAI) Gemini CLI configuration(Gemini CLI)
📌 저장소 링크: 8위 제미나이 CLI google-gemini/gemini-cli ※ 개인, 무료 사용자는 Antigravity CLI로 이전됨: antigravity.google 7위 마이크로덕 pollen-robotics/microduck 6위 임페커블 pbakaus/impeccable 5위 클로드 하우투 luongnv89/claude-howto 4위 홀마크 Nutlope/hallmark 3위 AWS 에이전트 툴킷 aws/agent-toolkit-for-aws 2위 엔비디아 오픈셸 NVIDIA/OpenShell 1위 클라우드플레어 시큐리티 오딧 스킬 cloudflare/security-audit-skill