#!/usr/bin/env bash # delivery-police.sh — 交付警察(Stop / SubagentStop hook) # # 病根(leo 2026-07-22 原話):「它是我的助理,如果都是我檢查,那我就是它的助理。」 # 一天內三次都是 leo 先發現:①雲端沒查文件就問 ②OAuth 做好但前端還是舊按鈕、網址沒設 DNS # ③連補規則也是 leo 講了才補。→ 角色顛倒=根本失敗。 # # 為什麼清單沒用:CRITICAL-PATH 使用規則 4/5(v2 覆蓋前為 6/7)寫了「要驗前端」,CLAUDE.md 規則二寫了四題公式, # 照樣被違反——因為**自評的人跟做事的人是同一個**,任何品管制度都不成立。 # 解法同 self-drive-police:在「要標完成/要收工」那一刻攔截 + 反問。 # # 機制:Claude 想停 → 掃這回合輸出有沒有「完成宣稱」→ 有、但沒看到實測證據 → exit 2 反問。 # 豁免:輸出已含實測證據(curl/dig 實際輸出、HTTP 碼、grep 到畫面字串、檔案:行號)→ 放行。 # 撞權限閘/明說四題命中 → 放行(不逼它做沒權限的事)。 # # 判準(leo 2026-07-22):「友善=前端。人去按了連到錯的機制、安裝失敗,不算友善。」 # → 有前端的東西,驗收只認用戶真的會走的那條路。 input="$(cat)" # 防無限迴圈 stop_active="$(printf '%s' "$input" | python3 -c ' import sys, json try: print(json.load(sys.stdin).get("stop_hook_active", False)) except Exception: print(False) ' 2>/dev/null)" [ "$stop_active" = "True" ] && exit 0 transcript="$(printf '%s' "$input" | python3 -c ' import sys, json try: print(json.load(sys.stdin).get("transcript_path", "")) except Exception: print("") ' 2>/dev/null)" [ -z "$transcript" ] || [ ! -f "$transcript" ] && exit 0 last_text="$(python3 -c ' import sys, json path = sys.argv[1] texts = [] try: with open(path) as f: lines = f.readlines() for line in reversed(lines): try: ev = json.loads(line) except Exception: continue msg = ev.get("message", ev) if msg.get("role") == "assistant": content = msg.get("content", "") if isinstance(content, list): for b in content: if isinstance(b, dict) and b.get("type") == "text": texts.append(b.get("text", "")) elif isinstance(content, str): texts.append(content) break except Exception: pass print("\n".join(texts)) ' "$transcript" 2>/dev/null)" [ -z "$last_text" ] && exit 0 # ── 豁免一:撞權限閘/明說四題命中 → 真的停不下來,放行 ── if printf '%s' "$last_text" | grep -qiE '權限閘|classifier|分類器擋|四題第|人閘|需要你放行|denied by'; then exit 0 fi # ── 是否有「完成宣稱」? ── if ! printf '%s' "$last_text" | grep -qiE '✅|完成了|已完成|通了|部署成功|已上線|已部署|搞定|做完了|全綠|收工'; then exit 0 fi # ── 豁免二:已有「夠格的」實測證據 → 放行 ── # # ⚠️ 本段自身踩過的雷(2026-07-22 實測 t2 抓到): # 舊版寫 `HTTP [0-9]{3}` 就放行 → 「curl 回 HTTP 200,這關通了」直接過關。 # 那正是要防的假綠原句(landing 回 200 但按鈕 href 還是舊的)。 # **把要防的東西寫成通行證**=規則 6「HTTP 200 不算驗過」被自己的 hook 架空。 # # 現在的判準:2xx/3xx 一律不算證據;只有下列才算—— # ① 抓到畫面內容(curl|grep / href= /