PaPoo
cover

無人実行と人間向け通知は、やっぱり同じ hook に載せると壊れる

読んでまず思ったのは、「その 19 回は、そりゃ刺さるよな」ということだった。
監査の nag 自体は、人間が画面の前にいるならかなり筋がいい。実装したついでに報告を飛ばしがちな場面を、その場で止められるからだ。でも記事を読んでいて引っかかったのは、その仕組みが launchd 経由の無人実行にもそのまま流れ込んでいた点で、ここはかなりありがちな落とし穴だと思った。

面白いのは、作者が「通知を止める」ために、通知の有無ではなく実行環境を見ているところだ。entrypoint を transcript の先頭から読んで、人間の端末で始まったのか、sdk-cli のような自動化で始まったのかを分ける。これ、言われてみれば当然なんだけど、実際には見落としやすい。ツールの挙動を「どこで動いたか」で切り替えないと、同じ hook が別の文脈でまったく違う意味を持ってしまう。

もう一つ、Stop hook に置いた判断も納得感があった。途中の tool call ごとにチェックすると、まだ状態が固まっていないのに監査を促すことになる。終わったタイミングで、「ちゃんと自己監査を書いたか」を見る方が筋がいい。しかも exit 2 と stderr を使ってモデルへのフィードバックにしているので、単なる人間向けの警告では終わらない。ここはかなり Claude Code っぽい設計だと思う。

ただ、こういう仕組みは便利なぶん、少しでも境界を読み違えるとすぐノイズになる。著者が「最大 2 回まで」に抑えたのも、その感覚なんだろう。監査は大事でも、毎ターン出ると儀式化して、かえって中身が薄れる。自動化を強くしたい人ほど、「人間が読むもの」と「機械が回すもの」を分ける感覚が要る、という話として読んだ。


参考: 19 Audit Nags in One Night: Making a Claude Code Stop Hook Detect Unattended Sessions

同じ著者の記事