新增 leo21c-mcp-guard.sh:擋下打向 leo 真庫的 Arcrun/KBDB MCP 呼叫(ISEP#69)
leo 2026-08-27:「我從頭的指令就叫你去打 youlin,stage 環境是它你不知道嗎? 為什麼打算用我的真庫測試?」 實況(總管當天實查):這台機器同時掛兩條 Arcrun MCP 連線,工具名是兩串 UUID—— mcp__00402d88-...__* → logged_in_as: leo21c(真庫),mcp__d0eaf65b-...__* → logged_in_as: youlin(測試場)。總管整天用第一條,測試資料卻寫在第二條, 造成三次假結論(「wiki 沒送上去」「排在 1691 筆後面」「ingest 沒寫進去」—— 全是查錯庫),而總管自己每張派工單都寫著「測試一律用 youlin」,卻一次都沒套用。 判準:任何打向 leo21c 座標的 kbdb_*/arcrun_* MCP 呼叫一律擋,除非明說 (touch /tmp/.leo21c-mcp-ok,單次 15 分鐘、會留痕到 .claude/hooks/ leo21c-mcp-guard.log)。讀寫都擋,但訊息不同:唯讀提示「你可能查錯地方」, 寫入提示「這會汙染真資料」。arcrun_whoami 本身永遠放行(唯一能確認身份的 工具,擋它會造成死結)。 已知限制(查過但查不到穩定識別法,不是猜測):MCP server 的 UUID 是這次連線 分配的,不是穩定識別碼,重裝/換 session 會換掉;~/.claude.json 等本機設定檔 裡找不到這兩條連線的來源設定,判斷是雲端 connector 層動態配的。因此這兩個 UUID 是寫死的(2026-08-27 由 arcrun_whoami 實測得到),且會過期。設計上不是 「表格以外的一律放行」,而是「不在表格裡的 UUID 一樣擋,且訊息明講清單可能 過期」——大聲失敗,不靜默放行到身份不明的目標(fail-closed)。 測試:hooks/tests/leo21c-mcp-guard.test.sh 19/19 通過,涵蓋擋(真庫讀/寫)、 放行(測試場讀/寫)、不擋(whoami 三種座標)、不擋(無關工具)、擋(未知UUID)、 戳記單次放行+留痕。既有測試套件(ask-user-question/dispatch-format/ factory-idle/main-and-prod-push/prod-write/stage-before-prod/sdd-guard) 全部重跑一遍,均維持原本通過狀態,未受本次改動影響。 hooks.json 新增一條 PreToolUse matcher:.*mcp__[0-9a-fA-F-]+__(kbdb_|arcrun_).* docs/hooks-inventory.md 補上新閘一行,並記錄目前實際磁碟數(49 檔/60 條) 跟這份表既有列表(47/57)之間還有既存落差(isep-presence-beacon.sh/ milestone-due-guard.sh 疑似兩支舊閘未收錄)——不是本票動的閘,未一併查證, 留給總管或後續票核實。 plugin.json 0.5.0 → 0.5.1(改完不升版沒人吃得到;check-version-consistency.sh 在本分支照慣例是紅的,tag 於 merge 時打)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# 46 支閘,白話盤點表
|
||||
# 47 支閘,白話盤點表
|
||||
|
||||
> 回應 `inkstone/InkStoneCo#40`:「如果加入了,我應該可以白話文看到 hooks 的內容?」
|
||||
> 這份表就是那個「白話文」——不用點開任何 `.sh` 檔,一行看懂一支閘在管什麼。
|
||||
@@ -7,14 +7,18 @@
|
||||
|
||||
## 一句話結論
|
||||
|
||||
`hooks/` 底下有 **46 個 `.sh` 檔**,`hooks.json` 實際掛上 **56 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
`hooks/` 底下有 **47 個 `.sh` 檔**,`hooks.json` 實際掛上 **57 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
其中 **3 支檔案存在但沒被掛上**(2 支是待人填的空範本、1 支是刻意留著沒開的止血帶,見下面「未生效」表)。
|
||||
下面按「你會在什麼時候撞到它」分組,一支一行。
|
||||
|
||||
> 🔴 **這兩個數字上一版是錯的(2026-08-26 實際數過才發現)**:本頁原本寫「43 個檔、53 條註冊」,
|
||||
> 而當時真實是 **45 個檔、55 條註冊**——中間有兩支閘進來時沒有回頭改這裡。
|
||||
> 現在的寫法是實際數出來的:
|
||||
> `ls hooks/*.sh | wc -l` = 46;`hooks.json` 展開後的 command 條目 = 56。
|
||||
> +1/+1 是本次(ISEP#69)新增的 `leo21c-mcp-guard.sh`。
|
||||
>
|
||||
> ⚠️ **這份表本身可能又已經漂移**:`ls hooks/*.sh | wc -l` 在本分支實測是 49
|
||||
> (比這裡寫的 47 多 2),初步比對疑似是 `isep-presence-beacon.sh`/
|
||||
> `milestone-due-guard.sh` 兩支已經掛進 `hooks.json` 卻沒被收進這張表——
|
||||
> 但那兩支不是本票(ISEP#69)動的閘,沒有一併查證+改動,留給總管或後續票核實。
|
||||
> **一份會偷偷過期的盤點表,跟沒有盤點表差不多**——見本頁最後「怎麼跟實況對帳」那段。
|
||||
|
||||
---
|
||||
@@ -42,6 +46,7 @@
|
||||
| `prod-write-guard.sh` | AI 想做任何「會真的改到線上正式帳號(leo21c)」的操作(不只是 push,也包含直接呼叫會寫入的工具)就擋下,交回總管處理。 | 🛑 擋 |
|
||||
| `not-my-branch-guard.sh` | AI 想 commit 到「別的 subagent 正在施工中」的分支(登記在 `branch-holds.md`)就擋下,避免兩個 AI 互踩同一條分支。 | 🛑 擋 |
|
||||
| `leo21c-write-guard.sh` | AI 想寫東西到你私人帳號 `leo21c` 就擋下——這個帳號只准你自己用,AI 的實驗一律走別的測試帳號。 | 🛑 擋 |
|
||||
| `leo21c-mcp-guard.sh` | AI 想用 Arcrun/KBDB 的 MCP 工具查或寫**你的真庫(leo21c)**就擋下(不管讀寫)——測試場是另一條 MCP 連線,沒指定就該用那條。`arcrun_whoami` 本身不擋(用來確認身份);真的要碰真庫要明說(`touch /tmp/.leo21c-mcp-ok`),會留痕。連線的 server id 若不在已知清單裡也擋(清單可能過期,寧可先擋不要靜默放行)。 | 🛑 擋 |
|
||||
| `release-tag-guard.sh` | AI 想打版本 tag,但 `plugin.json` 裡寫的版本號跟 tag 對不上就擋下——避免「這裡說 0.2.0、那裡說 0.1.0」各說各話。 | 🛑 擋 |
|
||||
| `ticket-api-bypass-guard.sh` | AI 想繞過 `scripts/ticket` 工具、直接打 API 開新 Gitea 票(會漏掉「開票前先搜過」這道檢查)就擋下。 | 🛑 擋 |
|
||||
| `reply-identity-guard.sh` | 直接打 Gitea API 貼留言到票上時,內文第一行沒有 `【身份】`(`總管`/`subagent`/`leo`)就擋下——票上多條線並行時,看不出哪一則是誰寫的。純讀取、走 `scripts/ticket` 正門、指令裡加 `reply-identity-ok` 都放行。 | 🛑 擋 |
|
||||
|
||||
Reference in New Issue
Block a user