新增 frontmatter 解析檢查,改寫五支 CLI 的 hook 接線準則 #50

Merged
jiantw83 merged 4 commits from feat/cli-hook-rewire/frontmatter-lint-and-guidelines into feat/cli-hook-rewire/main 2026-09-01 00:56:11 +00:00
Member

摘要

  • 需求描述:對應 jsc-hooks 0.3.4 修正 codex、copilot、antigravity、kiro 四支 CLI 的 hook 接線。meta 負責規範文件與稽核工具兩塊:把「這些 CLI 沒有 pre-tool hook」這個錯誤結論從準則裡拔掉、改寫成五支 CLI 的接線位置與陷阱事實表,並新增 tools/lint-frontmatter.sh 補上第五種無聲失效的機檢。四支 CLI 原本都接錯位置,版本前置檢查與部署後重啟閘門因此長期完全失效,而且失效不報錯。版本號同步為 0.2.5。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
tools/lint-frontmatter.sh 新增。抓 6 支技能的 description 是未加引號的 YAML 純量、內容含「冒號加空白」,那在 YAML 是語法錯誤,Antigravity 會靜默丟棄整支技能,磁碟 34 支只認 28 支,沒有任何錯誤訊息。這是第五個同一類的無聲失效,唯一發現途徑是逐檔比對磁碟數量與載入數量,人工每次稽核都要重做一遍還會漏,所以交給程式。檢查五項:分隔線成對、必要鍵齊全、未加引號的純量不含「冒號加空白」也不以 YAML 特殊字元起頭、引號收得起來。不相依任何 YAML 套件,因為護欄不該綁在不保證存在的相依上。
references/guidelines.md 規範的正本。改「Hook 規則」第 3 條,寫明五支 CLI 負載形態各不相同、沒有基準格式;新增「技能名解析與阻擋輸出的共用腳本」節,把技能名取值與阻擋輸出收斂到 skill-name.sh 與 deny.sh 兩支,避免規則寫兩份、改一份、另一份安靜漂移;改寫「版本前置檢查」,補進五支 CLI 的接線位置表與逐支陷阱表,並要求未實測的部分據實標明;改寫「部署後重啟閘門」,兩道閘門共用同一套接線就共用同一份事實表;審核檢查清單新增一項 lint-frontmatter.sh 退出 0。
skills/skill-check/SKILL.md 稽核流程要真的跑得到新腳本。lint-frontmatter.sh 併進第一組稽核,與 lint-scripts.sh 平行跑,四個結束碼逐一路由,明寫退出 3 是「什麼都沒掃」、不算通過。第一組步驟重新編號;第二組 sub agent 要略過的既決項目由四項改五項;第一組完成條件、第 3 步合併說明、第 6 步重驗完成條件全部同步。description 也補上新腳本。
references/behaviors.md 行為清單是 check-behaviors.sh 的比對來源,流程改了就要跟著改。skill-check 的關鍵步驟、外部呼叫、完成條件、可驗證跡象四列補上 frontmatter 檢查,完成條件寫明退出 3 不算通過。
README.md 對外的技能與工具目錄。skill-check 段落的第一組稽核補上 lint-frontmatter.sh;「Tools 目錄」表新增一列,寫清楚五項檢查、三個結束碼與「退出 3 不等於通過」,並註明 frontmatter 壞掉時 Antigravity 靜默丟棄整支技能。
plugin.json 版本號 0.2.4 提升為 0.2.5。三份 manifest 版本號必須一致,否則版本前置檢查判定會不一致。
.claude-plugin/plugin.json 同上,claude 走這一份 manifest,版本號同步為 0.2.5。
.codex-plugin/plugin.json 同上,codex 走這一份 manifest,版本號同步為 0.2.5。

