fix(hooks): 讓四支閘認得出「指令位置」跟「heredoc/引號裡的文字」

inkstone/InkStoneCo#23、#56 同一個病:閘對整條指令字串做關鍵字掃描,
把「檔案內容/留言引用裡剛好提到某個關鍵字」當成「真的在執行」,
同時放過包一層讀取指令、或藏在 heredoc body 裡的真動作。

- 新增共用輔助 hooks/lib/strip_heredoc.py:heredoc body 是資料不是指令,
  四支閘(github-contact / main-and-prod-push / stage-before-prod /
  kbdb-api-wall 的 Bash 分支)呼叫前一律先拿掉 body 再比對。
- main-and-prod-push-guard.sh:修掉跟 release-tag-guard.sh 同款的
  「開頭是讀取工具就整條放行」前綴繞過洞;git push 的偵測改成指令位置比對;
  main/master 目標改用單字邊界,不再誤中 "domain" 這種子字串。
- github-contact-guard.sh:拿掉 gh CLI/git push 判準裡「前面隨便一個空白
  就算數」的鬆散邊界,只認真正的指令分隔符。
- kbdb-api-wall-guard.sh:Bash 分支原本引用不存在的 kbdb_cmd_check.py,
  python3 找不到檔案就吃掉錯誤印 "OK",該分支形同虛設——任何
  `wrangler d1 execute` 直打 kbdb 都會被放行。邏輯搬進新檔
  hooks/lib/kbdb_cmd_check.py(shlex 分詞、quote-aware),把 .sh 的
  參照路徑改過去,補回 Bash 分支的 kbdb-sql-ok 逃生口。

四支各補 InkStoneCo#40 §1 要求的三行中文檔頭。

新增四支可重跑測試(scripts/test-*.sh),共 69 條斷言全過,
含 #23/#56 票上實撞的原始形狀(寫 docs/TESTING.md 的 heredoc、
貼引用 #56 敘述的留言、`grep git push`)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 18:51:52 +08:00
parent b5c4ef3540
commit 0cdb6f2c05
10 changed files with 490 additions and 75 deletions
+7 -1
View File
@@ -1,4 +1,7 @@
#!/bin/bash
# 管什麼: Bash 分支擋「繞過 API 牆、直接對那顆資料庫執行 SQL」的指令;Write/Edit 分支擋新增 DDL/原生 SQL/新 D1 binding。
# 為什麼: leo 2026-08-07 立 D38——KBDB 只能走 API,零 SQL、永不加表;規則掛在「KBDB」這個詞上,容易在想著「D1/建表」時漏載入。
# 誤觸時怎麼關: 該行尾加 kbdb-sql-ok(留痕,commit 說明理由);Bash 分支的判準邏輯在 hooks/lib/kbdb_cmd_check.py,誤攔先查那支。
# PreToolUse hook — KBDB 是 API-as-Wall:零 SQL、永不加表(L3 硬攔截)
#
# 【leo 2026-08-07 立】原話:
@@ -42,6 +45,9 @@ else
BASH_CMD=""
fi
if [ -n "${BASH_CMD:-}" ]; then
# 逃生口跟 Write/Edit 分支同一個標記(留痕,commit 說明理由)——加了這支才會真的擋,
# 之前 Bash 分支引用的檔案不存在、永遠印 "OK",逃生口自然也沒人需要,現在補上。
case "$BASH_CMD" in *kbdb-sql-ok*) exit 0 ;; esac
# 🔴 2026-08-07 修正:第一版做「整條命令字串比對」,結果**第四次誤擋總管**——
# 誤擋的是 `git commit -m "...引用了那個命令字面..."`:那是在**描述**這件事,
# 不是在執行它。同一天已被自己的閘誤擋三次(Task 分支),這是第四次。
@@ -49,7 +55,7 @@ if [ -n "${BASH_CMD:-}" ]; then
# 引號內、heredoc 內、commit message 內的同樣字面一律不算。
# 判斷邏輯住在獨立檔(見該檔開頭:內嵌逃逸讓這道閘改一次壞一次)
BASH_VERDICT=$(printf '%s' "$BASH_CMD" \
| python3 "$(dirname "$0")/kbdb_cmd_check.py" 2>/dev/null || echo "OK")
| python3 "$(dirname "$0")/lib/kbdb_cmd_check.py" 2>/dev/null || echo "OK")
if [ "$BASH_VERDICT" = "BAD" ]; then
cat >&2 <<'EOB'
🧱 kbdb-api-wall-guardBash):偵測到繞過 API 牆、直接對那顆資料庫執行 SQL 的命令。