v0.2.1:43 支閘的白話盤點、測試手冊、補上兩個被抓到的洞

leo 2026-08-20 問「InkStoneCo#40 加入了嗎?如果是這樣我應該可以白話文看到 hooks 的內容?」
答案是不行——43 支閘沒有任何白話清單。這一版補上。

docs/hooks-inventory.md   43 支逐支一行,按「你會在什麼時候撞到它」分 9 組
                          抽驗 5 支逐行核對源碼;順帶抓到 3 支有檔案沒註冊
docs/TESTING.md           A1-A8 + B1-B5,每格都有「怎麼跑/該看到什麼/什麼算失敗」
scripts/test-*.sh         兩支閘的測試,共 21 條,全過

兩個實撞的洞:
- release-tag-guard 的排除清單是前綴比對,x 整條放行
  (A8 那個新 session 抓到的,總管複驗屬實)。改用 #23 驗證過的判準:
  關鍵字要在指令位置才算執行。補 3 條複合指令測試,8/8。
  ⇒ 這是 InkStoneCo#36「包一層就繞過去」的同一個病,發生在同一天新寫的閘上。
- scripts/ticket 寫死只認名叫 gitea 的 remote,在 ISEP(remote 叫 origin)整個跑不起來
  ⇒「開票前先搜」那道閘在新 repo 等於不存在。改成掃所有指向本站的 remote + 環境變數 fallback。

A8 已通過:新 session 裡 plugin 的閘真的觸發(exit 2、tag 未建立、訊息來自 plugin 路徑)。

文件漂移訂正:plugin.json 與 README 寫 42 支/52 條,實際 43 支/53 條。

兩支新閘補上 #40 §1 要求的三行中文檔頭。
🔴 但仍違反 #40 §3「新規則一律先 warn」——兩支都是 block。理由記在 #40 留言,等 leo 裁。
This commit is contained in:
2026-08-20 17:08:00 +08:00
parent bb72b22f10
commit 1dfc4e373a
10 changed files with 497 additions and 13 deletions
+41
View File
@@ -0,0 +1,41 @@
#!/bin/bash
# 開票側門閘的測試(docs/TESTING.md A4
# 判準:4 種該擋、8 種不該擋、1 種有戳記時放行 = 13 條
cd "$(dirname "$0")/.." || exit 1
H=hooks/ticket-api-bypass-guard.sh
PASS=0; FAIL=0
run(){ # $1=want $2=cmd
printf '%s' "{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$2")}}" \
| bash "$H" >/dev/null 2>&1
got=$?
if [ "$got" = "$1" ]; then PASS=$((PASS+1)); printf ' ✅ '; else FAIL=$((FAIL+1)); printf ' ❌ '; fi
printf 'want=%s got=%s %.56s\n' "$1" "$got" "$2"
}
SAVED=""; [ -f /tmp/.ticket-where-ok ] && SAVED=$(cat /tmp/.ticket-where-ok)
rm -f /tmp/.ticket-where-ok
echo "── 該擋(沒有搜尋戳記,且真的在開新票)──"
run 2 'curl -X POST https://git.uncle6.me/api/v1/repos/inkstone/ISEP/issues -d @b.json'
run 2 'python3 -c "req(\"POST\", f\"{API}/repos/{REPO}/issues\", {\"title\":\"x\"})"'
run 2 'curl --request POST "$API/repos/inkstone/InkStoneCo/issues"'
run 2 'req("POST",f"{API}/repos/{REPO}/issues",{"title":"x","labels":[1]})'
echo "── 不該擋(誤攔比漏擋更該修)──"
run 0 'curl -s "https://git.uncle6.me/api/v1/repos/inkstone/ISEP/issues?state=open"'
run 0 'req("POST", f"{API}/repos/{REPO}/issues/14/comments", {"body":"x"})'
run 0 'req("POST", f"{API}/repos/{REPO}/issues/5/labels", {"labels":[1]})'
run 0 'req("PATCH", f"{API}/repos/{REPO}/issues/5", {"state":"closed"})'
run 0 'scripts/ticket new ISEP -F /tmp/b.md --title "x"'
run 0 'echo "等一下要開票到 /repos/x/issues"'
run 0 'grep -n issues hooks/ticket-api-bypass-guard.sh'
run 0 'curl -s "$API/repos/inkstone/Arcrun/issues?state=open&limit=100"'
echo "── 有新鮮戳記時放行 ──"
python3 -c "import json,time;json.dump({'at':time.time(),'n':0,'top':[]},open('/tmp/.ticket-where-ok','w'))"
run 0 'curl -X POST https://git.uncle6.me/api/v1/repos/inkstone/ISEP/issues'
rm -f /tmp/.ticket-where-ok
[ -n "$SAVED" ] && printf '%s' "$SAVED" > /tmp/.ticket-where-ok
echo
echo "$PASS/$((PASS+FAIL)) 通過"
[ "$FAIL" -eq 0 ]