沒人會叫的事會自己叫+讀不完的必讀檔要被整理(inkstone/ISEP#93、inkstone/ISEP#89) #106

Merged
claude-code merged 4 commits from feat/nag-and-wiki-compress into main 2026-08-28 01:28:01 +00:00
Member

【身份】subagent/inkstone/ISEP/feat/nag-and-wiki-compress

closes #93
closes #89

兩張票放同一條分支:都是「該發生卻不會自己發生的事」,觸發時機都在 session 邊界,
實作面共用同一套「去查、發現、講出來」的骨架。

版本號待總管定版plugin.json 目前是併回來的 0.14.0,我沒有動它)。


#93 — 逾期/掛著沒人接的事會主動叫

做什麼
scripts/isep-nag 撈三種沒人會叫的事:逾期 milestone/掛著等 leo 的票(標等了幾天)/標著「有人在做」卻好幾天沒動的票
scripts/isep-notify 發 Telegram,而且發不出去的時候不會安靜
hooks/overdue-nag-guard.sh SessionStart 跑一次(不輪詢、不 fan-out、不掛 Actions
hooks/tests/overdue-nag.test.sh 36 條,全程離線

對票上四條驗收

  1. 實跑撈得出票上點名的那五個逾期 milestone(08-24 三個、08-26 兩個),
    訊息白話:每段講「這對你意味什麼」,票標「等了 N 天」,短版給一個可以回的詞。
  2. 沒東西時說「查過了,沒有」;撈不到資料時說「我沒查到」而不是「沒有事情逾期」
    ——那兩句講成同一句就是把無知包裝成情報。
  3. 開 session 自己跑過一次,不用有人記得下指令。開場延遲 5.0 秒
    (長短版一次算完;分兩次呼叫是 10 秒)。逾時/沒網路都不卡開場,子 session 不叫。
  4. 驗不了,而且原因不在這條分支的程式碼——見下面「已知斷點」。

🔴 「這個 session 發不發得出去」被做成查得到的事實

工單補的那個限制已經處理:prod-write-guard v0.10.0 才認得出「發通知」不是「部署」,
hook 的註冊路徑是 session 啟動當下寫死的 ⇒ 更新 plugin 之後要開新 session 才生效
能不能發,是每個 session 各自不同的事實。

isep-notify 因此先拿真的要送的那一則去問這個 session 註冊的那支閘
(hook 裡有 CLAUDE_PLUGIN_ROOT,那就是註冊的那一份,沒有第二種可能),
把「版本+是哪個檔+會不會擋」寫成 gate-verdict.json,之後手動跑也查得到。然後:

  • 放行 ⇒ 送,並驗內層 data.data.ok(外層 200 不算送到)
  • 會擋 ⇒ 不繞路,改貼回票上並把原文印在眼前

為什麼不繞路:這支用 urllib,而 prod-write-guard 掛在 Bash 上——不問就一定送得出去。
一支「繞過閘也照送」的工具,會讓那道閘對整條 python 路徑失效。
本支自己去問那道閘,這比 shell 那條路更嚴,不是更鬆

「會擋」那條路用 git 歷史裡的真跡c263866 那一版閘)測過,不是拿假檔演的。


#89 — wiki 太長時有人整理

做什麼
scripts/wiki-compress auditplanapplyverifybench 五個動詞
hooks/wiki-size-guard.sh SessionStart 點名太長的檔;寫檔時擋「沒走流程的壓縮」
hooks/tests/wiki-compress.test.sh 25 條,全程離線、不碰真的 wiki

🔴 最重要的設計決定:只搬不改

票上第 2 條驗收是「不能弄丟任何一條教訓(要能逐條對帳)」。
⇒ 所以機器不改寫任何一條的正文,一個字都不動:只做「搬去 archive + 產目錄 + 標 ×N」。

「合併同類、濃縮成一行」聽起來更漂亮,但那要重寫正文,
重寫的當下沒有人會發現弄丟了什麼(票上原話)。
只搬不改的好處是 verify 可以用內文雜湊逐條對帳——「沒弄丟」是算出來的,不是宣稱的。

