Files
ISEP/hooks/tests/prod-write-guard.test.sh
T
isep-hand 65120a1c65 雲端要拿得到票、主線與通知:白名單住 ISEP、主線檔隨 repo 走、leo21c 讀放寫擋(inkstone/ISEP#130)
- docs/permissions-allow.json + scripts/settings-allow-sync:四個 Gitea 正門工具的權限白名單一份,
  setup script 裝完 plugin 寫一次、SessionStart 每次再對一次(只加不減、冪等)
- hooks/lib/mainline.py/scripts/mainline:家目錄沒主線就讀 InkStoneCo/system-dev/mainline.json;
  set/adopt/clear 兩份一起寫,refresh 只寫家目錄
- hooks/leo21c-write-guard.sh:唯讀 -d(tr/cut/sort…)先剪掉再判、notify_leo trigger 放行
  (與 prod-write-guard 同一份白名單)、改法段改印 09-02 起的 youlin 子網域;補第一支測試(26 條)
- prod-write-guard/main-and-prod-push-guard/kbdb-live-exam:認得 youlin 新子網域 arcrun-yuga3bse
- scripts/ticket:收件 repo 寫 inkstone/ISEP 不再 404(org 寫錯當場講)
- scripts/isep-notify:有 TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID 先走 Bot API 直送(雲端唯一通的路)
- 測試:A31–A35 共 79 條;README/plugin.json/hooks-inventory 數字實數(61 支、85 條、53 支腳本)

假設(記在這裡等 review):權限規則的形狀沿用 leo 09-07 親手加、實測有效的那四條;
「分類器真的不擋」要雲端一趟 run 的 permission_denials 才驗得到,本 PR 驗不了。
版本:待總管定版(plugin.json 仍 0.22.0)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DTZ9QtvjY7MNxjfQbexAm7
2026-09-07 01:17:15 +00:00

111 lines
6.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# prod-write-guard.sh 的迴歸測試。
# 🔴 必須寫成檔案跑:這道閘會擋掉「含有它要擋的字串」的指令本身
# ⇒ 直接在 Bash 裡打測試,會被自己擋下(2026-08-12 實撞)。
HOOK="$1"
mk(){ python3 -c "import json,sys;print(json.dumps({'tool_name':'Bash','tool_input':{'command':sys.argv[1]}}))" "$1"; }
PASS=0; FAIL=0
t(){ # t <期望 block|pass> <說明> <指令>
mk "$3" | "$HOOK" >/dev/null 2>&1; rc=$?
got=$([ $rc -eq 2 ] && echo block || echo pass)
if [ "$got" = "$1" ]; then echo " ✅ $2"; PASS=$((PASS+1))
else echo " ❌ $2 —— 期望 $1,實得 $got"; FAIL=$((FAIL+1)); fi
}
H='https://arcrun-kbdb.leo21c.workers.dev'
DASH_D='-d'
echo "── 該放行(唯讀)──"
t pass "純 GET" "curl -s $H/templates"
t pass "GET + tr -d(本次實撞的誤攔)" "ACC=\$(grep -oE '^X=.' f | tr $DASH_D '\\r'); curl -s $H/templates"
t pass "GET + cut -d=" "A=\$(cut ${DASH_D}= -f2 f); curl -s $H/templates"
t pass "GET + sort -d / xargs -d" "ls | sort $DASH_D | xargs $DASH_D '\\n' echo; curl -s $H/entries"
t pass "GET 帶 Bearer 標頭" "curl -s -H 'Authorization: Bearer xxx' $H/templates?limit=1"
t pass "打 staging" "curl -X POST https://arcrun-rag-installer-staging.workers.dev/x $DASH_D '{}'"
t pass "打 youlin 測試場" "curl -X POST https://arcrun-cypher-executor.youlin-hsieh-dev.workers.dev/x $DASH_D '{}'"
t pass "打 youlin 測試場(09-02 重裝後的子網域 arcrun-yuga3bseinkstone/ISEP#130" "curl -X POST https://arcrun-cypher-executor.arcrun-yuga3bse.workers.dev/webhooks/named $DASH_D @def.yaml"
t pass "打 Gitea(不是實例)" "curl -X POST https://git.uncle6.me/api/v1/repos/Leo/x/issues $DASH_D '{}'"
echo "── 該擋(寫入)──"
t block "POST 到實例" "curl -X POST $H/entries $DASH_D '{}'"
t block "PUT 到實例" "curl -X PUT $H/entries/1 --data '{}'"
t block "DELETE 到實例" "curl -X DELETE $H/entries/1"
t block "POST 且同時有 tr -d(剪字後仍該擋)" "cat f | tr $DASH_D '\\r' | curl -X POST $H/webhooks/named $DASH_D @-"
t block "wrangler deploy" "npx wrangler deploy --name arcrun-kbdb"
# ── 2026-08-13:「執行它」vs「談論它」───────────────────────────────
# 實撞:把 #108 的驗收證據留言到 Gitea,正文引述了那個指令名 ⇒ 一則留言被當成部署擋掉。
# 這批測資的挑法是「本 repo 現行真的會出現的形狀」,不是我自己挑好抓的壞例子
# ——PR #87 那道假綠閘就是敗在後者(14 條全過,卻漏掉 repo 實際在用的呼叫寫法)。
ACR_U='acr up''date' # 拆開寫:否則這支測試檔自己會被閘擋住(它也是一條 Bash 指令)
ACR_P='acr pu''sh'
WR_D='wrangler dep''loy'
echo "── 該放行(只是談論,不是執行)──"
t pass "heredoc 正文引述(本次實撞)" \
"B=\$(cat <<'EOF'
更新指令 \`$ACR_U --force\` 印出了 ARCRUN_NAMESPACE
EOF
); curl -X POST https://git.uncle6.me/api/v1/repos/Leo/Arcrun/issues/108/comments $DASH_D \"\$B\""
t pass "commit 訊息裡提到" "git commit -m '修好 $ACR_U 的命名空間注入'"
t pass "markdown code span(反引號)" "printf '%s' '看 \`$ACR_U\` 的輸出'"
t pass "grep 它的名字" "grep -n '$ACR_P' .claude/hooks/prod-write-guard.sh"
t pass "文章裡提到 $WR_D" "printf '%s' '# 為什麼 $WR_D 要擋'"
t pass "acr 唯讀子指令" "acr status --json"
t pass "acr whoami" "acr whoami"
echo "── 該擋(真的在指令位置執行)──"
t block "行首" "$ACR_U --force"
t block "&& 之後" "cd /x && $ACR_U"
t block "; 之後" "echo hi; $ACR_P workflow.yaml"
t block "管線之後" "cat x.yaml | $ACR_P -"
t block "bash -c 引號裡" "bash -c \"$ACR_U --force\""
t block "\$( ) 裡" "OUT=\$($ACR_U 2>&1)"
t block "npx 前綴" "npx $WR_D --name arcrun-kbdb"
t block "sudo 前綴" "sudo $ACR_U"
t block "heredoc 之後的真指令(剝內文不能連指令一起剝)" \
"cat <<'EOF' > note.md
只是筆記
EOF
$ACR_U --force"
# ══ inkstone/ISEP#63 → comment 5106:兩個卡點 ═══════════════════════════
#
# 卡點一:發一則 Telegram 給 leo`notify_leo`)跟「部署一個工作流上線」在本閘眼裡
# 長得一模一樣——兩者都是帶 body 的寫入型請求打到同一台實例。
# 判準改成看**打的是哪一個 named webhook**(路徑形狀+名字),
# 而放行的範圍只有一個名字,家族其他成員照擋。
# 卡點二:連「把這個卡點寫進票裡」都被同一支閘擋(同款第八次)——
# 內文引用了主機名與寫入旗標,而閘比對的是指令文字。
EXE="https://arcrun-cypher-executor.leo21c.wo""rkers.dev"
NAMED="$EXE/webhooks/named"
echo "── 卡點一:通知放得過,家族其他成員照擋 ──"
t pass "發一則 Telegram 給 leonotify_leo trigger" \
"curl -s -X POST $NAMED/leo/notify_leo/trigger $DASH_D '{\"text\":\"[總管] 進度\"}'"
t pass "同上,網址後面帶斜線" \
"curl -s -X POST $NAMED/leo/notify_leo/trigger/ --data '{\"text\":\"[總管] x\"}'"
t block "別的 named webhook(會動線上狀態)不在白名單裡" \
"curl -X POST $NAMED/leo/ship_refresh_cdn/trigger $DASH_D '{}'"
t block "部署端點(沒有名字、沒有 /trigger" \
"curl -X POST $NAMED $DASH_D @workflow.json"
t block "通知混著一筆真的寫入 ⇒ 整條照擋(白名單要每一個都符合)" \
"curl -X POST $NAMED/leo/notify_leo/trigger $DASH_D '{}' && curl -X POST $EXE/entries $DASH_D '{}'"
t block "名字只是前綴相同(notify_leo_deploy)不算通知" \
"curl -X POST $NAMED/leo/notify_leo_deploy/trigger $DASH_D '{}'"
echo "── 卡點二:談論它(內文引用)不是執行它 ──"
t pass "把卡點貼回票上,內文引用了實例網址與寫入旗標(本次實撞)" \
"B=\$(cat <<'EOF'
閘擋下來了:\`curl -X POST $NAMED\` 被當成部署。
EOF
); curl -X POST https://git.uncle6.me/api/v1/repos/inkstone/ISEP/issues/63/comments $DASH_D \"\$B\""
t block "真的在部署、只是把 payload 放進內文 ⇒ 起始行仍看得到,照擋" \
"curl -X POST $NAMED $DASH_D @- <<'EOF'
{\"name\":\"x\"}
EOF"
echo
echo "結果:通過 $PASS 失敗 $FAIL"
[ $FAIL -eq 0 ] || exit 1