ブログ
RSS技術やプロダクト開発に関する知見を発信しています
コーディングエージェントのhooksを共通のプロトコルに寄せる
社内で試験的に開発中のターミナルアプリで、Claude Code・Codex CLI・OpenCode・Grok Build の 4 つがタブの状態(実行中・承認待ち・完了・失敗)をどこまで自分から知らせてくるかを、生の PTY バイト列と各 CLI の hooks で測りました。ターミナルに流れてくるシグナルだけで 4 状態が揃う CLI は 1 つもなく、揃えるには CLI ごとの hooks を 1 つのプロトコルに変換するしかありませんでした。2026 年 9 月時点のバージョンでの結果です。
Renovateの緊急PRだけがCIで落ちる
pnpm 11 は公開から 24 時間未満のバージョンを既定で拒否し、Renovate は脆弱性修正の PR を即座に作るので、緊急の PR だけが CI で落ちます。Renovate 側でも待たせる案を考えていましたが、先行事例を調べると方向が逆でした。pnpm と Renovate の一次情報から、これからどう変えていくかを書きます。
PrefectのSecretブロックは暗号鍵の管理で注意していること
Prefect の Secret ブロックは、環境変数で鍵を渡さない限り、暗号化に使う Fernet 鍵を暗号文と同じ SQLite に平文で書きます。ドキュメントには「保存時に暗号化される」としかありません。ソースと実機で確かめた内容と、社内の自動化基盤で AI エージェント用の資格情報を置くときに決めた 2 つのルールを書きます。
git restoreがgit reset --hardの抜け道になっていたので、askで塞いだ
claude-bash-guardに、破壊的だが正当な理由で使うこともあるgit操作をask判定で5本追加しました。git reset --hardを止めるdenyメッセージ自身が代替として勧めていたgit restoreに、実はガードが掛かっていなかったという発見と、git checkoutを対象から外した理由を書きます。
ルールを増やす前に、ガードの迂回経路を塞いだ
gh向けのルールを積む前に、claude-bash-guard自体のコマンド解釈層に5つの迂回経路が見つかりました。モデルの素直な迂回を防げるかと、敵の難読化まで見抜く必要があるかという2軸に沿って3件を塞ぎ、2件は見送っています。実装の途中で見つかったコメント除去とlocalhost判定の既存バグ2件も書きます。
Bash実行ガードのテストに変異チェッカを足す
claude-bash-guardのテストスイートに、ソース文字列を1つずつ壊した変異体を作りテストが落ちるか確かめる変異チェッカを新設しました。テストが通ることとテストが効いていることは別だという前提のもと、実際に見つかった2つの穴と、あえてCIには組み込まなかった判断を書きます。
gh apiが全ルールの抜け道だったので、ホスト判定に割り切る
Claude CodeのBash実行ガードにghコマンドのルールを追加したところ、gh apiが全ルールの抜け道になることが分かりました。メソッド推論による判定案を検討したものの、最終的にはgithub.com以外のホストだけを見る形に単純化しています。実データに当てて見つかった3件の誤検知も書きます。
自社スキルにプロンプト監査をかける
Claude Fable 5 向けのプロンプト監査を社内標準のスキルとエージェントに当てた記録です。指示が丸ごと削られることを警戒して後回しにしていましたが、削除対象になったのは古いモデル向けに強い言い方をしていた文だけでした。
SKILL.md に必須の参照ファイルを注入する
SKILL.md に「この参照を読むこと」と書いても、読むかどうかはモデルの裁量です。毎回必要な参照は動的コンテキスト注入で本文に埋め込む形へ切り替えました。公式ドキュメントの記述、報告されている類似の症状、プラグインで配ったときの挙動を並べます。
AIは眠らない
Claude Code のメモリ機能を無効にしています。機能を否定しているのではなく、私の利用量では使うほうのコストが上回るためです。人間の睡眠が記憶に対して何をしているかを一次資料で確かめ、エージェント側に何が入っていないのかを並べました。
Bash実行ガードにask判定を追加する
Claude CodeのBash実行ガードはdenyしか返せず、破壊的だが正当な理由のある操作の置き場がありませんでした。Ruleにdecisionフィールドを足してask判定を追加し、メッセージの長さをdenyはモデルが読む詳しい説明に、askはユーザーが読む一文に分けています。実装の過程で見つかったテストの穴も書きます。
沈黙は語らない
「誰も何も言わない」を問題なしと読む運用が、エージェントを入れたあとで最初に壊れました。沈黙がそのまま通っていたのは、読み手がコストを払っていたからではなく、払ったと信じられる与信が相手に積まれていたからだった、という整理です。
ヘルパーを乗っ取られた前提で測っても脅威モデルの範囲は変えなかった
乗っ取られたヘルパーを模した別ターゲットHostileHelperを用意し、壊れたフレーム・RPC連打・capabilityの取り消し・bookmark設計・封じ込めの5項目でホスト側の耐性を実測しました。これまで範囲外としてきた「乗っ取られたヘルパー」は、測った上でも範囲外のままにしています。
他人の目は、同じ場所しか見なかった
エージェントのレビューゲートに人間のレビューの形をそのままなぞったところ、著者が自分で検証していることと同じ場所を見ていました。持ち込めるのは原理で手順ではないという整理と、AI向けに書いた指示は効いているかどうかを人間が読んでも判定できないという話です。
scopeを外したbookmarkで子プロセスにサブツリーを渡してみる
サンドボックス下の子プロセスへディレクトリのサブツリーを渡す正規の手段として、security-scoped bookmarkとsandbox extensionを検証しました。security-scoped bookmarkはプロセスの境界を越えられず、security scopeを外したplain bookmarkだけがopenat込みでサブツリーを開けるという、想定と逆の結果になりました。
削れと言われたのは、道しるべではなかった
「規定的な作り込みを削れ」という助言は、禁止形や思考手順のことを指しています。ヒントやフックやワークフローまで削れと読むと、裁量を渡したのに黙るエージェントが残ります。制約と整備を分けた上で、依存していた挙動を数え直した記録です。
JavaScriptCoreをプラグインごと子プロセスに切り出す
JavaScriptCoreのJSValue.call()は同期呼び出しで、プラグインがwhile(true)に入ると呼び出しスレッドが戻ってきません。試験的に開発しているターミナルアプリのプラグインをposix_spawnとsocketpair(AF_UNIX)で子プロセスへ切り出し、往復レイテンシp95 0.27msなど7項目を実測しました。
囲いを作れば、手綱は要らない?
エージェントの成果を決めているのは、モデルの賢さより何を観測できるかと何を触れるかでした。書き込み権限を取り返しがつくかどうかで層に分け、壊せない場所を先に作って承認そのものを減らした設定を、公開している dotfiles の実物とロボティクス側の議論に突き合わせます。
Email Worker の受信箱のキーを To ヘッダーではなくエンベロープの宛先にした
AI エージェント用の受信専用アドレスを Cloudflare Email Routing と Email Worker で作りました。リファレンス実装 agentic-inbox から外れて受信箱のキーをエンベロープの宛先から取った判断を軸に、ドキュメントにあって型に無い canBeForwarded、25 MiB の受信上限と 2 MB の行上限の差、Worker からは 550 を返せないこと、「受信専用」を決めているのはこの構成だということを、一次資料と実測で確かめます。
規約は、規約について嘘をつく
エージェントに読ませる規約が、実際の挙動と食い違ったまま残っていました。参照ファイルを読めと明示的に書いた指示が、その通りには動いていなかった件を起点に、規約そのものを検査した記録です。
