65120a1c65
- 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
79 lines
5.7 KiB
Bash
Executable File
79 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# leo21c-write-guard.sh 的迴歸測試(inkstone/ISEP#130)
|
||
#
|
||
# ── 這支在守什麼 ──────────────────────────────────────────────────────
|
||
# 閘的判準是「**讀可以,寫不行**」(leo 2026-08-20:leo21c 是他本人在用的知識庫)。
|
||
# 2026-09-04 雲端 Routine 的 run log:**讀 notify_leo 的定義被擋** ——
|
||
# 讀都讀不到,雲端就什麼都拿不到(inkstone/ISEP#130 開票的第一件)。
|
||
#
|
||
# 這支之前**沒有任何測試**,所以「讀會不會被誤攔」從來沒被驗過。
|
||
# 下面的測資是 Routine 文件(cloud-worker.md/progress-guard.md)裡**真的會下的那幾條指令**,
|
||
# 不是想像出來的例子。
|
||
#
|
||
# 🔴 三個方向都要驗,缺一個就是假綠:
|
||
# A 讀 ⇒ 放行(含 `tr -d`/`cut -d=` 這種唯讀的 -d,那正是 09-04 被擋的形狀)
|
||
# B 寫 ⇒ 擋(心跳 POST/PATCH 收件匣/部署端點/別的 trigger)
|
||
# C 閘印出來的「改法」指的是**現役**的 youlin 網址,不是 09-02 已死的舊名
|
||
#
|
||
# 這支閘不寫任何檔案,直接跑真跡即可;全程離線。
|
||
# 用法:bash hooks/tests/leo21c-write-guard.test.sh
|
||
set -u
|
||
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||
HOOK="$HERE/../leo21c-write-guard.sh"
|
||
PASS=0; FAIL=0
|
||
mk(){ python3 -c "import json,sys;print(json.dumps({'tool_name':'Bash','tool_input':{'command':sys.argv[1]}}))" "$1"; }
|
||
t(){ # t <期望 pass|block> <說明> <指令>
|
||
LAST_ERR=$(mk "$3" | bash "$HOOK" 2>&1 >/dev/null); rc=$?
|
||
got=$([ "$rc" -eq 2 ] && echo block || echo pass)
|
||
if [ "$got" = "$1" ]; then echo " ✅ $2"; PASS=$((PASS+1))
|
||
else echo " ❌ $2 —— 期望 $1,實得 $got(rc=$rc)"; FAIL=$((FAIL+1)); fi
|
||
}
|
||
|
||
L='https://arcrun-cypher-executor.leo21c.workers.dev'
|
||
K='-H "X-Arcrun-API-Key: leo"'
|
||
D='-d'
|
||
|
||
echo "── A. 讀 ⇒ 放行(雲端 Routine 真的會下的形狀)──"
|
||
t pass "① 讀收件匣(progress-guard.md 步驟 0 原句)" "curl -s \"$L/kbdb/entries?entry_type=inbox&limit=20\" $K"
|
||
t pass "② 讀 notify_leo 定義(09-04 被擋的那一條)" "curl -s $L/webhooks/named/leo/notify_leo $K"
|
||
t pass "③ 讀 + tr -d(唯讀的 -d,不是 body)" "curl -s $L/workflows/notify_leo $K | tr $D '\\r'"
|
||
t pass "④ 讀 + cut -d=" "NS=\$(grep ns cfg | cut ${D}= -f2); curl -s $L/kbdb/entries?limit=1 $K"
|
||
t pass "⑤ 讀 + sort -d / date -d" "curl -s $L/health | sort $D; date $D yesterday"
|
||
t pass "⑥ 明寫 -X GET" "curl -s -X GET $L/kbdb/entries?entry_type=dash_beat $K"
|
||
t pass "⑦ 讀心跳(progress-guard 2.6 原句)" "curl -s \"$L/kbdb/entries?entry_type=dash_beat&limit=30\" $K"
|
||
t pass "⑧ git commit 訊息提到 leo21c 與 POST(git 寫不到那台)" "git commit -m 'fix: curl -X POST $L/kbdb/entries 會被擋'"
|
||
t pass "⑨ 修這道閘自己" "sed -i 's/a/b/' hooks/leo21c-write-guard.sh"
|
||
t pass "⑩ 打 youlin(09-02 起的新子網域)POST,不是 leo21c" "curl -X POST https://arcrun-cypher-executor.arcrun-yuga3bse.workers.dev/webhooks/named $D '{}'"
|
||
t pass "⑪ 用 youlin 的 CF 帳號部署" "CLOUDFLARE_ACCOUNT_ID=1129efd7df2e8899d537e9c8fbabb6cb npx wrangler deploy"
|
||
t pass "⑫ 發一則 notify_leo(通知型 trigger,什麼都沒改;同 prod-write-guard 白名單)" "curl -s -X POST $L/webhooks/named/leo/notify_leo/trigger -H 'Content-Type: application/json' $D '{\"text\":\"[總管] hi\"}'"
|
||
|
||
echo "── B. 寫 ⇒ 擋 ──"
|
||
t block "⑬ 打心跳 POST(cloud-worker.md 步驟 0 原句——它寫進 leo 的庫)" "curl -s -X POST \"$L/kbdb/entries\" $K -H 'Content-Type: application/json' $D '{\"entry_type\":\"dash_beat\"}'"
|
||
t block "⑭ PATCH 收件匣" "curl -s -X PATCH \"$L/kbdb/entries/123\" $K $D '{\"content\":\"x\"}'"
|
||
t block "⑮ DELETE" "curl -X DELETE $L/kbdb/entries/1 $K"
|
||
t block "⑯ 只帶 -d 的隱式 POST" "curl $L/kbdb/entries $D '{}'"
|
||
t block "⑰ --data-urlencode" "curl $L/kbdb/entries --data-urlencode text=hi"
|
||
t block "⑱ --request PUT" "curl --request PUT $L/kbdb/entries/1 $D '{}'"
|
||
t block "⑲ 別的工作流 trigger(ship_refresh_cdn 會動線上狀態)" "curl -X POST $L/webhooks/named/leo/ship_refresh_cdn/trigger $D '{}'"
|
||
t block "⑳ 部署端點(無名字的 named webhook)" "curl -X POST $L/webhooks/named $D @def.yaml"
|
||
t block "㉑ notify_leo 旁邊夾一個部署端點" "curl -X POST $L/webhooks/named/leo/notify_leo/trigger $D '{}' && curl -X POST $L/webhooks/named $D @x"
|
||
t block "㉒ 寫 + tr -d(剪掉唯讀 -d 之後仍該擋)" "cat f | tr $D '\\r' | curl -X POST $L/kbdb/entries $D @-"
|
||
t block "㉓ 用 leo21c 的 CF 帳號部署" "CLOUDFLARE_ACCOUNT_ID=51a01bfa2665bd7bc3fd080dc40cf3e1 npx wrangler deploy"
|
||
|
||
echo "── C. 擋下時印的改法要指到活著的 youlin ──"
|
||
mk "curl -X POST $L/kbdb/entries $D '{}'" | bash "$HOOK" 2>"$HERE/.leo21c-msg.$$" >/dev/null
|
||
MSG=$(cat "$HERE/.leo21c-msg.$$"); rm -f "$HERE/.leo21c-msg.$$"
|
||
if printf '%s' "$MSG" | grep -q 'arcrun-cypher-executor.arcrun-yuga3bse.workers.dev'; then
|
||
echo " ✅ ㉔ 改法段印的是現役子網域 arcrun-yuga3bse"; PASS=$((PASS+1))
|
||
else echo " ❌ ㉔ 改法段沒有現役子網域 arcrun-yuga3bse"; FAIL=$((FAIL+1)); fi
|
||
if printf '%s' "$MSG" | grep -q 'cypher : https://arcrun-cypher-executor.youlin-hsieh-dev'; then
|
||
echo " ❌ ㉕ 改法段還教人打 09-02 已死的 youlin-hsieh-dev"; FAIL=$((FAIL+1))
|
||
else echo " ✅ ㉕ 改法段不再把死的舊名當網址教人"; PASS=$((PASS+1)); fi
|
||
if printf '%s' "$MSG" | grep -q '讀可以,寫不行'; then
|
||
echo " ✅ ㉖ 訊息講得出判準(讀可以,寫不行)"; PASS=$((PASS+1))
|
||
else echo " ❌ ㉖ 訊息沒講判準"; FAIL=$((FAIL+1)); fi
|
||
|
||
echo
|
||
echo "通過 $PASS 條,失敗 $FAIL 條"
|
||
[ "$FAIL" -eq 0 ]
|