合併留給人,機器負責把該合併的那批點名出來
mistakes.md 260 條裡有 73 條自己寫著「同款第 N 次」「又犯一次」「同一個病」(占 28%)。
用標題相似度只找得到 1 對——人下的判斷比機器算的相似度準得多,照抄它,不要重新猜一遍。

對票上三條驗收(拿現在的 mistakes.md 複本實壓,真的 wiki 一個字沒動):

  1. 7,681 行 → 1,199 行;80 個查詢命中率 80/80
    定位成本 2,956 → 131 行快 22.5 倍bench,取樣均勻分佈全檔,不是只考最新那批)
  2. 260 條一條都沒少verify 逐條對帳)。
    而且 verify 反向測過:真的弄丟一條時它抓得到
    ——一個抓不到問題的對帳表,比沒有更糟,因為它會被當成證據
  3. apply 沒有 --ticket 不准跑(裸號也不收),並把「這一版壓掉了什麼」
    寫進 .compress-log.md,含下一個人跑得起來的對帳指令

閘的判準是字元數不是關鍵字:wiki 檔淨縮水 >800 字且 >45% 才擋,至多擋一次,
留痕式出口是 wiki-compress-ok(同 wiki-secret-ok 的慣例)。


已知斷點:notify_leo 通道現在是斷的(不是這條分支造成的)

POST …/webhooks/named/leo/notify_leo/trigger
→ 404 {"error":"找不到 workflow \"notify_leo\",請先執行 acr push"}

閘判定 pass、網路通、這條路本來就不需要金鑰 ⇒ 是那台實例上沒有這支工作流
總管用 MCP 複查,範圍比這裡更廣:arcrun_get_workflow(notify_leo)not_found
搜尋只回 ship_refresh_cdn 一支且執行紀錄寫著「圖定義已失效」
那台實例上的工作流定義是整批失效的

修它要寫 leo 的個人帳號,而 leo21c-write-guard.sh(leo 2026-08-20 立)明文禁止
這是真人閘,總管也不能解。

📌 這條斷了不代表 #93 沒交付:本次的設計前提就是「不假設發得出去」——
實測那兩次的退路都真的走通了#93#issuecomment-51825184 是它自動觸發留下的,
不是手貼的),並把原文印在眼前。通道修好後不必改任何程式碼,
重跑 python3 scripts/isep-nag --notify 就能補驗那一格。

過程中順手修掉一個真 bug:urllib 不帶 User-Agent 會被 Cloudflare 回 403 error code 1010
而 curl 自帶 UA ⇒ 同一個網址 curl 通、python 不通,非常容易被誤讀成「通道壞了」。


併回 main(最新基底 = 5fca644,v0.15.0)

併過兩輪:v0.14.0(五批)與 v0.15.0#105 派工紀律三件)。
每一處衝突都兩邊都留,沒丟掉任何一側;plugin.json 版本吃 main 的 0.15.0
(總管已定版,我沒有動它)。

🔴 hooks.json 這次 git 自動合成功了,而那正是最危險的情況

它是 JSON——合錯了語法照樣合法、閘卻不見了,不會有任何東西喊一聲。
所以「沒有衝突」不等於「沒掉東西」。複驗做了兩件:

① 逐支點名(82 條 / 60 支,指令已寫進 README.md「裝什麼」那段)
② 跟兩個父節點做集合對照

merged 82  =  main 79  +  我的 3
從 main 掉了:            0 條
從我這邊掉了:            0 條
兩邊都沒有卻冒出來的:    0 條

#105 三支與我的兩支同時在,位置也對:

roster-guard.sh              PreToolUse   Agent / Task
diagnosis-evidence-guard.sh  PreToolUse   Bash
investigate-first-stamp.sh   PostToolUse  Agent|Task / SendMessage
overdue-nag-guard.sh         SessionStart
wiki-size-guard.sh           SessionStart / PreToolUse Write|Edit|MultiEdit

盤點(全部在合併後的樹上實數)