設計重點

  • 四個 hook 接線缺陷是同一種病:設定寫得看起來正確、CLI 靜默不理、不報任何錯。codex 的 matcher 用 Skill,但 Codex 沒有 Skill 工具,技能是模型用 Bash 讀 SKILL.md;codex 的 hooks 鍵寫成內嵌物件,實際規格是路徑字串;antigravity 的 PreToolUse 寫成 Flat,實際要 matcher 加 hooks 包一層的 Grouped;三支新接的命令沒帶 JSC_CLI={代號},閘門認不出自己跑在哪支 CLI 上,一次都擋不下來。copilot 原本指向 $COPILOT_HOME/hooks/,那是腳本目錄不是設定目錄,設定從來不會被讀。
  • 一道護欄回報「這裡沒有能力」時,要先確認那是查證過的事實、不是沒查。準則寫著「只有 claude 接得上」之後就沒有人再去查,兩道閘門因此在四支 CLI 上長期失效。所以這次把接線位置與陷阱寫成事實表放進準則,未實測的部分要求逐項標明驗證等級。
  • 兩道閘門共用同一套接線,就共用同一份事實表。「部署後重啟閘門」那節不再自寫一份能力描述,改指向「版本前置檢查」的接線位置表。寫兩份就會只改一份,另一份繼續錯著。
  • kiro 的 verdict 據實寫 degraded,不寫 wired 也不寫 failed。理由是 CLI 限制,不是接線問題:技能走 ResolveSkill 這個 agent 內部請求、由前端發起,preToolUse 攔不到技能叫用;userPromptSubmit 的非零結束碼也擋不下那一輪。只能把警告印到 stdout 供注入並退出 0。
  • 兩道版本檢查都只擋「確定落後」,查不到基礎資訊就安靜放行。只有 claude 讀得到 installed_plugins.json 那份本機載入版本,fail-closed 會把另外四支整批鎖死。這是版本讀得到讀不到的限制,跟能不能阻擋是兩件事。
  • lint-frontmatter.sh 不相依 YAML 套件。本機沒有 pyyaml,五項檢查只需要 YAML 1.2 的 plain scalar 規則,自己判定就夠,也才跑得到每一台機器上。單引號跳脫是重複一次、雙引號跳脫是反斜線,兩套規則不同,所以逐字掃而不用正規表示式一次比對兩種。

測試結果

  • meta 存取庫本身的機檢全綠:sh tools/lint-scripts.sh /root/plugins/meta 退出 0,13 支腳本過語法、可執行、結束碼宣告三項,新腳本的執行權限已帶上;sh tools/check-behaviors.sh /root/plugins/meta 退出 0,行為清單對上 7 支技能、五個欄位齊全;sh tools/ste100-lint.sh /root/plugins/meta 退出 0。
  • lint-frontmatter.sh 對十個 jsc domain 實跑,全部退出 0,共 34 支 SKILL.md:ask 1 支、cli 5 支、git 2 支、gitea 5 支、hooks 2 支、log 4 支、meta 7 支、pkg 1 支、review 3 支、sdlc 4 支。原本那 6 支「冒號加空白」的缺陷已在各自存取庫修掉,這支腳本確認修乾淨了。
  • lint-frontmatter.sh 的錯誤路徑也實跑:不帶參數退出 2(用法錯誤);對沒有 skills/ 的目錄退出 3 並印出原因,符合「什麼都沒掃、不等於通過」的設計。
  • 同一支腳本對工作目錄下非 jsc 的存取庫掃出 4 個真實缺陷,全是同一種「冒號加空白」。那四支不在本次 PR 範圍,僅列為腳本有效性的旁證。
  • 以下是對應 jsc-hooks 0.3.4 的接線驗證狀態,據實逐項標明等級,未驗證的不得混進已驗證的結論:
CLI 形狀 觸發
claude 實證 實證
codex 實證 未驗證
antigravity 實證(agy -p "/hooks" 確認四條全載入) 未驗證,對話 quota 用盡
copilot 未證(沒有唯讀列出管道) 未驗證
kiro 實證(agent validate 加三種反證) 部分實證:agentSpawn、userPromptSubmit 實跑觸發
  • kiro 的 verdict 是 degraded,理由是 CLI 限制不是接線問題:技能走 ResolveSkill 這個 agent 內部請求,preToolUse 攔不到技能叫用,userPromptSubmit 的非零結束碼也擋不下那一輪。
  • 尚未做的事,一併列明:write-guard.sh 三種模式與 SDLC 模型鎖在 codex、copilot、antigravity、kiro 四支非 claude CLI 上還沒接線;kiro 的 resources 兩層 glob 能不能修好技能可見性未驗證。

