修好一次性戳記恆擋:InkStoneCo 專案版 hooks 與 plugin 雙掛載
inkstone/ISEP#122:leo 三次要部署被 prod-write-guard.sh 恆擋,蓋了戳記 也放不了行。根因不在 prod-write-guard.sh 本身,而在 InkStoneCo/.claude/settings.json 還登記著一份 2026-08-20 立 ISEP plugin 之前的舊 hook,跟 plugin 自己的 hooks.json 同時掛在同一個事件上——每個 PreToolUse 都跑了兩次,一次性戳記被第一份消耗掉,第二份永遠看到空戳記。 實查(在這台機器的樹上實數):InkStoneCo 專案版登記著 38 支 hook, 34 支跟 plugin 完全同名同用途(純殘骸)、3 支是已退役機制 (claim-verify-police.sh/subagent-claim-worksheet.sh/sdd-guard.sh, ISEP#60/#91 早已裁定退役但專案版沒跟著退)、1 支(kv-write-guard.sh) 是專案版有、plugin 當時沒有的真閘。 這次: - kv-write-guard.sh 原樣搬進本 repo(B 組,PreToolUse Write|Edit|MultiEdit), 補齊那個真的缺口,附 8 條迴歸測試 - 新增 duplicate-hook-registration-guard.sh(E 組,SessionStart): 往後任何專案的 settings.json 又跟 plugin 長出同名登記,開場就點名, 不必再靠「戳記莫名其妙失效」才發現,附 8 條迴歸測試 - 兩支新閘:61→63 支、84→86 條註冊(在自己的樹上實數,不是加減推) InkStoneCo 那邊的清理(37 支殘骸從 settings.json 與 .claude/hooks/ 移除, kv-write-guard.sh 保留至本次升版並 /plugin update 之後)另外commit, 不在本 repo 範圍內。 驗證:重演過修好前的雙掛載(蓋一次戳記→專案版先吃掉→plugin 版恆擋, EXIT=2),也驗過修好後單次執行放行(EXIT=0)與不蓋戳記仍被擋(EXIT=2)。 待總管定版。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+21
-2
@@ -1,4 +1,4 @@
|
||||
# 61 支閘,白話盤點表
|
||||
# 63 支閘,白話盤點表
|
||||
|
||||
> 回應 `inkstone/InkStoneCo#40`:「如果加入了,我應該可以白話文看到 hooks 的內容?」
|
||||
> 這份表就是那個「白話文」——不用點開任何 `.sh` 檔,一行看懂一支閘在管什麼。
|
||||
@@ -7,10 +7,27 @@
|
||||
|
||||
## 一句話結論
|
||||
|
||||
`hooks/` 底下有 **61 個 `.sh` 檔**,`hooks.json` 實際掛上 **84 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
`hooks/` 底下有 **63 個 `.sh` 檔**,`hooks.json` 實際掛上 **86 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
其中 **3 支檔案存在但沒被掛上**(2 支是待人填的空範本、1 支是刻意留著沒開的止血帶,見下面「未生效」表)。
|
||||
下面按「你會在什麼時候撞到它」分組,一支一行。
|
||||
|
||||
> 📌 **`inkstone/ISEP#122`(2026-09-02)進來兩支、+2 條**:`kv-write-guard.sh`(B 組,
|
||||
> 2026-08-25 立於 InkStoneCo 專案版,原樣搬進來)與 `duplicate-hook-registration-guard.sh`
|
||||
> (E 組,這次新寫)。61→**63** 支、84→**86** 條,兩個數字都是加完之後**在自己的樹上當場數出來的**
|
||||
> (`ls hooks/*.sh | wc -l`/`grep -c '"command":' hooks/hooks.json`),不是拿上一版加二。
|
||||
>
|
||||
> 這張票查的是「總管三次要部署被 `prod-write-guard.sh` 恆擋、蓋了戳記也放不了行」,
|
||||
> 根因不在 `prod-write-guard.sh` 本身,而在 `InkStoneCo/.claude/settings.json`
|
||||
> 還登記著一份跟 ISEP plugin 同名的舊 hook——每個 `PreToolUse` 事件都跑了**兩次**,
|
||||
> 一次性戳記被第一份消耗掉,第二份永遠看到空戳記、恆擋。實查:專案版登記著 38 支,
|
||||
> **34 支跟 plugin 完全同名同用途**(純殘骸,已從 `InkStoneCo/.claude/settings.json`
|
||||
> 刪除登記)、**3 支是已經退役的機制**(`claim-verify-police.sh`/
|
||||
> `subagent-claim-worksheet.sh`/`sdd-guard.sh`,同樣刪除)、
|
||||
> **1 支(`kv-write-guard.sh`)是專案版有、plugin 當時沒有的真閘**——原樣搬進本 repo,
|
||||
> 這就是這次 B 組新增的那一支。`duplicate-hook-registration-guard.sh` 是防復發的機械閘:
|
||||
> 下次任何專案的 `settings.json` 又長出跟 plugin 同名的登記,SessionStart 就會點名,
|
||||
> 不必再靠「戳記莫名其妙失效」這種事後除錯才發現。
|
||||
>
|
||||
> 🔴 **這兩個數字上一版是錯的(2026-08-26 實際數過才發現)**:本頁原本寫「43 個檔、53 條註冊」,
|
||||
> 而當時真實是 **45 個檔、55 條註冊**——中間有兩支閘進來時沒有回頭改這裡。
|
||||
> 現在的寫法是實際數出來的:
|
||||
@@ -145,6 +162,7 @@
|
||||
| `mistake-needs-ticket-guard.sh` | AI 想往 `mistakes.md`(教訓紀錄)新增一條「機制可以防止」的教訓,卻沒附對應票號就擋下——沒有票號的教訓沒有人會回頭處理。 | 🛑 擋 |
|
||||
| `wiki-size-guard.sh` | AI 想**一口氣砍掉 wiki 檔一大半內容**(淨縮水超過 800 字且超過原本 45%)就擋一次——那不是一次編輯,那是一次壓縮,而**壓縮會弄丟東西,弄丟的當下沒有人會發現**。出路是走 `scripts/wiki-compress`:它逼你附票號、把壓掉了什麼寫進 `.compress-log.md`,並用內文雜湊**逐條對帳**證明沒弄丟。只是改字、加字、小修一律不碰;真要手改就在內容裡放 `wiki-compress-ok` 留痕。 | 🛑 擋(至多攔一次) |
|
||||
| `pending-changes-retired.sh` | AI 想寫東西進已經廢除的 `pending-changes.md` 檔案就擋下——這個檔案已停用,規格變更一律改開 Gitea 票。 | 🛑 擋 |
|
||||
| `kv-write-guard.sh` | AI 想新增一行「往 KV 綁定寫入」的程式碼(`大寫識別字.put(`/`.delete(`)就擋下——長效資料一律要走 KBDB API,KV 只是暫存。判準是形狀(全大寫識別字 + `.put`/`.delete`),不是列名字清單;只讀(`.get`/`.list`)放行,刪除既有 KV 寫入(退休戰)也放行。真的是短命資料(session/nonce/有 TTL 的快取)在那一行尾端加 `kv-ok: <為什麼>` 留痕放行。2026-08-25 立於 InkStoneCo 專案版,`inkstone/ISEP#122` 原樣搬進本 repo。 | 🛑 擋 |
|
||||
|
||||
> 🔴 **`sdd-guard.sh` 已於 `inkstone/ISEP#91` 退役**(原本掛在這一組)。
|
||||
> 它擋的是「動 code 檔時,`status: active` 的 SDD 不是恰好一份」。
|
||||
@@ -209,6 +227,7 @@
|
||||
| `overdue-nag-guard.sh` | 對話一開始就去 Gitea 撈**沒有人會叫的事**:逾期的 milestone、掛著等你的票(標「等了幾天」)、標著「有人在做」卻好幾天沒動的票;撈完用白話講出來,**有事就發 Telegram 給你**。沒東西可報時它會說「查過了,沒有」——**安靜跟壞掉長得一模一樣**。發不出去時不會靜默:它會先問這個 session 的 `prod-write-guard` 會不會擋(舊版把「發通知」誤認成「部署」),擋就改貼回票上並把原文印在眼前。只在開 session 時跑一次,**不輪詢、不掛排程**。 | 📝 記錄(context 注入 + Telegram) |
|
||||
| `wiki-size-guard.sh` | 對話一開始講出「哪幾個 wiki 檔已經沒有人讀得完了」(預設超過 1200 行就點名)。**讀不完的必讀檔,跟沒有那個檔的差別只在於它讓人以為有。** 另一半掛在寫檔上,見 B 組。 | 📝 記錄(context 注入) |
|
||||
| `skill-deploy-drift-guard.sh` | 如果「全機真正在用的 skill」跟「repo 裡版控的正本」內容對不上,就在開場講出來——避免用著一份沒人知道已經跟正本分家的舊拷貝。 | 📝 記錄 |
|
||||
| `duplicate-hook-registration-guard.sh` | 如果這個專案自己的 `.claude/settings.json` 還登記著跟 ISEP plugin 同名的舊 hook,就在開場點名是哪幾支——**同一個動作跑兩次**,多數閘只是白跑,但帶「蓋一次戳記只放行一次」語意的閘會被第一份吃光,第二份永遠看到空戳記、恆擋(`inkstone/ISEP#122` 就是這樣,2026-09-01 撞了三次才被抓到)。判準是「有沒有真的註冊」,不是「檔案存不存在」。 | 📝 記錄(context 注入) |
|
||||
|
||||
## F. AI 想結束這一輪、要收工的時候(Stop)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user