ls hooks/*.sh | wc -l                    58 → 60
grep -c '"command":' hooks/hooks.json    79 → 82
ls agents/*.md | wc -l                        7
ls -p scripts | grep -v / | wc -l            48
未掛進 hooks.json 的 .sh                       3(重數過,與盤點表原本寫的一致)

順手修掉的漂移(每次併都有,這次三個)

  • docs/hooks-inventory.md 的標頭被貼成兩份、「一句話結論」被貼成三份,數字還互相打架
  • README.mdhooks/ 那列累積成四列,其中兩列是舊數字
  • plugin.json 描述欄寫「49 支腳本」,而用盤點表自己寫死的那道指令實數是 48

docs/TESTING.md 裡我的兩格是 A21/A22(併之前兩邊都叫 A16/A17,撞號)。


測試(合併後全部重跑)

hooks/tests 23 支全綠:

overdue-nag 36        wiki-compress 25
ask-user-question 14  countdown 20         diagnosis-evidence 26  dispatch-format 52
factory-idle 33       gate-ok 17           gitea-arm-check 16     presence-beacon 14
cross-repo 19         main-and-prod-push 10  mainline-focus 24    mainline-idle 61
milestone-account 22  pr-verdict 52        prod-write 37          reply-identity 11
roster 24             sdd 8                search-is-not-proof 31 stage-before-prod 16
unpushed-police 10
scripts/test-* 13 支全綠(release-manifest 21、milestone-account 23、
                        debt-worklist 47、ticket-handoff-writeback 49 …)
claude plugin validate .            ✔ passed
scripts/check-version-consistency   ✅ 0.15.0 = v0.15.0

🔴 四支要帶參數才跑得起來,不帶會紅——而那是假紅
prod-write-guardstage-before-prod-guardmain-and-prod-push-guard 要帶 hook 路徑,
main-and-prod-push-guard-cross-repo 要帶 hook 的絕對路徑(帶 repo 根目錄會回「沙盒建不起來」),
gitea-arm-check 要帶 repo 根目錄。

跑之前有清 CLAUDE_CODE_CHILD_SESSION(不清的話有幾群會全綠而且是假綠)。
ask-user-question-guard.live.test.sh(會叫 haiku)沒跑。

🔴 五個新檔需要 100755(兩支 hook 被 hooks.json 直接執行、三支 CLI)。
用 git 推的,已複驗遠端分支上的模式:git ls-tree -r gitea/feat/nag-and-wiki-compress | grep -c 100755
123,與本地一致。不要改用 Gitea 檔案 API 重送——那個 API 沒有 mode 參數,
一律 100644,那兩支閘會變成安裝了卻不會執行,而且失敗是安靜的

【身份】subagent/inkstone/ISEP/feat/nag-and-wiki-compress closes #93 closes #89 兩張票放同一條分支:都是「**該發生卻不會自己發生的事**」,觸發時機都在 session 邊界, 實作面共用同一套「去查、發現、講出來」的骨架。 **版本號待總管定版**(`plugin.json` 目前是併回來的 `0.14.0`,我沒有動它)。 --- ## `#93` — 逾期/掛著沒人接的事會主動叫 | 檔 | 做什麼 | |---|---| | `scripts/isep-nag` | 撈三種沒人會叫的事:逾期 milestone/掛著等 leo 的票(標等了幾天)/標著「有人在做」卻好幾天沒動的票 | | `scripts/isep-notify` | 發 Telegram,而且**發不出去的時候不會安靜** | | `hooks/overdue-nag-guard.sh` | SessionStart 跑一次(**不輪詢、不 fan-out、不掛 Actions**) | | `hooks/tests/overdue-nag.test.sh` | 36 條,全程離線 | **對票上四條驗收**: 1. ✅ 實跑撈得出票上點名的**那五個逾期 milestone**(08-24 三個、08-26 兩個), 訊息白話:每段講「這對你意味什麼」,票標「等了 N 天」,短版給一個可以回的詞。 2. ✅ 沒東西時說「**查過了,沒有**」;撈不到資料時說「我沒查到」而**不是**「沒有事情逾期」 ——那兩句講成同一句就是把無知包裝成情報。 3. ✅ 開 session 自己跑過一次,不用有人記得下指令。開場延遲 **5.0 秒** (長短版一次算完;分兩次呼叫是 10 秒)。逾時/沒網路都不卡開場,子 session 不叫。 4. ⛔ **驗不了,而且原因不在這條分支的程式碼**——見下面「已知斷點」。 ### 🔴 「這個 session 發不發得出去」被做成查得到的事實 工單補的那個限制已經處理:`prod-write-guard` v0.10.0 才認得出「發通知」不是「部署」, 而 **hook 的註冊路徑是 session 啟動當下寫死的** ⇒ 更新 plugin 之後要開新 session 才生效 ⇒ **能不能發,是每個 session 各自不同的事實。** `isep-notify` 因此**先拿真的要送的那一則去問這個 session 註冊的那支閘** (hook 裡有 `CLAUDE_PLUGIN_ROOT`,那就是註冊的那一份,沒有第二種可能), 把「版本+是哪個檔+會不會擋」寫成 `gate-verdict.json`,之後手動跑也查得到。然後: - 放行 ⇒ 送,並驗**內層** `data.data.ok`(外層 200 不算送到) - 會擋 ⇒ **不繞路**,改貼回票上並把原文印在眼前 **為什麼不繞路**:這支用 urllib,而 `prod-write-guard` 掛在 `Bash` 上——不問就一定送得出去。 一支「繞過閘也照送」的工具,會讓那道閘對整條 python 路徑失效。 本支自己去問那道閘,**這比 shell 那條路更嚴,不是更鬆**。 「會擋」那條路用 **git 歷史裡的真跡**(`c263866` 那一版閘)測過,不是拿假檔演的。 --- ## `#89` — wiki 太長時有人整理 | 檔 | 做什麼 | |---|---| | `scripts/wiki-compress` | `audit`/`plan`/`apply`/`verify`/`bench` 五個動詞 | | `hooks/wiki-size-guard.sh` | SessionStart 點名太長的檔;寫檔時擋「沒走流程的壓縮」 | | `hooks/tests/wiki-compress.test.sh` | 25 條,全程離線、不碰真的 wiki | ### 🔴 最重要的設計決定:**只搬不改** 票上第 2 條驗收是「不能弄丟任何一條教訓(要能逐條對帳)」。 ⇒ 所以機器**不改寫任何一條的正文,一個字都不動**:只做「搬去 archive + 產目錄 + 標 `×N`/`↻`」。 「合併同類、濃縮成一行」聽起來更漂亮,但那要重寫正文, 而**重寫的當下沒有人會發現弄丟了什麼**(票上原話)。 只搬不改的好處是 `verify` 可以用**內文雜湊**逐條對帳——「沒弄丟」是算出來的,不是宣稱的。 合併留給人,機器負責**把該合併的那批點名出來**: `mistakes.md` 260 條裡有 **73 條自己寫著「同款第 N 次」「又犯一次」「同一個病」**(占 28%)。 用標題相似度只找得到 1 對——**人下的判斷比機器算的相似度準得多,照抄它,不要重新猜一遍。** **對票上三條驗收**(拿**現在的 `mistakes.md` 複本**實壓,真的 wiki 一個字沒動): 1. ✅ **7,681 行 → 1,199 行**;80 個查詢**命中率 80/80**, 定位成本 `2,956 → 131 行`,**快 22.5 倍**(`bench`,取樣均勻分佈全檔,不是只考最新那批) 2. ✅ **260 條一條都沒少**(`verify` 逐條對帳)。 而且 `verify` **反向測過**:真的弄丟一條時它抓得到 ——**一個抓不到問題的對帳表,比沒有更糟**,因為它會被當成證據 3. ✅ `apply` 沒有 `--ticket` 不准跑(裸號也不收),並把「這一版壓掉了什麼」 寫進 `.compress-log.md`,含下一個人跑得起來的對帳指令 閘的判準是**字元數不是關鍵字**:wiki 檔淨縮水 >800 字且 >45% 才擋,至多擋一次, 留痕式出口是 `wiki-compress-ok`(同 `wiki-secret-ok` 的慣例)。 --- ## ⛔ 已知斷點:`notify_leo` 通道現在是斷的(不是這條分支造成的) ``` POST …/webhooks/named/leo/notify_leo/trigger → 404 {"error":"找不到 workflow \"notify_leo\",請先執行 acr push"} ``` 閘判定 `pass`、網路通、這條路本來就不需要金鑰 ⇒ **是那台實例上沒有這支工作流**。 總管用 MCP 複查,範圍比這裡更廣:`arcrun_get_workflow(notify_leo)` → `not_found`, 搜尋只回 `ship_refresh_cdn` 一支且執行紀錄寫著「圖定義已失效」 ⇒ **那台實例上的工作流定義是整批失效的**。 修它要寫 leo 的個人帳號,而 `leo21c-write-guard.sh`(leo 2026-08-20 立)明文禁止 ⇒ **這是真人閘,總管也不能解。** 📌 **這條斷了不代表 `#93` 沒交付**:本次的設計前提就是「不假設發得出去」—— 實測那兩次的退路**都真的走通了**(`#93` 的 `#issuecomment-5182`、`5184` 是它自動觸發留下的, 不是手貼的),並把原文印在眼前。通道修好後不必改任何程式碼, 重跑 `python3 scripts/isep-nag --notify` 就能補驗那一格。 過程中順手修掉一個真 bug:**urllib 不帶 User-Agent 會被 Cloudflare 回 `403 error code 1010`**, 而 curl 自帶 UA ⇒ 同一個網址 curl 通、python 不通,非常容易被誤讀成「通道壞了」。 --- ## 併回 main(最新基底 = `5fca644`,v0.15.0) 併過兩輪:`v0.14.0`(五批)與 `v0.15.0`(`#105` 派工紀律三件)。 每一處衝突都**兩邊都留**,沒丟掉任何一側;`plugin.json` 版本吃 main 的 `0.15.0` (總管已定版,**我沒有動它**)。 ### 🔴 `hooks.json` 這次 git 自動合成功了,而那正是最危險的情況 它是 JSON——**合錯了語法照樣合法、閘卻不見了,不會有任何東西喊一聲。** 所以「沒有衝突」不等於「沒掉東西」。複驗做了兩件: **① 逐支點名**(82 條 / 60 支,指令已寫進 `README.md`「裝什麼」那段) **② 跟兩個父節點做集合對照**: ``` merged 82 = main 79 + 我的 3 從 main 掉了: 0 條 從我這邊掉了: 0 條 兩邊都沒有卻冒出來的: 0 條 ``` `#105` 三支與我的兩支同時在,位置也對: ``` roster-guard.sh PreToolUse Agent / Task diagnosis-evidence-guard.sh PreToolUse Bash investigate-first-stamp.sh PostToolUse Agent|Task / SendMessage overdue-nag-guard.sh SessionStart wiki-size-guard.sh SessionStart / PreToolUse Write|Edit|MultiEdit ``` ### 盤點(全部在合併後的樹上實數) ``` ls hooks/*.sh | wc -l 58 → 60 grep -c '"command":' hooks/hooks.json 79 → 82 ls agents/*.md | wc -l 7 ls -p scripts | grep -v / | wc -l 48 未掛進 hooks.json 的 .sh 3(重數過,與盤點表原本寫的一致) ``` ### 順手修掉的漂移(每次併都有,這次三個) - `docs/hooks-inventory.md` 的標頭被貼成**兩份**、「一句話結論」被貼成**三份**,數字還互相打架 - `README.md` 的 `hooks/` 那列累積成**四列**,其中兩列是舊數字 - `plugin.json` 描述欄寫「49 支腳本」,而用盤點表自己寫死的那道指令實數是 **48** `docs/TESTING.md` 裡我的兩格是 **A21/A22**(併之前兩邊都叫 A16/A17,撞號)。 --- ## 測試(合併後全部重跑) `hooks/tests` 23 支全綠: ``` overdue-nag 36 wiki-compress 25 ask-user-question 14 countdown 20 diagnosis-evidence 26 dispatch-format 52 factory-idle 33 gate-ok 17 gitea-arm-check 16 presence-beacon 14 cross-repo 19 main-and-prod-push 10 mainline-focus 24 mainline-idle 61 milestone-account 22 pr-verdict 52 prod-write 37 reply-identity 11 roster 24 sdd 8 search-is-not-proof 31 stage-before-prod 16 unpushed-police 10 scripts/test-* 13 支全綠(release-manifest 21、milestone-account 23、 debt-worklist 47、ticket-handoff-writeback 49 …) claude plugin validate . ✔ passed scripts/check-version-consistency ✅ 0.15.0 = v0.15.0 ``` 🔴 **四支要帶參數才跑得起來,不帶會紅——而那是假紅**: `prod-write-guard`/`stage-before-prod-guard`/`main-and-prod-push-guard` 要帶 hook 路徑, `main-and-prod-push-guard-cross-repo` 要帶 **hook 的絕對路徑**(帶 repo 根目錄會回「沙盒建不起來」), `gitea-arm-check` 要帶 repo 根目錄。 跑之前有清 `CLAUDE_CODE_CHILD_SESSION`(不清的話有幾群會全綠而且是假綠)。 `ask-user-question-guard.live.test.sh`(會叫 haiku)沒跑。 🔴 **五個新檔需要 `100755`**(兩支 hook 被 `hooks.json` 直接執行、三支 CLI)。 用 git 推的,已複驗遠端分支上的模式:`git ls-tree -r gitea/feat/nag-and-wiki-compress | grep -c 100755` = **123**,與本地一致。**不要改用 Gitea 檔案 API 重送**——那個 API 沒有 mode 參數, 一律 `100644`,那兩支閘會變成安裝了卻不會執行,而且**失敗是安靜的**。
claude-code added 3 commits 2026-08-28 01:18:07 +00:00
兩張票放同一條分支:都是「該發生卻不會自己發生的事」,觸發點都在 session 邊界。

## inkstone/ISEP#93 —— 逾期和掛著沒人接的事會主動叫

- scripts/isep-nag        撈三種沒人會叫的事(逾期 milestone/等 leo 的票/掉在地上的棒子)
- scripts/isep-notify     發 Telegram,而且**發不出去的時候不會安靜**
- hooks/overdue-nag-guard.sh  SessionStart 跑一次(不輪詢、不 fan-out、不掛 Actions)
- hooks/tests/overdue-nag.test.sh  35 條,全程離線

實跑撈得出票上點名的那五個逾期 milestone(08-24 三個、08-26 兩個)。
沒東西可報時會說「查過了,沒有」——安靜跟壞掉長得一模一樣。

🔴 工單補的那個限制(今天實測出來的)已經處理:
「能不能發得出去」取決於這個 session 載到的 ISEP 是哪一版
(prod-write-guard v0.10.0 才認得出 notify_leo 不是部署,而 hook 註冊路徑
在 session 啟動當下就寫死了)。所以 isep-notify 會**先拿真的要送的那一則
去問這個 session 註冊的那支閘**,把判定寫成檔(誰都查得到),然後:
  · 放行 ⇒ 送,並驗內層 data.data.ok(外層 200 不算送到)
  · 會擋 ⇒ **不繞路**,改貼回票上並把原文印在眼前
用 git 歷史裡的真跡(c263866 那一版閘)測過「會擋」那條路。

 實測發現通道本身現在是斷的:實例上找不到 notify_leo 工作流(404)。
   不是閘、不是網路、不是金鑰。詳情與修法寫在 docs/TESTING.md 最後一段。
   退路兩次都走通了(inkstone/ISEP#93 comment 5182、5184)。

## inkstone/ISEP#89 —— wiki 太長時有人整理

- scripts/wiki-compress   audit/plan/apply/verify/bench 五個動詞
- hooks/wiki-size-guard.sh  SessionStart 點名太長的檔;寫檔時擋「沒走流程的壓縮」
- hooks/tests/wiki-compress.test.sh  25 條,全程離線、不碰真的 wiki

設計上最重要的一條:**只搬不改**,正文一個字都不動。
「合併同類、濃縮成一行」要重寫正文,而重寫的當下沒有人會發現弄丟了什麼。
所以機器只做「搬 + 目錄 + 標 ×N/↻」,合併留給人。

拿現在的 mistakes.md 複本實壓過(不動真的 wiki):
  7,681 行 → 1,199 行
  260 條一條都沒少(verify 用內文雜湊逐條對帳)
  80 個查詢命中率 80/80,定位成本 2,956 → 131 行,**快 22.5 倍**(bench)
verify 反向測過:真的弄丟一條時它抓得到(抓不到的對帳表比沒有更糟)。

## 盤點數字

在這棵樹上當場數的,不是拿上一版加減推的:
  ls hooks/*.sh | wc -l              → 55(was 53)
  grep -c '"command":' hooks.json    → 71(was 68)
plugin.json/README/hooks-inventory 三處同步改。
**版本號沒動**(0.11.0),待總管定版。
2026-08-28 第一版漏了這一格,而它剛好就在實測時咬到:
閘判定 pass、Telegram 卻 404(實例上找不到 notify_leo 工作流),
退路留言貼上票之後**只看得到 pass**——真正的斷點一個字都沒進票。
⇒ 下一個人會去修閘,而斷點根本不在那裡。

把留言內文抽成 fallback_body()(獨立成一支就是為了測得到),
測試從「看原始碼有沒有那個字串」改成**真的產一份留言出來檢查**:
斷點原因、原文、身份欄三格都要在。36 條全綠。
衝突全部**兩邊都留**,沒有丟掉任何一側:

- hooks.json      main 的 `scripts/mainline refresh` + 我的兩支,同一個
                  SessionStart 陣列裡並存
- plugin.json     版本吃 main 的 0.14.0(**沒有自己決定版本**),描述欄的
                  三個數字在合併後的樹上重數
- README.md       main 那格被貼成兩列(54 支/69 條 與 54 支/71 條,互相矛盾),
                  收成一列並填上實數
- hooks-inventory main 的 `mainline refresh` 那列 + 我的兩列;標頭與
                  「一句話結論」的數字重數
- TESTING.md      兩邊各自新增的格子都留。**我的兩格改號成 A21/A22**——
                  併之前兩邊都叫 A16/A17,撞號(這一頁本來就已經有
                  三組重複的 A14–A18,這次至少沒有再加一組)

盤點(`ls hooks/*.sh | wc -l`、`grep -c '"command":' hooks/hooks.json`、
`ls -p scripts | grep -v / | wc -l`,都在**合併後**的樹上跑):

    55 → 57 支 .sh
    72 → 75 條註冊
         47 支腳本

📌 順手抓到一個漂移:main 的 plugin.json 描述欄寫「48 支腳本」,
   而用 hooks-inventory 自己寫死的那道指令實數是 44(main)/47(合併後)。
   已記在 hooks-inventory 的版本註記裡——**同一個病,第 N 次,只是換一欄。**

📌 TESTING.md 的「已知斷點」那段補上總管用 MCP 查到的更廣範圍:
   不只 notify_leo 不見了,那台實例的工作流定義是**整批失效**;
   而且修它要寫 leo 的個人帳號 ⇒ `leo21c-write-guard.sh` 明文禁止
   ⇒ **那是真人閘,總管也不能解**。

測試(合併後全部重跑,帶對參數):
  我的兩套          overdue-nag 36/36、wiki-compress 25/25
  hooks/tests/*     ask-user-question 14、countdown 20、dispatch-format 33、
                    factory-idle 33、gate-ok 17、presence-beacon 14、
                    mainline-focus 24、mainline-idle 61、milestone-account 22、
                    pr-verdict 52、reply-identity 11、sdd 8、
                    search-is-not-proof 31、unpushed-police 10、
                    prod-write 37、stage-before-prod 16、
                    main-and-prod-push 10、cross-repo 19、gitea-arm-check 16
  scripts/test-*    13 支全綠(含 release-manifest 21、milestone-account 23、
                    debt-worklist 47、ticket-handoff-writeback 49)
  claude plugin validate . 通過;check-version-consistency 通過(0.14.0 = v0.14.0)
claude-code added 1 commit 2026-08-28 01:26:03 +00:00
## hooks.json:這次 git 自動合成功了,而那正是最危險的情況

`hooks.json` 是 JSON——**合錯了語法照樣合法、閘卻不見了,不會有任何東西喊一聲。**
所以「沒有衝突」不等於「沒掉東西」,一律再做兩件事:

① 逐支點名(指令已寫進 README「裝什麼」那段)→ 82 條,60 支各自幾條全部列出
② 跟**兩個父節點**做集合對照:

    merged 82 = main 79 + 我的 3
    從 main 掉了:0 條
    從我這邊掉了:0 條
    兩邊都沒有卻冒出來的:0 條

`#105` 三支與我的兩支同時在,位置也對:

    roster-guard.sh              PreToolUse  Agent / Task
    diagnosis-evidence-guard.sh  PreToolUse  Bash
    investigate-first-stamp.sh   PostToolUse Agent|Task / SendMessage
    overdue-nag-guard.sh         SessionStart
    wiki-size-guard.sh           SessionStart / PreToolUse Write|Edit|MultiEdit

(總管提醒的 `roster-guard` vs `mainline-focus-guard` 那種「同一陣列位置兩邊各一支」
 這次沒有再發生衝突,但兩支都在,各 2 條。)

## 三處文字衝突:兩邊都留,數字重數

- plugin.json     版本吃 main 的 **0.15.0**(總管已定版,**我沒有動它**);
                  描述欄補上 main 新增的「7 位有名字的工人」,三個數字重數
- README.md       吃 main 的新表格結構(多了 agents/commands/skills/scripts 四列),
                  數字重數;並把累積成**四列**的 `hooks/` 收成一列
- hooks-inventory 標頭被貼成兩份、「一句話結論」被貼成**三份**(數字還互相打架),
                  各收成一份;版本註記兩邊都留

## 盤點(全部在合併後的樹上實數,不是加減推的)

    ls hooks/*.sh | wc -l                    58 → 60
    grep -c '"command":' hooks/hooks.json    79 → 82
    ls agents/*.md | wc -l                        7
    ls -p scripts | grep -v / | wc -l            48
    未掛進 hooks.json 的 .sh                       3(與本頁原本寫的一致,重數過)

📌 抓到的漂移(每次併都有一個,這次三個):
   ① hooks-inventory 的標頭 ×2、一句話結論 ×3
   ② README 的 `hooks/` 列 ×4,其中兩列是舊數字
   ③ plugin.json 描述欄寫「49 支腳本」,而用本頁寫死的那道指令實數是 48

## 測試(合併後全部重跑,帶對參數)

hooks/tests 23 支全綠:ask-user-question 14、countdown 20、diagnosis-evidence 26、
dispatch-format 52、factory-idle 33、gate-ok 17、gitea-arm-check 16、
presence-beacon 14、cross-repo 19、main-and-prod-push 10、mainline-focus 24、
mainline-idle 61、milestone-account 22、**overdue-nag 36**、pr-verdict 52、
prod-write 37、reply-identity 11、roster 24、sdd 8、search-is-not-proof 31、
stage-before-prod 16、unpushed-police 10、**wiki-compress 25**

scripts/test-* 13 支全綠。
claude plugin validate . ✔ passed;check-version-consistency  0.15.0 = v0.15.0。
兩支新 SessionStart hook 併完實跑過,閘判定探針對 v0.15.0 的 prod-write-guard 回 pass。

🔴 跑之前清 `CLAUDE_CODE_CHILD_SESSION`;四支要帶參數
(三支帶 hook 絕對路徑、cross-repo 帶 hook 絕對路徑、gitea-arm-check 帶 repo 根目錄)
——不帶會紅,而那是假紅。
claude-code merged commit 7a3ce4e590 into main 2026-08-28 01:28:01 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: inkstone/ISEP#106