前置 Push Request

  • 無
## 摘要 - 需求描述:對應 jsc-hooks 0.3.4 修正 codex、copilot、antigravity、kiro 四支 CLI 的 hook 接線。meta 負責規範文件與稽核工具兩塊:把「這些 CLI 沒有 pre-tool hook」這個錯誤結論從準則裡拔掉、改寫成五支 CLI 的接線位置與陷阱事實表,並新增 `tools/lint-frontmatter.sh` 補上第五種無聲失效的機檢。四支 CLI 原本都接錯位置,版本前置檢查與部署後重啟閘門因此長期完全失效,而且失效不報錯。版本號同步為 0.2.5。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/lint-frontmatter.sh` | 新增。抓 6 支技能的 `description` 是未加引號的 YAML 純量、內容含「冒號加空白」,那在 YAML 是語法錯誤,Antigravity 會靜默丟棄整支技能,磁碟 34 支只認 28 支,沒有任何錯誤訊息。這是第五個同一類的無聲失效,唯一發現途徑是逐檔比對磁碟數量與載入數量,人工每次稽核都要重做一遍還會漏,所以交給程式。檢查五項:分隔線成對、必要鍵齊全、未加引號的純量不含「冒號加空白」也不以 YAML 特殊字元起頭、引號收得起來。不相依任何 YAML 套件,因為護欄不該綁在不保證存在的相依上。 | | `references/guidelines.md` | 規範的正本。改「Hook 規則」第 3 條,寫明五支 CLI 負載形態各不相同、沒有基準格式;新增「技能名解析與阻擋輸出的共用腳本」節,把技能名取值與阻擋輸出收斂到 `skill-name.sh` 與 `deny.sh` 兩支,避免規則寫兩份、改一份、另一份安靜漂移;改寫「版本前置檢查」,補進五支 CLI 的接線位置表與逐支陷阱表,並要求未實測的部分據實標明;改寫「部署後重啟閘門」,兩道閘門共用同一套接線就共用同一份事實表;審核檢查清單新增一項 `lint-frontmatter.sh` 退出 0。 | | `skills/skill-check/SKILL.md` | 稽核流程要真的跑得到新腳本。`lint-frontmatter.sh` 併進第一組稽核,與 `lint-scripts.sh` 平行跑,四個結束碼逐一路由,明寫退出 3 是「什麼都沒掃」、不算通過。第一組步驟重新編號;第二組 sub agent 要略過的既決項目由四項改五項;第一組完成條件、第 3 步合併說明、第 6 步重驗完成條件全部同步。`description` 也補上新腳本。 | | `references/behaviors.md` | 行為清單是 `check-behaviors.sh` 的比對來源,流程改了就要跟著改。skill-check 的關鍵步驟、外部呼叫、完成條件、可驗證跡象四列補上 frontmatter 檢查,完成條件寫明退出 3 不算通過。 | | `README.md` | 對外的技能與工具目錄。skill-check 段落的第一組稽核補上 `lint-frontmatter.sh`;「Tools 目錄」表新增一列,寫清楚五項檢查、三個結束碼與「退出 3 不等於通過」,並註明 frontmatter 壞掉時 Antigravity 靜默丟棄整支技能。 | | `plugin.json` | 版本號 0.2.4 提升為 0.2.5。三份 manifest 版本號必須一致,否則版本前置檢查判定會不一致。 | | `.claude-plugin/plugin.json` | 同上,claude 走這一份 manifest,版本號同步為 0.2.5。 | | `.codex-plugin/plugin.json` | 同上,codex 走這一份 manifest,版本號同步為 0.2.5。 | ## 設計重點 - 四個 hook 接線缺陷是同一種病:設定寫得看起來正確、CLI 靜默不理、不報任何錯。codex 的 matcher 用 `Skill`,但 Codex 沒有 `Skill` 工具,技能是模型用 Bash 讀 `SKILL.md`;codex 的 `hooks` 鍵寫成內嵌物件,實際規格是路徑字串;antigravity 的 `PreToolUse` 寫成 Flat,實際要 `matcher` 加 `hooks` 包一層的 Grouped;三支新接的命令沒帶 `JSC_CLI={代號}`,閘門認不出自己跑在哪支 CLI 上,一次都擋不下來。copilot 原本指向 `$COPILOT_HOME/hooks/`,那是腳本目錄不是設定目錄,設定從來不會被讀。 - 一道護欄回報「這裡沒有能力」時,要先確認那是查證過的事實、不是沒查。準則寫著「只有 claude 接得上」之後就沒有人再去查,兩道閘門因此在四支 CLI 上長期失效。所以這次把接線位置與陷阱寫成事實表放進準則,未實測的部分要求逐項標明驗證等級。 - 兩道閘門共用同一套接線,就共用同一份事實表。「部署後重啟閘門」那節不再自寫一份能力描述,改指向「版本前置檢查」的接線位置表。寫兩份就會只改一份,另一份繼續錯著。 - kiro 的 verdict 據實寫 `degraded`,不寫 `wired` 也不寫 `failed`。理由是 CLI 限制,不是接線問題:技能走 `ResolveSkill` 這個 agent 內部請求、由前端發起,`preToolUse` 攔不到技能叫用;`userPromptSubmit` 的非零結束碼也擋不下那一輪。只能把警告印到 stdout 供注入並退出 0。 - 兩道版本檢查都只擋「確定落後」,查不到基礎資訊就安靜放行。只有 claude 讀得到 `installed_plugins.json` 那份本機載入版本,fail-closed 會把另外四支整批鎖死。這是版本讀得到讀不到的限制,跟能不能阻擋是兩件事。 - `lint-frontmatter.sh` 不相依 YAML 套件。本機沒有 pyyaml,五項檢查只需要 YAML 1.2 的 plain scalar 規則,自己判定就夠,也才跑得到每一台機器上。單引號跳脫是重複一次、雙引號跳脫是反斜線,兩套規則不同,所以逐字掃而不用正規表示式一次比對兩種。 ## 測試結果 - meta 存取庫本身的機檢全綠:`sh tools/lint-scripts.sh /root/plugins/meta` 退出 0,13 支腳本過語法、可執行、結束碼宣告三項,新腳本的執行權限已帶上;`sh tools/check-behaviors.sh /root/plugins/meta` 退出 0,行為清單對上 7 支技能、五個欄位齊全;`sh tools/ste100-lint.sh /root/plugins/meta` 退出 0。 - `lint-frontmatter.sh` 對十個 jsc domain 實跑,全部退出 0,共 34 支 SKILL.md:ask 1 支、cli 5 支、git 2 支、gitea 5 支、hooks 2 支、log 4 支、meta 7 支、pkg 1 支、review 3 支、sdlc 4 支。原本那 6 支「冒號加空白」的缺陷已在各自存取庫修掉,這支腳本確認修乾淨了。 - `lint-frontmatter.sh` 的錯誤路徑也實跑:不帶參數退出 2(用法錯誤);對沒有 `skills/` 的目錄退出 3 並印出原因,符合「什麼都沒掃、不等於通過」的設計。 - 同一支腳本對工作目錄下非 jsc 的存取庫掃出 4 個真實缺陷,全是同一種「冒號加空白」。那四支不在本次 PR 範圍,僅列為腳本有效性的旁證。 - 以下是對應 jsc-hooks 0.3.4 的接線驗證狀態,據實逐項標明等級,未驗證的不得混進已驗證的結論: | CLI | 形狀 | 觸發 | | --- | --- | --- | | claude | 實證 | 實證 | | codex | 實證 | 未驗證 | | antigravity | 實證(`agy -p "/hooks"` 確認四條全載入) | 未驗證,對話 quota 用盡 | | copilot | 未證(沒有唯讀列出管道) | 未驗證 | | kiro | 實證(`agent validate` 加三種反證) | 部分實證:`agentSpawn`、`userPromptSubmit` 實跑觸發 | - kiro 的 verdict 是 `degraded`,理由是 CLI 限制不是接線問題:技能走 `ResolveSkill` 這個 agent 內部請求,`preToolUse` 攔不到技能叫用,`userPromptSubmit` 的非零結束碼也擋不下那一輪。 - 尚未做的事,一併列明:`write-guard.sh` 三種模式與 SDLC 模型鎖在 codex、copilot、antigravity、kiro 四支非 claude CLI 上還沒接線;kiro 的 `resources` 兩層 glob 能不能修好技能可見性未驗證。 ## 前置 Push Request - 無
jiantw83 added 4 commits 2026-08-31 11:14:08 +00:00
What:
- 新增 tools/lint-frontmatter.sh,掃一個 domain 每支 skills/*/SKILL.md 的 frontmatter,檢查分隔線成對、必要鍵齊全、未加引號的純量不含「冒號加空白」、起頭字元不是 YAML 特殊字元、加了引號的值收得起來,共五項。
- 改寫 skills/skill-check/SKILL.md 的第一組稽核,把這支腳本併進去成為第 2 步,原本的行為清單檢查、結束碼路由檢查、hook smoke 依序後移。
- 第二組留白的檢查清單項目由四項改成五項,第 3 步的合併說明、三組的完成條件、第 6 步的重驗完成條件同步改寫。

Why:
- 抓到 6 支技能的 description 是未加引號的 YAML 純量、內容含「冒號加空白」。那在 YAML 是鍵的分隔符號,整份 frontmatter 當場語法錯誤。
- Antigravity 讀到語法錯誤就靜默丟棄整支技能。磁碟上 34 支,它只認 28 支。載入器不報、CLI 不報,技能清單只是少了幾列。
- 這種缺陷唯一的發現途徑是逐檔比對磁碟數量與載入數量。人工比對 10 個 domain 每次稽核都要重做一遍,還會漏。輸入輸出固定的判定就交給程式。

How:
- 腳本用 awk 自己判定 YAML 1.2 的 plain scalar 規則,不相依 pyyaml。護欄不綁在一個不保證存在的相依上,才跑得到每一台機器。
- 單引號的跳脫是重複一次、雙引號的跳脫是反斜線,兩套規則不同,所以引號改用逐字掃描,不用正規表示式一次比對兩種。
- 結束碼分四種:0 是掃到 SKILL.md 且五項全過、1 是有不合格項目(清單走 stderr,格式 {檔案}:{鍵}:{說明})、2 是用法錯誤、3 是什麼都沒掃。
- SKILL.md 明寫退出 3 不算通過,並把「每個 domain 的 lint-frontmatter.sh 退出 0」列進第 6 步的完成條件。

Who:
屬 CLI hook 接線修正(jsc-hooks 0.3.4)在 meta 這一側的稽核工具。
What:
- 改寫「Hook 規則」第 3 條,寫明五支 CLI 的 hook 負載形態各不相同,沒有哪一支是基準格式。
- 新增「技能名解析與阻擋輸出的共用腳本」節,列出 skill-name.sh 與 deny.sh 的用法、各 CLI 的技能名取值來源、抽成共用腳本的理由。
- 改寫「版本前置檢查」,補上五支 CLI 的接線位置表、逐支陷阱表、未實測部分的標明規則。
- 改寫「部署後重啟閘門」,指名 restart-gate.sh,並寫明接線位置與版本前置檢查完全相同。
- 審核檢查清單新增一項:該 domain 的 lint-frontmatter.sh 要退出 0,退出 3 不算通過。

Why:
- 這一節以前寫著「只有 claude 接得上,其餘四支沒有 pre-tool hook」。那是錯的。四支全都有能阻擋的 pre-tool 事件,是我們接錯位置。
- 四個無聲失效逐一坐實了這件事:codex 的 matcher 用 Skill,但 Codex 沒有 Skill 工具,技能是模型用 Bash 讀 SKILL.md;codex 的 hooks 鍵寫成內嵌物件,實際規格是路徑字串;antigravity 的 PreToolUse 寫成 Flat,實際要 matcher 加 hooks 包一層的 Grouped;三支新接的命令沒帶 JSC_CLI={代號},閘門認不出自己跑在哪支 CLI 上,一次都擋不下來。
- 錯誤的結論被寫進準則之後就沒有人再去查。版本前置檢查與部署後重啟閘門因此在四支 CLI 上長期失效,而且失效是安靜的:hook 沒被觸發不會報錯,看起來就跟「沒有東西該擋」一樣。

How:
- 接線位置表每一列都經過執行檔抽出或本機實測,事件名、matcher、寫入檔案、阻擋方式逐欄寫死。
- verdict 據實分級:claude、codex、copilot、antigravity 寫 wired;kiro 的技能叫用走 ResolveSkill 內部請求、不走工具管線,攔不到,寫 degraded,不寫 failed。
- antigravity 與 kiro 的觸發沒有實跑驗證,另段標明,回報時不得混進已驗證的結論。
- 兩道閘門共用同一套接線,就共用同一份事實表。重啟閘門那節只指回接線位置表,不另寫一份能力描述,避免改一份、漏一份。

Who:
屬 CLI hook 接線修正(jsc-hooks 0.3.4)在 meta 這一側的規範文件。
What:
- README 的 skill-check 段落,第一組稽核補上 lint-frontmatter.sh。
- README 的工具表新增 tools/lint-frontmatter.sh 一列,寫明五項檢查、不相依 YAML 套件、四種結束碼、退出 3 不等於通過。
- references/behaviors.md 的 skill-check 表改寫四列:關鍵步驟、外部呼叫、完成條件、可驗證跡象。

Why:
- 準則要求該 domain 的 behaviors.md 與 skills/ 相符,check-behaviors.sh 才會退出 0;README 的「Skills 目錄」也要跟著改動同步。
- 文件沒跟上,稽核就查不到這支新腳本,也不知道退出 3 是什麼都沒掃。這支腳本擋的正是靜默失效,文件本身先靜默漏掉它,等於白做。

How:
- 照 skills/skill-check/SKILL.md 的新流程改寫,關鍵步驟寫明第一組平行跑腳本檢查、frontmatter 檢查、行為清單檢查與 hook smoke。
- 外部呼叫清單依實際呼叫順序插入 tools/lint-frontmatter.sh。
- 完成條件補上「frontmatter 檢查退出 3 是什麼都沒掃,不算通過」,可驗證跡象補上「每個 domain 的 lint-frontmatter.sh 退出 0」。
- 第二組留白項目由四項改五項,同步寫進關鍵步驟的合併說明。

Who:
屬 CLI hook 接線修正(jsc-hooks 0.3.4)在 meta 這一側的文件同步。
What:
- plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 的 version 由 0.2.4 提升到 0.2.5。

Why:
- 準則要求改動連帶提升三份 manifest 的 version,README 的「Skills 目錄」與 manifest 同步。
- 版本前置檢查靠 manifest 版本判定本機載入版本有沒有落後遠端發佈版本。版本號不動,這批新增的 frontmatter 檢查與改寫過的 hook 準則就發不出去,各機器也擋不到舊版。

How:
- 由主流程的 sync-skill-manifest.sh 同步三份,只動 version 欄,其餘欄位不變。
- 三份的 name 與 description 逐位元一致,避免各 CLI 讀到不同內容。

Who:
屬 CLI hook 接線修正(jsc-hooks 0.3.4)在 meta 這一側的發版收尾。
jiantw83 merged commit c4fdd8b2d8 into feat/cli-hook-rewire/main 2026-09-01 00:56:11 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/meta#50