ð ãå®äºããä¿¡çšããªãïŒStopããã¯ãJSONLãèªãã§LLMã®åºåã匷å¶ãã
æ10äžã®å€§åŠçã ã£ãé ãäœæ¥ã人ã«ä»»ããããšãžã®ä¿¡é Œæã¯ãäžå¯§ã«é Œããã鲿ãèãããä¿¡ãããã®3ã¹ãããã§æç«ããŠãããšæã£ãŠããŸãããä»ã¯éããŸããæå120äžã®ä»ãä¿¡é Œã¯ä»çµã¿ãæ ä¿ãããã®ã ãšç¥ã£ãŠããŸããLLMãåãã§ãã
ãªããã®ä»çµã¿ãå¹ãã®ã
LLMã«å®è£ ãä»»ãå§ãããšãå¿ ãã¶ã€ããå£ããããŸãã
ãå®è£ ããŸããããããã¹ããéã£ãŠããŸããããå®äºã§ããã
ãã®3è¡ã®åŸãå®éã«åãããŠã¿ããšå£ããŠããããããã¯ã確ãã«åããŠã¯ãããèå¿ãªãšã©ãŒãã³ããªã³ã°ãæããŠãããå¢çå€ã§ãŒãé€ç®ããã䞊è¡å®è¡ã§ç«¶åããããããããå®äºãšèšã£ãŠãããå®äºããŠããªããç¶æ ã¯ãLLMã䜿ãéçºã®æå€§ã®ãã€ãºã§ãã
ææããã°çŽããŠãããŸããã§ããææããããã«ã¯èªåã现éšãŸã§è¿œããããªããã°ãªããªããããã§ã¯äººéã®ç®ãéãã³ã¹ããé«ãããŠãèªåŸåã®æå³ããããŸããã
解決çã¯ãLLMãèªåã§èªåã®åºåã審æ»ããç¿æ £ããããŒããŠã§ã¢ã¬ãã«ã§åŒ·å¶ããããšãã§ãã
ãã€ã³ãã¯ãç¿æ £ãã§ã¯ãªãã匷å¶ããšããèªã§ããLLMã¯ããã³ããã§ãå¿ ãã»ã«ãç£æ»ããŠãã ããããšæžãã°äžå®ç¢ºçã§åŸããŸããã§ãäžå®ç¢ºçã¯100%ã§ã¯ãããŸãããã»ãã·ã§ã³ãé·ããªãã°æç€ºã¯èãŸããã¢ãã«ã®èª¿åã«ãã£ãŠçç¥ãããŸããããã³ããã§ç¿æ £ã¥ããããšããã®ã¯ã貌ãçŽã§å®å šãæ ä¿ããããšããã®ãšåãã§ãã
Stopããã¯ïŒPostToolUseããã¯ã®çµã¿åããã¯ããããä»çµã¿ã§è§£æ±ºããŸãã**LLMãã»ãã·ã§ã³ãçµäºããããšããç¬éã«ããã®åºåããã¹ããã·ã§ã«ã¹ã¯ãªãããèªãã§ãããŒã¯ãŒããç¡ããã° exit 2 ã§ãããã¯ããã**LLMã¯èªåã®ãå®äºã宣èšãèªåã®ããŒãã¹ã«æåŠãããäœéšãããŸãã
ããã³ãããå¿ããŠããã¢ãã«ãéã£ãŠããã»ãã·ã§ã³ã10æéç¶ããŠãããã®ããã¯ã¯èµ°ããŸããç°å¢ãç£æ»ãèŠæ±ããã®ã§ãç£æ»ã¯ç¿æ £ã§ã¯ãªãç©ççãªå¿ èŠæ¡ä»¶ã«ãªããŸãã
ããäžã€éèŠãªèšèšå€æããããŸããäœæ¥ãç¡ãã£ãã¿ãŒã³ã¯ããã¯ãé»ãããããšããç¹ã§ãã
LLMãšäŒè©±ããã ãã®ã¿ãŒã³ã調æ»ã ãããŠäœãæžããªãã£ãã¿ãŒã³ã«ãç£æ»ããŠãã ããããšæ¯ååºãŠããããããã¯ç£æ»ã§ã¯ãªããã€ãºã§ããå®éãæåã®ããŒãžã§ã³ã§ã¯å šã¿ãŒã³ã«ç£æ»èŠæ±ãåºãŠããŸããã2026-07-11ã®ããã©ãŒãã³ã¹ç£æ»ã§ãç£æ»ãååŒåããŠæ¬é¡ãå£ããŠããããšããè©äŸ¡ãäžããã倿Žããã£ãã¿ãŒã³ã«ã ãçºç«ãããèšèšã«å€ãããŸããã
ãã®ã倿Žã®ãã£ãã¿ãŒã³ã ãããå®çŸããããã«ã2ã€ã®ããã¯ã飿ºããŸãã
PostToolUseããã¯ïŒaudit_flag_set.shïŒãããã¡ã€ã«ãæžããã»ç·šéãããã€ãã³ããåãåã£ãŠãã©ã°ãã¡ã€ã«ãç«ãŠãStopããã¯ïŒself_audit_stop.shïŒããã®ãã©ã°ãæŸãããã©ã°ãç¡ããã°é»ãããã©ã°ãããã°åºåããã¹ãã粟æ»ããããã®2ããã¯é£æºã«ãã£ãŠãéãã«åãã¹ãæã¯éãã§ãç£æ»ãå¿
èŠãªæã ã声ãäžããæ§é ã宿ããŸãã
å ããŠãããäžã€ã®èœãšã穎ãžã®å¯ŸåŠãçµã¿èŸŒãŸããŠããŸããsdk-cliçµç±ã®ç¡äººèªååã»ãã·ã§ã³ãžã®å¯Ÿå¿ã§ãã
launchdã§æ·±å€ã«èµ°ãèªååããããAgent SDKçµç±ã®ãã€ãã©ã€ã³å®è¡ããããã£ãç¡äººã»ãã·ã§ã³ã«ç£æ»èŠæ±ãåºããŠãèªã人éã¯ããŸããã2026-07-12ãäžæ©ã§ sdk-cli èªååã19ä»¶èµ°ããstderr ã«ç£æ»èŠæ±ã19ä»¶ç©ãŸãããšããäºæ
ãçºçããŸããã以æ¥ãã»ãã·ã§ã³å
é 15è¡ãèªãã§ "entrypoint":"sdk-cli" ãå«ãŸããŠããã°å³ã¹ãããããåŠçãå
¥ã£ãŠããŸãã人éã®ããã»ãã·ã§ã³ã«ã ãèªããããããšãã倿ã§ãã
ãããŠã»ãã·ã§ã³åœããæå€§2åãšããäžéãèšããŠããŸããåãã»ãã·ã§ã³å ã§äœåºŠããç£æ»ããŠãã ããããåºããšãã¢ãã«ãåå¿ãããã³ã«ãŸãç£æ»ãèµ°ããã«ãŒããèµ·ãããªã¹ã¯ããããŸããã»ãã·ã§ã³å¥ã®ã«ãŠã³ã¿ãã¡ã€ã«ã§2åãè¶ ãããé»ãããšããå®å šåŒã§ãã
ãã®ä»çµã¿ãå¹ãçç±ãäžèšã§ãŸãšãããšã**ã人éãã«ãŒã«ãå®ãããšã«æåŸ ããã®ã§ã¯ãªããã«ãŒã«ãç Žããªãæ§é ãäœãã**ãšããèšèšææ³ã§ããèªåŸåãšã¯LLMãä¿¡é Œããããšã§ã¯ãªããLLMãä¿¡é Œã§ããç¶æ ã匷å¶ããããšã§ãã
å šäœã®æµã
ãŸãããã¯é£æºã®å šäœåãã¢ã¹ããŒå³ã§ææ¡ããŸãã
Claude Code ã»ãã·ã§ã³
â
ââ ããŒã«å®è¡ïŒWrite / EditïŒ
â â
â ââ PostToolUseãã㯠â⺠audit_flag_set.sh
â ââ touch /tmp/claude-audit-pending-{sid}
â
â ïŒLLMããå®äºããšèšãããšããïŒ
â
ââ Stop ã€ãã³ã
â
ââ Stopãã㯠â⺠self_audit_stop.sh
â
ââ ãã©ã°ç¢ºèª: /tmp/claude-audit-pending-{sid}
â ãªã â exit 0ïŒé»ã£ãŠéãïŒ
â ãã â
â
ââ entrypoint確èªïŒsdk-cliïŒïŒ
â sdk-cli â rm flag; exit 0ïŒç¡äººã¹ãããïŒ
â human â
â
ââ åæ°ç¢ºèª: /tmp/claude-audit-prompted-{sid}
â ⥠2 â rm flag; exit 0ïŒäžéå°éïŒ
â < 2 â
â
ââ transcript JSONL ã Python ã§ããŒã¹
â ââ æåŸã® assistant ããã¹ããæœåº
â
ââ ç£æ»ããŒã¯ãŒãæ€çŽ¢
â ãã â exit 0ïŒåæ Œã»ç¡é³ïŒ
â ãªã â
â
ââ exit 2ïŒãããã¯ïŒ
ââ stderr ã«ä¿ãã¡ãã»ãŒãž â LLMãž
PostToolUseããã¯: audit_flag_set.shïŒå š6è¡ïŒ
#!/bin/bash
# PostToolUse(Write|Edit): ãã®ã¿ãŒã³ã§ãã¡ã€ã«å€æŽããã£ãå°ãã»ãã·ã§ã³å¥ã«ç«ãŠãã
# Stopããã¯(self_audit_stop.sh)ãæŸã£ãŠãã»ã«ãç£æ»ã®åºãå¿ããä¿ãã
sid=$(/usr/bin/python3 -c 'import sys,json;print(json.load(sys.stdin).get("session_id",""))' 2>/dev/null)
[ -n "$sid" ] && touch "/tmp/claude-audit-pending-${sid}" 2>/dev/null
exit 0
ãã®ããã¯ã¯ã·ã³ãã«ã§ããClaude Code ã Write ãŸã㯠Edit ããŒã«ãå®è¡ãããã³ã«åŒã°ããstdin ãã JSON ãåãåã£ãŠ session_id ãæãåºãã/tmp/claude-audit-pending-{sid} ãšãããŒããã€ããã¡ã€ã«ãäœãã ãã§ããtouch ã®å€±æã¯ç¡èŠïŒ2>/dev/nullïŒããåžžã« exit 0 ã§éããŸãã
ãã€ã³ãã¯ããã©ã°ãç«ãŠãã ãããšãã責åã®æç¢ºãã§ãã倿ã¯ãã¹ãŠ Stopããã¯åŽã«å§ããŸãã
Stopããã¯: self_audit_stop.sh ã®å®è£ 詳解
Stopããã¯ã¯67è¡ãããŸããåãããã¯ãé ã«èªãã§ãããŸãã
â ã»ãã·ã§ã³IDã»ãã©ã³ã¹ã¯ãªãããã¹ã®ååŸ
input=$(cat)
get() { /usr/bin/python3 -c "import sys,json;print(json.load(sys.stdin).get('$1',''))" 2>/dev/null; }
sid=$(printf '%s' "$input" | get session_id)
tpath=$(printf '%s' "$input" | get transcript_path)
input=$(cat) ã§ stdin ããããã¡ãªã³ã°ããget 颿°ã§ JSON ãã£ãŒã«ããåãåºããŸãã/usr/bin/python3 ããã«ãã¹æå®ããŠããã®ã¯ãã·ã§ã«ããã¯ãå®è¡ãããç°å¢ã§ã¯ PATH ãæå°æ§æã«ãªã£ãŠããããšãããããã§ãã
â¡ ãã©ã°ç¢ºèªïŒå€æŽã®ãªãã¿ãŒã³ãã¹ãããïŒ
flag="/tmp/claude-audit-pending-${sid}"
[ -n "$sid" ] && [ -f "$flag" ] || exit 0
$flag ãã¡ã€ã«ãååšããªããã°å³ exit 0ãããã§ããã¡ã€ã«ãè§Šããªãã£ãã¿ãŒã³ãã¯ãã¹ãŠã¹ã«ãŒãããŸãã
⢠sdk-cli æ€åºïŒç¡äººèªååã¹ãããïŒ
if [ -n "$tpath" ] && [ -f "$tpath" ] && head -15 "$tpath" 2>/dev/null | grep -q '"entrypoint":"sdk-cli"'; then
rm -f "$flag"
exit 0
fi
ãã©ã³ã¹ã¯ãªãã JSONL ã®å
é 15è¡ãèªã¿ã"entrypoint":"sdk-cli" ãå«ãŸããŠããã°ç¡é³ã¹ãããããŸããJSONL ã®ã¡ã¿ããŒã¿ãããã¯ã¯å
é æ°è¡ã«åºãŸã£ãŠããããããã¡ã€ã«å
šäœãèªãŸãã« head -15 ã§å€å®ã§ããŸãããã©ã°ã¯æ¶ããŠããæããŸãïŒæ®ããšæ¬¡ã®ã»ãã·ã§ã³ã«æã¡è¶ããªãããïŒã
⣠ã»ãã·ã§ã³åœãã2åäžé
prompted="/tmp/claude-audit-prompted-${sid}"
count=$(cat "$prompted" 2>/dev/null || echo 0)
if [ "$count" -ge 2 ]; then rm -f "$flag"; exit 0; fi
/tmp/claude-audit-prompted-{sid} ã«æ°å€ãæžã蟌ã¿ã2以äžãªãé»ããŸãããã®ã«ãŠã³ã¿ã¯ $((count + 1)) ã§ã€ã³ã¯ãªã¡ã³ããããããã¯æã«æžãçŽããŸãïŒåŸè¿°ïŒã
†JSONL ã Python ã§çŽæ¥ããŒã¹ïŒæåŸã® assistant ããã¹ãæœåº
last=$(/usr/bin/python3 - "$tpath" <<'PY'
import sys, json
msgs = []
try:
for line in open(sys.argv[1], encoding="utf-8"):
line = line.strip()
if not line:
continue
try:
o = json.loads(line)
except Exception:
continue
if o.get("type") == "assistant" or o.get("role") == "assistant":
m = o.get("message", o)
c = m.get("content")
if isinstance(c, list):
for b in c:
if isinstance(b, dict) and b.get("type") == "text":
msgs.append(b.get("text", ""))
elif isinstance(c, str):
msgs.append(c)
except Exception:
pass
print(msgs[-1] if msgs else "")
PY
)
ããããã®ããã¯ã®æ žå¿ã§ããClaude Code ã®ãã©ã³ã¹ã¯ãªãã㯠JSONLïŒ1è¡1ãªããžã§ã¯ãïŒã§ä¿åãããŠããŸããPython ã§1è¡ãã€èªã¿ãtype == "assistant" ãŸã㯠role == "assistant" ã®è¡ãæ¢ããcontent ãåãåºããŸãã
content ãé
åã®å ŽåïŒããŒã«åŒã³åºããšæ··åšãããªãã圢åŒïŒã¯ type == "text" ã®ãããã¯ã ããéããŸããæååã®å Žåã¯ãã®ãŸãŸè¿œå ããŸããæåŸã« msgs[-1]ãããªãã¡çŽè¿ã®assistantããã¹ãã¡ãã»ãŒãžã ããè¿ããŸãã
try / except ã§ãšã©ãŒãæ¡ãã€ã¶ããŠããã®ã¯æå³çãªãã§ã€ã«ãªãŒãã³èšèšã§ãããã©ã³ã¹ã¯ãªãããå£ããŠããŠããèªã¿èŸŒã¿ã«å€±æããŠãããããã¯ããªãã誀çãããèŠéãã蚱容ããèšèšã§ãã
â¥ ç£æ»ããŒã¯ãŒãæ€çŽ¢ãšãããã¯
rm -f "$flag"
[ -z "$last" ] && exit 0
if printf '%s' "$last" | grep -qE 'ç£æ»|朰ãã|æ¢ã«å
ç¢|ãããŠèŠéã|ã»ã«ãç£æ»|äžå±€|äºæž¬ã§ããäžå
·å'; then
exit 0
fi
echo $((count + 1)) > "$prompted"
echo "â ïž ã»ã«ãç£æ»æªå®æœãå®è£
/é
ç·ãããªãæµå¯Ÿçç£æ»(䞊è¡/倱ææ/åªç/å¢ç/ç§å¯å€/宿€èšŒ)ãæžãŸããå ±åã¯**3è¡ä»¥å
**ã§(èŠç¹ã®ã¿ã»è¡šãé·æçŠæ¢=2026-07-11ãã£ãŒãããã¯)ã軜埮ãªããç£æ»äžèŠ:çç±ãã®äžèšã§è¯ãã" >&2
exit 2
ãã©ã°ã¯å
ã«ããã§æ¶ããŸãïŒã«ãŒã鲿¢ïŒã$last ã空ãªãèªã¿åã倱æãªã®ã§ãã§ã€ã«ãªãŒãã³ã§ééã
ããŒã¯ãŒãæ£èŠè¡šçŸã¯ ç£æ»|朰ãã|æ¢ã«å
ç¢|ãããŠèŠéã|ã»ã«ãç£æ»|äžå±€|äºæž¬ã§ããäžå
·å ã®7ãã¿ãŒã³ã§ããã©ããäžã€ã§ãããã° exit 0ïŒåæ ŒïŒãäžã€ãç¡ããã°ã«ãŠã³ã¿ãã€ã³ã¯ãªã¡ã³ãããstderrã«ä¿ãã¡ãã»ãŒãžãåºã㊠exit 2 ã§ãããã¯ããŸãã
exit 2 ããªããããã¯ã«ãªãã®ããšããç¹ãè£è¶³ããŸããClaude Code ã®ããã¯ã¯çµäºã³ãŒãã§åäœãå¶åŸ¡ããŸããexit 0 ã¯æ£åžžééãexit 2 ã¯ãã¢ãã«ã«ãã£ãŒãããã¯ãè¿ããŠç¶ç¶ãä¿ãããšããæå³ãæã¡ãŸããstderrã«æžããã¡ãã»ãŒãžã¯ãã®ãŸãŸã¢ãã«ãžã®ãã£ãŒãããã¯ãšããŠæž¡ãããã¢ãã«ã¯ããªãæ¢ãããããããèªãã§ç£æ»ãæžãçŽããŸãã
ãã®ã¡ãã»ãŒãžã« 2026-07-11ãã£ãŒããã㯠ãšããæ¥ä»æ³šèšãå
¥ã£ãŠããã®ãå®éã®ã³ãŒããã®ãŸãŸã§ããæåã¯é·ã衚圢åŒã®ç£æ»ãèŠæ±ããŠããŸããããã衚ãé·æçŠæ¢ã»3è¡ä»¥å
ããšãããã£ãŒãããã¯ãå
¥ããã¡ãã»ãŒãžæèšãæŽæ°ãããŸãããããã¯ã®ã³ã¡ã³ãã¯ãã®çµç·¯ã®èšé²ã§ãã
å®è£ ã®è©³çް
ãªãã·ã§ã«ã¹ã¯ãªããã
self_audit_stop.sh ã¯Bashã§æžããŠãããŸããClaude Codeã®ããã¯ã¯ package.json ã®ããç°å¢ã§ããã°Nodeã§ãæžããŸãããç§ã¯ãããŠã·ã§ã«ã«ããŠããŸããçç±ã¯ãããã¯ãèµ·åããç°å¢ã¯æå°æ§æã®ã·ã§ã«ã ãããã§ãã
hooks.json ãèŠããšãECCïŒEverything Claude CodeïŒã®ããã¯ã¯ã»ãŒãã¹ãŠNodeã®ã¯ã³ã©ã€ããŒã§æžãããŠããŸããNodeã§ãåé¡ã¯ãããŸããããNodeãèµ°ãããã«ã¯ node ãžã®PATHãéã£ãŠããå¿
èŠããããŸããç§ã®ç°å¢ã§ã¯nvmã§Nodeã管çããŠãããããã€ã³ã¿ã©ã¯ãã£ãã·ã§ã«ïŒ.zshrcãèªãŸããç¶æ
ïŒã§ã¯PATHãéããŸãããlaunchdçµç±ã®æå°ã·ã§ã«ã§ã¯éããªããECCåŽã¯èªåã§Nodeå®è¡ãã¹ããšã³ããªãŒãã€ã³ãã«åã蟌ãããšã§è§£æ±ºããŠããŸããããããã«ã¹ã¿ã ããã¯ã«æ¯åæžãã®ã¯éå°ã§ãã
ã·ã§ã«ã¹ã¯ãªãããªã #!/bin/bash ã§ç¢ºå®ã« /bin/bash ã䜿ãããŸããPythonåŒã³åºãã ãã¯PATHã«äŸåããªããã /usr/bin/python3 ããã«ãã¹æå®ããŠãããããã ãèŠããŠããã°ããšã¯ã·ã§ã«çµã¿èŸŒã¿ã§æžããäŸåããŒãã§ç¢ºå®ã«åãããšããç£æ»ããã¯ã«æ±ããæå€§ã®æ§è³ªã§ããããã¯ãåããªããã°ç£æ»ãçŽ éãã«ãªãã®ã§ãããã¯èªäœã¯éããªãã·ã³ãã«ã«ããŸãã
ãã§ã€ã«ãªãŒãã³èšèšã®å²åŠ
ã³ãŒãã®è€æ°ç®æã« || exit 0ã2>/dev/nullãtry / except: pass ãæ£ã£ãŠããŸããããã¯æå³çãªãã§ã€ã«ãªãŒãã³èšèšã§ãã
[ -z "$last" ] && exit 0 # èªããªããã°ãã§ã€ã«ãªãŒãã³
except Exception:
pass
print(msgs[-1] if msgs else "")
ãã©ã³ã¹ã¯ãªãããèªããªãç¶æ³ã¯å®éã«èµ·ããŸããã»ãã·ã§ã³ãçªç¶åããŠJSONLãäžå®å
šãªãŸãŸæ®ã£ãŠãããšãããã¡ã€ã«ã·ã¹ãã ã®æš©éãå€ãã£ãŠãããšããPythonã®ããŒã¹äžã«Unicodeãšã©ãŒãåºããšãããããã£ãç°åžžç³»ã§ exit 2 ãè¿ããšãäœãããŠããªãã®ã«ã¢ãã«ããããã¯ãããŸãã
誀ãããã¯ã®ã³ã¹ãã¯ãèŠéãã®ã³ã¹ãããé«ããèŠéããç£æ»ã¯æ¬¡ã®ã¿ãŒã³ã§ïŒãã©ã°ãç«ãŠã°ïŒãŸãæŸããŸããã§ã誀ãããã¯ã¯ã¢ãã«ãããªãæ¢ãããããããè§£éããããšããŠäœèšãªã¿ãŒã³ãæ¶è²»ããå Žåã«ãã£ãŠã¯ããã¯ãžã®ä¿¡é Œã倱ãããŸããããŸãããã¯ã誀äœåããããšå€æããããããã®ããã¯ã¯å®è³ªç¡å¹ã§ãã
ãšã©ãŒã¯é»ã£ãŠéããç£æ»ã®ããå¿ããããããã¯ãžã®äžä¿¡ä»»ã®ã»ããé·æãã¡ãŒãžã倧ããããã®å€æããã§ã€ã«ãªãŒãã³èšèšã®æ ¹æ ã§ãã
ããŒã¯ãŒã7ãã¿ãŒã³ã®éžå®åºæº
if printf '%s' "$last" | grep -qE 'ç£æ»|朰ãã|æ¢ã«å
ç¢|ãããŠèŠéã|ã»ã«ãç£æ»|äžå±€|äºæž¬ã§ããäžå
·å'; then
exit 0
fi
7ãã¿ãŒã³ãèŠããšã倧ãã3çš®é¡ã«åãããŸãã
**ãç£æ»ããã»ã«ãç£æ»ã**ã¯æãçŽæ¥çãªããŒã«ãŒã§ããç§ãCLAUDE.mdã§ãæµå¯Ÿçã»ã«ãç£æ»ãæžãŸãããšæç€ºããŠããã®ã§ãã¢ãã«ãåŸãã°å¿ ããã®èªãå«ãæãæžããŸãã
**ãæœ°ããããæ¢ã«å ç¢ãããããŠèŠéãã**ã¯3åºåå ±åã®èªåœã§ãããæœ°ããïŒå¯ŸåŠæžã¿ïŒ/ æ¢ã«å ç¢ïŒå¯ŸåŠäžèŠïŒ/ ãããŠèŠéãïŒæå³çã«åŸåãïŒããšãã3åºåã§å ±åããããæç€ºããŠããã®ã§ããã®ã©ãããå«ãŸããã°ç£æ»ã¯å®æœãããŠããã
**ãäžå±€ããäºæž¬ã§ããäžå ·åã**ã¯è£å©çãªããŒã«ãŒã§ããæ·±ãç£æ»ããããšãèªç¶ã«åºãŠããèªã§ãããããã¯å°æ¥çã«åé€ããåè£ã§ããããŸããèªãå ·äœããããšãã¢ãã«ãããã®èªãå«ããã°éãããšã·ã§ãŒãã«ãããåŠç¿ãããªã¹ã¯ããããŸãã
ããŒã«ãŒããŒã¯ãŒãã¯å®æçã«èŠçŽãã®ãæ£è§£ã§ããã¢ãã«ããç£æ»ããŸãããã ãã§éãããšããåŸåã匷ããªãã°ãããå ·äœçãªèªãžå·®ãæ¿ããŸãã
ããã¯ã®ç»é²ïŒsettings.jsonãžã®æžãæ¹
audit_flag_set.sh ãš self_audit_stop.sh ã¯ãClaude Codeã®ãŠãŒã¶ãŒã¬ãã«èšå®ïŒ~/.claude/settings.json ã«çžåœïŒã®ããã¯ã»ã¯ã·ã§ã³ã§ç»é²ããŸããå®éã®èšå®åœ¢åŒã¯æ¬¡ã®éãã§ãã
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/audit_flag_set.sh"
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/self_audit_stop.sh"
}
]
}
]
}
}
matcher ã« Write|Edit ãšæžãã®ããã€ã³ãã§ãã* ã«ãããšBashããŒã«ã®å®è¡ã«ãåå¿ããŠãã©ã°ãç«ã¡ããã³ãã³ããèµ°ãããã ãã§ç£æ»ãèŠæ±ãããããšãã誀çºç«ãèµ·ããŸãããã¡ã€ã«ãæžããã¿ãŒã³ã«ã ãç£æ»ãæ±ãããã®ã§ããã¡ã€ã«æžã蟌ã¿ç³»ããŒã«ã ãã«ããããããŸãã
MultiEditãå«ãããå Žå㯠Write|Edit|MultiEdit ã«ããŸããç§ã®ç°å¢ã§ã¯ MultiEdit ã®äœ¿çšé »åºŠãäœãã®ã§ããã©ã«ãã§ã¯å€ããŠããŸãã
ç§ãè©°ãŸã£ã話
è©°ãŸãâ ïŒå šã¿ãŒã³ã§ç£æ»èŠæ±ãåºãŠã»ãã·ã§ã³ããããããªã£ã
äžçªæåã®ããŒãžã§ã³ã«ã¯PostToolUseããã¯ããããŸããã§ãããStopããã¯ã ãã§ãæ¯åç£æ»ãèŠæ±ããããšããå®è£ ã§ããã
# æåæã®èª€ã£ãèšèšïŒãã©ã°ãªãïŒ
last=$(python3 ã§JSONLãèªã)
if printf '%s' "$last" | grep -qE 'ç£æ»|...'; then
exit 0
fi
exit 2
çç¶ïŒäŒè©±ããã ãã®ã¿ãŒã³ã調æ»ããã ãã®ã¿ãŒã³ãæ¢åã³ãŒããèªãã ã ãã®ã¿ãŒã³ã«ãå šéšãã»ã«ãç£æ»ã宿œããŠãã ããããåºãŸããã1æéã®ã»ãã·ã§ã³ã§ç£æ»èŠæ±ã20å以äžç©ãŸããæ¬é¡ã®è°è«ã®ããã ã«ãç£æ»ããŠãã ããããå²ã蟌ãã§ããç¶æ ã«ãªããŸããã
åå ïŒãäœãã倿Žããã¿ãŒã³ããšãäŒè©±ã ãã®ã¿ãŒã³ããåºå¥ããä»çµã¿ããªãã£ãããšã§ãã
çŽãæ¹ïŒPostToolUseããã¯ã§ /tmp/claude-audit-pending-{sid} ãç«ãŠãStopããã¯ã§ãã®ãã©ã°ã®æç¡ãæåã«ç¢ºèªããèšèšã«å€æŽããŸããããã©ã°ããªããã°å³ exit 0ãããã§ãã¡ã€ã«æžã蟌ã¿ãçºçããã¿ãŒã³ã ãã«çµãããŸãã
CLAUDE.mdã«ã2026-07-11ã®ããã©ãŒãã³ã¹ç£æ»ã§ãç£æ»ãååŒåããŠæ¬é¡ãå£ããŠããããšããè©äŸ¡ãäžãããšèšé²ãããŠããã®ã¯ããã®æ¹ä¿®ã決æãããã£ããã§ããç£æ»ãæ¯ååºããšãã¢ãã«ãç§ãããŸããããšããæ £ããçããŠã圢åŒçãªäžè¡ãæžãã ãã®ã«ãŒãã£ã³ã«ãªããŸããå°ãªãåæ°ã§ç¢ºå®ã«å¹ãããã»ãããç£æ»ã®éã¿ãä¿ãããŸãã
è©°ãŸãâ¡ïŒæ·±å€ã«èªååããããèµ°ããã³stderrãspamããã
launchdã§æ·±å€2æã«èµ°ãç»åçæèªååãããããããŸãïŒObsidianã® hot.md ã«èšé²ãããŠããai-portraitsã®èªååã§ãïŒããã®ãããã¯Agent SDKçµç±ã§Claude Codeã»ãã·ã§ã³ãç«ã¡äžããåŠçãå®è¡ããŠçµäºãããšããç¡äººãããŒã§ããã
Stopããã¯ã远å ããç¿æããã°ãèŠããç°å€ããããŸãããstderrã«ãâ ïž ã»ã«ãç£æ»æªå®æœããã19件䞊ãã§ããŸããã
çç¶ïŒç¡äººã®èªååã»ãã·ã§ã³ã«æ¯åç£æ»èŠæ±ãåºãŠãstderr ã«ç©ãŸããã誰ãèªãŸãªãã9æéåŸã«ç§ãçºèŠãããŸã§äœã®æå³ããªãèŠåãåºç¶ããŠããŸããã
åå ïŒããã¯ãã誰ãå®è¡ããŠãããããåºå¥ããŠããªãã£ãããšã§ãã人éãã€ã³ã¿ã©ã¯ãã£ãã«äœ¿ãã»ãã·ã§ã³ãšãAgent SDKçµç±ã®ç¡äººãããã»ãã·ã§ã³ãåãããžãã¯ã§åŠçããŠããŸããã
çŽãæ¹ïŒãã©ã³ã¹ã¯ãªããJSONLã®å
é 15è¡ãèªã¿ã"entrypoint":"sdk-cli" ãå«ãŸããŠãããã確èªããåŠçã远å ããŸããã
if [ -n "$tpath" ] && [ -f "$tpath" ] && head -15 "$tpath" 2>/dev/null | grep -q '"entrypoint":"sdk-cli"'; then
rm -f "$flag"
exit 0
fi
head -15 ã§å
é ã ãèªãã®ã¯ãJSOLã®ã¡ã¿ããŒã¿ãå
é ã«åºãŸã£ãŠããããã§ãããã¡ã€ã«å
šäœãèªãå¿
èŠã¯ãªãã15è¡ã§ååå€å®ã§ããŸãããã®ãã©ã°ã¯Claude Codeãã»ãã·ã§ã³éå§æã«æžã蟌ããã®ã§ãsdk-cliãšã³ããªãŒãã€ã³ãã¯ãã®å€ã "sdk-cli" ã«ãªããŸãã
ã³ãŒãã®ã³ã¡ã³ãã« 2026-07-12: äžæ©ã§sdk-clièªåå19ä»¶ãstopspamãåãã ãšæ®ããŠããã®ã¯ããã®äºä»¶ã®èšé²ã§ããããã¯ãæžããç¿æ¥ã«å³åº§ã«çºçããã®ã§ãèšèšæŒããšããŠèšæ¶ãããŠããŸãã
è©°ãŸãâ¢ïŒç£æ»ã«ãŒããèµ·ããŠã»ãã·ã§ã³ãæ¢ãŸããªããªã£ã
ãã©ã°ãšsdk-cliæ€åºãå ¥ããåŸãæ°ããåé¡ãåºãŸãããç£æ»ãæžããã¿ãŒã³ã®æ¬¡ã®ã¿ãŒã³ã§ããäžåºŠç£æ»ãèŠæ±ãããã«ãŒãã§ãã
çç¶ã®è©³çްïŒ
- ã¢ãã«ãå®è£ ãæžã â PostToolUseã§ãã©ã°ãç«ã€
- ã¢ãã«ããå®äºããšèšã â Stopããã¯ãèµ°ã â ãã©ã°ããã»ç£æ»ãªã â
exit 2ã§ããã㯠- ã¢ãã«ãç£æ»ãæžã â ãã®ã¿ãŒã³ã§ãPostToolUseãèµ°ãããã§ã¯ãªãããStopããŸãèµ°ã
- ããã
rm -f "$flag"ã®ã¿ã€ãã³ã°ãåŸãéããŠãåã®ãã©ã°ãæ®ã£ãŠãã
ããã¯å®éã«ã¯ãã©ã°ã®æ¶ãå¿ãã§ã¯ãªããåæå®è£ ã§ãã©ã°ãæ¶ãäœçœ®ãééã£ãŠããããšãåå ã§ãããæåã¯ãããŒã¯ãŒããèŠã€ãã£ãããã©ã°ãæ¶ã / èŠã€ãããªãã£ãããã©ã°ãæ¶ãã exit 2ããšããæµãã§æžããŠããŸããã
# 誀ã£ãèšèšïŒãã©ã°æ¶ãã®ã¿ã€ãã³ã°ãé
ãïŒ
if grep -qE 'ç£æ»|...'; then
rm -f "$flag" # åæ Œæã ãæ¶ã
exit 0
fi
exit 2 # äžåæ Œæã¯ãã©ã°ãæ®ã
çç¶ïŒäžåæ Œã§ãããã¯âã¢ãã«ãç£æ»ãæžãâæ¬¡ã®Stopã§ãŸããã©ã°ããâãŸããããã¯ãåãã»ãã·ã§ã³å ã§ãç£æ»ããŠãã ããããé£ç¶ããŠåºãŸãã
çŽãæ¹ïŒãã©ã°ã¯exit 2ã®åå²ã«å
¥ãåã«å¿
ãæ¶ãèšèšã«å€ããŸããã
rm -f "$flag" # åçº: ãã®ã¿ãŒã³ã®flagã¯å¿
ãæ¶ã(ã«ãŒã鲿¢)
[ -z "$last" ] && exit 0
if printf '%s' "$last" | grep -qE 'ç£æ»|...'; then
exit 0
fi
echo $((count + 1)) > "$prompted"
exit 2
ãã©ã°ã¯ãã§ãã¯ã®çµæã«é¢ä¿ãªããStopããã¯ãèµ°ã£ãæç¹ã§æ¶ããŸããæ¬¡ã®Stopã§åãã»ãã·ã§ã³IDã®ãã©ã°ãæ®ãã®ã¯ããã®ã¿ãŒã³ã§ãŸããã¡ã€ã«ãæžããå Žåã ããã«éå®ãããŸãã
å ããŠãåäžã»ãã·ã§ã³å ã§2åãŸã§ããšããäžéãèšããŸããã
count=$(cat "$prompted" 2>/dev/null || echo 0)
if [ "$count" -ge 2 ]; then rm -f "$flag"; exit 0; fi
ã«ãŠã³ã¿ãã¡ã€ã«ã«1ã2ãæžãã2以äžã«ãªã£ããé»ããããã§ã«ãŒãã®å®å šåŒã宿ããŸããã
è©°ãŸãâ£ïŒJSOLã®contentãé åã®å Žåãããã¹ããå šéšç©ºã«ãªã£ã
Pythonã®ããŒã¹éšåãäžççžã§ã¯ãããŸããã§ãããåæå®è£ ã¯ããã§ããã
# 誀ã£ãå®è£
ïŒcontentãæåååæïŒ
c = m.get("content")
if isinstance(c, str):
msgs.append(c)
Claude Codeã®ãã©ã³ã¹ã¯ãªããã¯ãããã¹ãã ãã®ã¬ã¹ãã³ã¹ã§ã¯ content ãæååã§ãããããããŒã«åŒã³åºããšæ··åšããã¿ãŒã³ïŒã€ãŸããã³ãŒããèªãã§ããå®è£
ããããšããå
žåçãªã¿ãŒã³ïŒã§ã¯ content ã¯é
åã«ãªããŸãã
{
"role": "assistant",
"content": [
{"type": "text", "text": "ããã§å®è£
ããŸããã"},
{"type": "tool_use", "id": "...", "name": "Write", "input": {...}}
]
}
ãã®ãã©ãŒãããã§ isinstance(c, str) ã¯åœã«ãªããããã¹ããåããŸãããmsgs ã空ã®ãŸãŸ print(msgs[-1] if msgs else "") ã«å°éãã空æååãè¿ããŸãã空æååã¯ãã§ã€ã«ãªãŒãã³ã§ exit 0 ã«ãªãã®ã§ãç£æ»èŠæ±ãåºãªããªããŸããã€ãŸããç£æ»ãå¿
èŠãªã¿ãŒã³ãåžžã«çŽ éãã«ãªãããšãããµã€ã¬ã³ããã°ã§ãã
çç¶ãšããŠæ°ã¥ããã®ã¯ãå®è£
ã®ã¿ãŒã³ã«å
šãç£æ»èŠæ±ãåºãªããã§ããã調æ»ã¿ãŒã³ã¯æ£ããçŽ éãããã®ã«ãå®è£
ã¿ãŒã³ã§ãåºãªãã®ã¯ãããããããã¯ããããã°ã㊠$last ã®äžèº«ãèŠããšç©ºæååã«ãªã£ãŠãããPythonã®ããžãã¯ããã¬ãŒã¹ããŠé
å圢åŒã®ãã³ããªã³ã°æŒãã«æ°ã¥ããŸããã
ä¿®æ£åŸã¯é åãšæååã®äž¡æ¹ãåŠçããŸãã
c = m.get("content")
if isinstance(c, list):
for b in c:
if isinstance(b, dict) and b.get("type") == "text":
msgs.append(b.get("text", ""))
elif isinstance(c, str):
msgs.append(c)
é
åã®å Žå㯠type == "text" ã®ãããã¯ã ããéããããŒã«åŒã³åºãã®ãããã¯ã¯ç¡èŠããŸãããã®ããžãã¯ã«å€ããŠãããå®è£
ã¿ãŒã³ã§ç¢ºå®ã«ç£æ»èŠæ±ãåºãããã«ãªããŸããã
è©°ãŸãâ€ïŒç£æ»ã¡ãã»ãŒãžãé·ãããŠã¢ãã«ãåŸããªãã£ã
æåã® exit 2 ã®éã®ã¡ãã»ãŒãžã¯ããã§ããã
ã»ã«ãç£æ»ã宿œããŠãã ããã以äžã®èгç¹ã衚圢åŒã§å ±åããŠãã ããã
| èŠ³ç¹ | ç¶æ
| 詳现 |
|------|------|------|
| äžŠè¡ | | |
| å€±ææ | | |
| åªç | | |
ïŒäžç¥ïŒ
8è¡ã®è¡šãã³ãã¬ãŒããå«ãã200åè¿ãã¡ãã»ãŒãžã§ããã
çç¶ïŒã¢ãã«ã衚ãåããããšããŠ15ã20è¡ã®ç£æ»å ±åãæ¯åæžãããã«ãªããŸãããå ±åèªäœã¯äžå¯§ã§ããããã3ãã¡ã€ã«æžãæãã軜埮ãªä¿®æ£ãã§ã20è¡ã®è¡šãåºãŠããŸããæ¬é¡ã®å®è£ ã®è°è«ãç£æ»ã®è¡šã«åãããŠããŸããã»ãã·ã§ã³ã®èªã¿è¿ããå°é£ã«ãªããŸããã
2026-07-11ã®ãã£ãŒãããã¯ã¯ã衚ãé·æçŠæ¢ã»3è¡ä»¥å ãã§ããã
çŽãæ¹ïŒã¡ãã»ãŒãžã1è¡ã®æç€ºã«å§çž®ããŸããã
echo "â ïž ã»ã«ãç£æ»æªå®æœãå®è£
/é
ç·ãããªãæµå¯Ÿçç£æ»(䞊è¡/倱ææ/åªç/å¢ç/ç§å¯å€/宿€èšŒ)ãæžãŸããå ±åã¯**3è¡ä»¥å
**ã§(èŠç¹ã®ã¿ã»è¡šãé·æçŠæ¢=2026-07-11ãã£ãŒãããã¯)ã軜埮ãªããç£æ»äžèŠ:çç±ãã®äžèšã§è¯ãã" >&2
ã軜埮ãªããç£æ»äžèŠ:çç±ãã®äžèšã§è¯ãããšããéãéãäœã£ãã®ãå¹ããŠããŸãããããå ¥ããããšã§ãæ¬åœã«è»œåŸ®ãªå€æŽã§ã¯ãç£æ»äžèŠ:宿°å€æŽã®ã¿ããšãã1è¡ã§å®çµããããã«ãªããŸãããéèŠãªå€æŽã§ã¯ã朰ããïŒäžŠè¡æžã蟌ã¿ã¯ atomic rename ã§å¯ŸåŠæžã¿ããšãã1ã2è¡ãåºãŸãã
芳ç¹ãåæããªããã3è¡ä»¥å ããšããå¶çŽãçµã¿åãããããšã§ããç£æ»ã圢åŒçã«ééãããããã®é·ã衚ãã§ã¯ãªããæ¬åœã«åé¡ãããã°1è¡ã§ææããããšããè¡åã«å€ãããŸãããç£æ»ã®éã§ã¯ãªã質ãäžãã倿Žã§ãã
ã€ãŸãããã€ã³ã
ååã§æžãã5ã€ã®è©°ãŸãã¯å®è£ ããžãã¯ã®è©±ã§ãããããã§ã¯èšå®ã»ç°å¢ã»éçšé¢ã§åŒã£ããããããç¹ãç¶²çŸ ããŸããç§ãå®éã«èžãã ãã®ãã³ãã¥ããã£ã§èŠããããã®ãç®æ¡æžãã«ããŸãã
èšå®ã»ç°å¢ãŸãã
-
settings.json å ã®ãã¹ã«
~ã䜿ã£ãïŒã·ã§ã«ã®~å±éã¯ãããã¯ãåŒã°ããæå°ç°å¢ã§ã¯èµ·ããªãããšããããsettings.json ã®ã³ãã³ããã¹ã¯å±éæžã¿ã®çµ¶å¯Ÿãã¹ã§æžãã/Users/èªåã®ãŠãŒã¶ãŒå/.claude/hooks/audit_flag_set.shã®ããã«çŽæ¥æå®ããïŒãã®èšäºã§ã¯èªã¿ãããã®ãã~衚èšã䜿ã£ãŠããããå®éã®ãã¡ã€ã«ã¯çµ¶å¯Ÿãã¹ïŒã -
chmod +xãå¿ããïŒããã¯ãç»é²ããããã¡ã€ã«ããããã§ãäœãèµ·ããªãââã®å€§åã¯ãããls -la ~/.claude/hooks/ã§-rwxr-xr-xã«ãªã£ãŠããã確èªããªããã°chmod +x ~/.claude/hooks/*.shã§ä»äžãããGit管çããŠããå Žåã¯git add --chmod=+xããã.gitattributesã«*.sh eol=lf text eol=lfãšå®è¡ãããèšå®ãå ¥ããŠããã -
settings.json ã®ãã©ãŒããããééããïŒ
hooks.PostToolUseã¯é åã®äžã«ãªããžã§ã¯ãããã®äžã«ãŸãhooksé åãå ¥ãäºéæ§é ãJSONæ§é ã®ãã¹ã¯Claude Codeããµã€ã¬ã³ãã«ç¡èŠããã ãã§ãšã©ãŒãåºãªããããã¯ç»é²åŸã¯å¿ ãjq . ~/.claude/settings.jsonã§æŽåœ¢ããŠç®èŠç¢ºèªãããjqããªããã°python3 -m json.tool ~/.claude/settings.jsonã§ãå¯ã -
matcherã«Write|Edit|BashãšæžããïŒBashããŒã«ã®å®è¡ïŒgrepãã³ãã³ãå®è¡ïŒã§ããã©ã°ãç«ã¡ããã³ãŒãã調ã¹ãã ãã®ã¿ãŒã³ãã«ç£æ»èŠæ±ãåºããWrite|EditïŒãŸãã¯Write|Edit|MultiEditïŒã«éå®ãããMultiEditã远å ãããã©ããã¯MultiEditã®äœ¿çšé »åºŠæ¬¡ç¬¬ã -
/usr/bin/python3ãååšããªãïŒmacOS ã§ãXcode Command Line Toolsãå ¥ããŠããªãå Žåã/usr/bin/python3èªäœããã€ã³ã¹ããŒã«ããŸããïŒããèããŠããç¶æ ã«ãªã£ãŠãããããã¯ã®äžã§ãããèµ°ããšå¯Ÿè©±ããã³ãããåºãŠæ¢ãŸããxcode-select --installãäºåã«æžãŸããããHomebrewã®python3ã䜿ãå Žåã¯ãã«ãã¹ïŒ/opt/homebrew/bin/python3ãªã©ïŒã«æžãçŽãã
JSONL ããŒã¹ã»å®è¡ã¿ã€ãã³ã°ãŸãã
-
ã»ãã·ã§ã³éå§çŽåŸã®æåã®ã¿ãŒã³ã§ããã¯ãçŽ éãããïŒ
tpathãæž¡ãããŠããŠãããã©ã³ã¹ã¯ãªãããã¡ã€ã«ã®æžã蟌ã¿ãããã¯ããåŸã«ãªãã±ãŒã¹ãããã[ -f "$tpath" ]ãåœã«ãªãlastã空ããã§ã€ã«ãªãŒãã³ã§ééãããååã¿ãŒã³ã¯ããŸã æžããçŽåŸããšããç¶æ ãªã®ã§å®å®³ã¯å°ãªãã -
JSONL ã®æ«å°Ÿãäžå®å šãªè¡ã§çµãã£ãŠããïŒLLMã®å¿çãé·ãå Žåããã©ã³ã¹ã¯ãªãããžã®æžã蟌ã¿ãšStopããã¯ã®å®è¡ãã¬ãŒã¹ã³ã³ãã£ã·ã§ã³ãèµ·ãããæ«å°Ÿã®è¡ãéäžã§åãã JSON ã«ãªã
json.loadsãäŸå€ãæãããtry / except: continueã§è¡åäœã«ã¹ãããããŠããããå®å®³ã¯ãªãã1ã€åã®å®å šãª assistant ã¡ãã»ãŒãžã䜿ã£ãŠå€å®ããã -
contentãNoneã®ã¿ãŒã³ïŒããŒã«åŒã³åºãã ããå«ãassistantã¡ãã»ãŒãžïŒããã¹ããããã¯ãæããªãïŒã§ã¯m.get("content")ãNoneãè¿ããisinstance(None, list)ãisinstance(None, str)ãåœãªã®ã§msgsã«äœã远å ãããªããããã¯æå³éãã®åäœã§ãããã¹ããæããªãã¿ãŒã³ã¯çŽ éãããã -
ã»ãã·ã§ã³IDã空æåã«ãªãïŒstdin JSON ã«
session_idãå«ãŸããªãã±ãŒã¹ãçšã«ããã[ -n "$sid" ] && [ -f "$flag" ] || exit 0ã®æ¡ä»¶ã§$sidã空ãªãå³ã¹ãããã«ãªãããå®å®³ã¯ãªãããããã¯ããéãã«äœãããªããç¶æ ã«ãªããçç¶ãšããŠæ°ã¥ãããinputãäžæãã¡ã€ã«ã«æžãåºããŠjq .ã§ç¢ºèªããã
éçšã»é·æãŸãã
-
/tmpã®ãã©ã°ãå€ãã»ãã·ã§ã³IDã§èç©ããïŒ/tmp/claude-audit-pending-*ãš/tmp/claude-audit-prompted-*ã¯ãClaude CodeãçµäºããŠãèªåã§ã¯æ¶ããªããOSãåèµ·åããã°æ¶ããããæ°é±éèµ·åãã£ã±ãªãã®ç°å¢ã§ã¯å€§éã®ãŽããç©ãŸãããæ1åçšåºŠrm -f /tmp/claude-audit-*ã§æé€ããããããã¯ã®èµ·åæã«å€ããã¡ã€ã«ãåé€ããè¡ãå ããã -
ç£æ»ããŒã¯ãŒããã¢ãã«ã«åŠç¿ãããŠåœ¢éªžåããïŒãç£æ»ããšããèªãå«ã1è¡ã§ééã§ããããšãã¢ãã«ãèŠãããšããç£æ»ïŒåé¡ãªããã®ãããªç©ºç ²ãåºãããã«ãªãããã®ã·ã°ãã«ãèŠãããããŒã¯ãŒããæŽæ°ããããæœ°ããããæ¢ã«å ç¢ãããããŠèŠéããã®ããã«å®éã®å€æãèªãèšèã¯åœ¢éªžåãã«ãããèªåœã®æ£åžãã¯2ã3ã¶æãããç®å®ã
-
è€æ°ã®Stopããã¯ãå¹²æžããïŒå¥ã®Stopããã¯ãå ã«
exit 2ãè¿ããšãClaude Codeãããã¯ãã§ãŒã³ãããã§æ¢ããå¯èœæ§ãããïŒå®è£ äŸåïŒãããã¯ã¯ç»é²é ã«å®è¡ããããããç£æ»ããã¯ã¯é åã®æ«å°Ÿã«çœ®ãããããã¯è€æ°ã®ããžãã¯ã1æ¬ã®Stopããã¯ã«çµ±åããã -
stderrã®ãããã°åºåãæ¶ãå¿ããïŒããã¯ããããã°ãããšã
echo "DEBUG: sid=$sid" >&2ã远å ããããæ¶ãå¿ãããšæ¬çªã®stderrã«ãããã°è¡ãæ··å ¥ããããããã°å°çšã®ãã©ã°å€æ°ïŒDEBUG_HOOK=1ïŒãç°å¢å€æ°ã«ããŠå¶åŸ¡ãããããããã°åŸã¯å¿ ãåé€ããã
ãã¹ããã©ã¯ãã£ã¹
1. Python㯠/usr/bin/python3 ãã«ãã¹åºå®
ããã¯ãåãæå°ã·ã§ã«ç°å¢ã¯PATHãéã£ãŠããªããpython3 ãšã ãæžããšãèŠã€ãããªããã§ãµã€ã¬ã³ãã¹ãããã«ãªãã/usr/bin/python3 ã®ãã«ãã¹æå®ã®ã¿å®å
šããã®ããã¯ã§ã³ã¡ã³ãã«ããã«ãã¹ããšæžããŠããçç±ã¯ããã
2. ãã©ã°ã¯å€å®åã«æ¶ãïŒã«ãŒã鲿¢ã®èŠïŒ
rm -f "$flag" # åçº: ãã®ã¿ãŒã³ã®flagã¯å¿
ãæ¶ã(ã«ãŒã鲿¢)
[ -z "$last" ] && exit 0
ãåæ Œæã ãæ¶ããèšèšã«ãããšãäžåæ Œã§ãããã¯âã¢ãã«ãç£æ»ãæžãâæ¬¡ã®Stopã§ãã©ã°ãæ®ã£ããŸãŸâãŸããããã¯ãã®ã«ãŒããèµ·ããããã©ã°ã¯Stopããã¯èµ·åæç¹ã§å¿ ãæ¶ããæ¬¡åãã©ã°ãç«ã€ã®ã¯ããã®ã¿ãŒã³ã§ãŸããã¡ã€ã«ãæžããå Žåã ããã«éå®ãããã
3. ãã§ã€ã«ãªãŒãã³ååã培åºãã
ããã¯ãç°åžžçµäºãããšã㯠exit 0ïŒéãïŒãéžã¶ãããã¯ãžã®äžä¿¡ä»»ãç©ã¿éãªãã»ããé·æãã¡ãŒãžã倧ãããç£æ»ã®èŠéãã¯æ¬¡ã®ã¿ãŒã³ã§æŸãããããã¯ã®èª€ãããã¯ã¯ããŸãããã¯ã誀äœåããããšããè©äŸ¡ã«çŽçµãã以éããã¯ãå®è³ªç¡å¹åããããå®å
šç³»ããã¯ïŒç§å¯å€ã®ã³ããã鲿¢ãªã©ïŒã¯éã«ãã§ã€ã«ã¯ããŒãºãæ£ããã圹å²ã«ãã£ãŠèšèšæ¹éãåããã
4. ã»ãã·ã§ã³å¥ãã©ã°ã§è€æ°ãŠã£ã³ããŠã®å¹²æžãé²ã
flag="/tmp/claude-audit-pending-${sid}"
session_id ããã¡ã€ã«åã«åã蟌ãããšã§ãè€æ°ã®Claude CodeãŠã£ã³ããŠãåæéãããŠããŠãæ··ç·ããªããã«ãŠã³ã¿ãã¡ã€ã« claude-audit-prompted-${sid} ãåæ§ãsession_idãå
¥ã£ãŠããªããã° $sid ã空ã«ãªã [ -n "$sid" ] ã®æ¡ä»¶ã§å³ã¹ãããããå®å
šåŒã«ããªãã
5. head -15 ã§å
é ã ãèªã
head -15 "$tpath" 2>/dev/null | grep -q '"entrypoint":"sdk-cli"'
Claude Codeã®JSONLã¯ãã»ãã·ã§ã³ã®ã¡ã¿ããŒã¿ãããã¯ïŒãšã³ããªãŒãã€ã³ãæ
å ±ãå«ãïŒãå
é æ°è¡ã«æžã蟌ãããã¡ã€ã«å
šäœã cat ãã head -15 ã§ååå€å®ã§ãããé·å€§ãªã»ãã·ã§ã³ïŒæ°çŸKBïŒã§ãããã¯ã®èµ·åã³ã¹ããã»ãŒãŒãã«ãªãã
6. matcher 㯠Write|Edit ã«éå®ãã
* ã«ãããšBashã³ãã³ãå®è¡ã»Readã»Grep ã§ãPostToolUseããã¯ãèµ°ããã調æ»ã ãããã¿ãŒã³ãã«ãã©ã°ãç«ã€ããã¡ã€ã«ãæžããã¿ãŒã³ã ããæŸããããªã Write|EditãMultiEditãå«ããå Žå㯠Write|Edit|MultiEditã
7. ã»ãã·ã§ã³åœããäžéïŒ2åïŒã§é£çºãé²ã
count=$(cat "$prompted" 2>/dev/null || echo 0)
if [ "$count" -ge 2 ]; then rm -f "$flag"; exit 0; fi
åäžã»ãã·ã§ã³å ã§ç£æ»èŠæ±ã3å以äžåºããšãã¢ãã«ããç£æ»ã¯å®æã«ãŒãã£ã³ããšèªèããŠåœ¢åŒçãªå¿çãããããã«ãªãã2åãè¶ ãããé»ãããå°ãªãåæ°ã§ç¢ºå®ã«å¹ããããã»ããç£æ»ã®éã¿ãä¿ãããã
8. ç¡äººã»ãã·ã§ã³ãæ€åºããŠã¹ããããã
launchdã»Agent SDKã»cronçµç±ã®ç¡äººå®è¡ã»ãã·ã§ã³ã«ç£æ»èŠæ±ãåºããŠãèªã人éãããªãããã©ã³ã¹ã¯ãªããå
é 15è¡ã« "entrypoint":"sdk-cli" ãããã°ãã©ã°ãæ¶ã㊠exit 0ããããå
¥ããªããšå€éãããã®stderrãç£æ»èŠæ±ã§åãŸãïŒå®éã«1æ©ã§19ä»¶ç©ãŸããäºä»¶ãèµ·ããïŒã
9. ãããã¯ã¡ãã»ãŒãžã¯çããéãéãäœã
echo "â ïž ã»ã«ãç£æ»æªå®æœã...軜埮ãªããç£æ»äžèŠ:çç±ãã®äžèšã§è¯ãã" >&2
200åã®è¡šãã³ãã¬ãŒããéããš20è¡ã®ç£æ»ãæ¯åè¿ã£ãŠãããã軜埮ãªã1è¡ã§ããããšããéãéãäœãããšã§ãéèŠãªå€æŽã§ã¯ã朰ããïŒatomic renameã§å¯ŸåŠæžã¿ãã®1è¡ãåºãŠã軜埮ãªå€æŽã§ã¯ãç£æ»äžèŠïŒå®æ°å€æŽã®ã¿ãã®1è¡ãåºããç£æ»ã®éã§ã¯ãªã質ã®åé¡ã
10. ããŒã¯ãŒãã¯ã倿ãèªãèšèãã«ãã
ç£æ»|朰ãã|æ¢ã«å
ç¢|ãããŠèŠéã|ã»ã«ãç£æ»|äžå±€|äºæž¬ã§ããäžå
·å ã®7ãã¿ãŒã³ã®ãã¡ãæã圢骞åãã«ããã®ã¯ã朰ããããæ¢ã«å
ç¢ãããããŠèŠéããã®3ã€ããããã¯3åºåå ±åã®èªåœã§ãããå®éã®å€æãçµãªããšèªç¶ã«åºãªãèšèããç£æ»ãã ããæ®ããŠã»ããåããšãç£æ»æžã¿ã1è¡ã§ééã§ããã·ã§ãŒãã«ãããå¢ããã
11. ã³ã¡ã³ãã«äºä»¶æ¥æãæ®ã
# 2026-07-12: äžæ©ã§sdk-clièªåå19ä»¶ãstopspamãåãã
ãã®ã³ãŒããããã«ããçç±ããå°æ¥ã®ã¢ãã«ãšèªåã«äŒãããããã¯ã¯åŸããèªãã§ãæå³ãäžéæã«ãªããããïŒããªãããã§head -15ïŒãããªã2åäžéïŒãïŒãäºä»¶ã®æ¥æãšçç¶ã1è¡æ®ãã ãã§ãå幎åŸã®æ¹ä¿®ã³ã¹ãã倧ããäžããã
12. jq ã§ settings.json ãæ€èšŒãã
jq . ~/.claude/settings.json
ããã¯ãç»é²ããåŸã¯ jq ã§æŽåœ¢ããŠç®èŠç¢ºèªãããç¹ã« hooks.PostToolUse[].hooks[] ã®äºéé
åæ§é ã¯ééãããããJSONæ§é ã®ãã¹ã¯Claude Codeããµã€ã¬ã³ãã«ç¡èŠããããæ°ã¥ãã«ãããåããªããšæã£ãããŸãããã
13. ãããã°ã¯äžæãã¡ã€ã«ãžã®æžãåºãã§
# ãããã°æã®ã¿è¿œå ãçµãã£ããå¿
ãåé€
printf '%s' "$input" > /tmp/hook-debug-input.json
echo "DEBUG: sid=$sid tpath=$tpath" >&2
stderrãžã®ãããã°åºåã¯ã¢ãã«ã«ãã£ãŒãããã¯ããããããæ¶ãå¿ãããšæ¬çªã§äœèšãªãã€ãºã«ãªãããããã°å®äºåŸã¯å¿
ãåé€ããã/tmp/hook-debug-input.json ã« stdin ãæžãåºã㊠jq . ã§èŠããšãããã¯ã«æž¡ã£ãŠããJSONã®å
šå®¹ãåããã
14. ããã¯èªäœãç£æ»å¯Ÿè±¡ã«ãã
ãããã¯ãåããŠããã¯ãããæ€èšŒããéçšããªããé±1åçšåºŠãæå³çã«ãã¡ã€ã«ãæžããŠç£æ»èŠæ±ãåºãããšã確èªããããŸã㯠/tmp/claude-audit-prompted-* ã®ã¿ã€ã ã¹ã¿ã³ããèŠãŠãæåŸã«ç£æ»ãèŠæ±ãããã®ã¯ãã€ããã確èªãããããã¯ãéãã«å£ããŠãããšãç£æ»ãªãã§ãå®äºããéãç¶ããã
ãŸãšã
ãå®äºã§ãããšããèšèã¯ãLLMãåºåããèªã®äžã§æãå±éºãªãã®ã®äžã€ã§ããæåãšããŠååšãããã宿 ãä¿èšŒããªãããåããŸãããããã¹ããéã£ãŠããŸãããå®è£ ãå®äºããŸãããââãã®3è¡ãèªãã§å®å¿ããç¿æãæ¬çªã§å£ããŠãããšããçµéšã¯ãLLMã䜿ãéçºè ãªãäžåºŠã¯éãéã§ãã
Stopããã¯ïŒPostToolUseããã¯ã®çµã¿åããã¯ãããã«1æ¬ã®ç©ççãªæµãç«ãŠãŸãã
audit_flag_set.sh ã®6è¡ããã¡ã€ã«å€æŽã®ãã³ã«ãã©ã°ãç«ãŠãself_audit_stop.sh ã®67è¡ããã®ãã©ã°ãæŸãããã©ã³ã¹ã¯ãªããJSONLãPythonã§çŽæ¥ããŒã¹ããçŽè¿ã®assistantããã¹ããã7ã€ã®ããŒã¯ãŒããæ¢ãããªããã° exit 2 ã§ãããã¯ãããããã³ããã§ãå¿
ãç£æ»ããŠãã ããããšé Œãã®ã§ã¯ãªããããŒãã¹ãç£æ»ãç©ççãªé鿡件ã«ããã
ãã®ä»çµã¿ãå ¥ããŠããããå®äºãšèšã£ãã®ã«å£ããŠãããã®é »åºŠãäœæã§7ã8å²èœã¡ãŸãããæ®ãã®2ã3å²ã¯ãããŒã¯ãŒãã®åœ¢éªžåïŒãç£æ»ïŒåé¡ãªããã®ç©ºç ²ïŒããããã¯ãéãã«ã¹ãããããç°åžžç³»ã§ããã©ã¡ããããŒã¯ãŒãã®å®ææŽæ°ãšããã¯ãã°ã®ç¢ºèªã§å¯Ÿå¿ã§ããŸãã
æå120äžã®èªåŸç°å¢ã§æã倧åãªã®ã¯ãLLMãæ£ããåããŠãããšä¿¡ããããšãã§ã¯ãªãããLLMãæ£ããåããŠããã確èªã§ããæ§é ãæã€ããšãã§ããä¿¡é Œã¯ä»çµã¿ãæ ä¿ããââæ10äžã®å€§åŠçã ã£ãé ããå€ãã£ããæãæ ¹æ¬çãªèãæ¹ã§ãã
ä»çµã¿ã®å šäœåã»æ120äžã®å èš³ã»30æ¥æé ã¯æænoteã«ãŸãšããŠããŸãã ð Claude CodeèªåŸç°å¢ã§ãå®éã©ã皌ãã â ä»çµã¿ã»å®äŸã»å§ãæ¹ã»ãµããŒã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
- AIå°å ¥ã»èªååã®çžè«ãšå®è£ ãã³ãã¬7æ¬ã®é åžã¯ å ¬åŒLINE ããð¬
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