Files
jiantw83andClaude Sonnet 5 2329e4d709 feat(spec-version-guard): 新增版本前置檢查規範、共用腳本與 hook
新增 spec-version-guard 規範(定義遠端發佈版本 vs 當前實際載入版本的比對規則、
fail-closed、錯誤訊息格式)與 scripts/version-guard.mjs(hook/CLI 雙模式,
hook 模式輸出 Claude Code/Copilot 相容的 PreToolUse deny JSON);spec-preflight
的載入順序補上版本檢查第 0 步;新增 hooks/hooks.json 掛 PreToolUse;
do-wiki/models/plan-wiki/plugins-uninstall/todo-wiki 五個 skill 檔頭引用新規範
(plugins-install 刻意排除,避免版本落後時擋住自己的修復手段)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 14:53:35 +08:00

82 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: spec-preflight
description: JSC plugins 共用「規範前置載入流程」:每個 skill 執行前先載入本規範自身、再依序載入自己需要的其他 /jsc-shared:spec-xxx;任一載入不到即代表 shared plugin 未安裝,用 AskUserQuestion 詢問是否安裝,使用者拒絕就中斷該 skill,絕不憑名稱或記憶臆測規範內容繼續執行。當其他 skill 內文引用 spec-preflight 或 /jsc-shared:spec-preflight、或執行任何需要先載入共用規範的 JSC skill 時載入此 skill。單獨被使用者呼叫時,直接說明本規範內容。
---
# spec-preflight — 共用規範前置載入流程
「shared plugin(`jsc-shared`)本身是所有共用規範的存放處,但『要先去載入 shared 的規範』這件事沒有地方可以事先講」——這是**雞生蛋問題**:其他 16+ 個 skill 都得依賴 shared 的 spec 才能正確執行,卻不能把「怎麼判斷 shared 有沒有裝」這段邏輯也放進 shared 裡,否則 shared 未安裝時連這段判斷邏輯都載入不到。本規範就是這個問題的**唯一解法本體**:其他 skill 只需在檔頭保留一段**最小**的本地文字(見〔被引用時的最小前置區塊〕),把完整流程都委派給本規範。
## 載入順序
每個 skill 執行前,依下列順序以 Skill 工具載入,**順序不可顛倒**:
0. **先依 `/jsc-shared:spec-version-guard` 執行版本檢查**:確認當前實際載入的 `jsc-shared`(以及該 skill 所屬 plugin 自己)版本沒有落後於 Gitea `master` 現行版本;不符即中斷本 skill,見〔「版本不符」與「shared 未安裝」是兩種不同中斷原因〕。這一步排在所有 spec 載入之前,避免用舊版規則做事。
1. **再載入本規範自身**:`/jsc-shared:spec-preflight`。這一步本身就是探測——載入成功代表 shared plugin 已安裝,可以繼續往下載入其他 spec;載入失敗直接進入〔載入失敗的處理〕。
2. **再依該 skill 自己列出的規範清單,逐一載入其他 `/jsc-shared:spec-xxx`**。清單與載入順序由各 skill 自己在檔頭決定(通常照該 skill 內文實際用到的先後順序排列),本規範不代為規定其他 spec 之間的順序。
## 「版本不符」與「shared 未安裝」是兩種不同中斷原因
第 0 步(版本檢查)與第 1 步(本規範是否載入得到)失敗時的原因完全不同,**中斷訊息不可混用**:
| 情境 | 代表什麼 | 中斷訊息依據 |
| --- | --- | --- |
| 第 0 步版本檢查不符或查不到遠端版本 | shared plugin **已安裝**,但版本落後於 Gitea `master`,或遠端查詢失敗(fail-closed) | 依 `/jsc-shared:spec-version-guard`〔錯誤訊息格式〕,導向 `/jsc-shared:plugins-install` 更新 |
| 第 1 步載入不到本規範自身 | shared plugin **根本未安裝** | 依本規範〔載入失敗的處理〕,導向安裝 `https://gitea.jsc.idv.tw/plugins/shared.git` |
不得把「版本落後」誤報成「未安裝」(使用者會照著安裝流程走卻發現早就裝了),也不得把「未安裝」誤報成「版本落後」(使用者會照著更新指令走卻發現裝不了,因為根本沒有 marketplace)。
## 載入失敗的處理
只要**任一** spec(包含本規範自身)載入不到,一律判定為**shared plugin(`jsc-shared`)未安裝**,不視為暫時性錯誤、不重試、不略過繼續:
1. 用 **AskUserQuestion** 詢問使用者是否要安裝 shared plugin,安裝目標固定是:
```
https://gitea.jsc.idv.tw/plugins/shared.git
```
安裝步驟可參考 `/jsc-shared:plugins-install` 的安裝方式(若該 skill 當下也載入不到,代表連它都不存在,此時直接依一般 plugin 安裝方式引導使用者:把上述 repo 加入對應助理的 plugin marketplace 並安裝 `jsc-shared`)。
2. 使用者同意安裝 → 完成安裝後,**從〔載入順序〕第 1 步重新開始**逐一載入,全部成功才繼續執行原 skill 剩餘步驟。
3. 使用者拒絕安裝 → 依〔使用者拒絕時的中斷規則〕處理。
## 使用者拒絕時的中斷規則
**使用者不安裝則直接中斷本 skill**:
- 立刻停止呼叫本規範的那個 skill,不得繼續執行任何後續步驟(包含它原本排在前面、看似與缺失的 spec 無關的步驟)。
- 不得因為「這個 skill 大部分邏輯不依賴那份 spec」而自行判斷可以跳過繼續做。
- 只需回報「因缺少共用規範 `spec-xxx` 且使用者未安裝 shared plugin,本次 `<skill 名稱>` 已中斷」,不需要也不應該杜撰替代做法。
## 禁令(不可違反)
**絕不允許在 spec 載入失敗的情況下,僅憑該 spec 名稱字面意思或以往記憶臆測其內容繼續執行;規範內容以實際載入到的 spec 檔案為準。**
- 即使助理「記得」某個 `spec-xxx` 通常講什麼(例如過去對話中讀過),只要**這次呼叫**沒有成功載入,就必須視為「內容未知」,不可用記憶內容替代。
- skill 描述(`description`)裡對某個 spec 的一行摘要只是索引用途,**不是規範本文**,載入失敗時不得只憑那一行摘要繼續執行。
- 這條禁令沒有例外,即使使用者在對話中催促「先照你知道的做」也不成立——中斷並如實說明原因,交由使用者裁示。
## 被引用時的最小前置區塊(給其他 skill 抄的範本)
其他 skill 檔案在檔頭只需保留下列**最小**文字,不可展開重抄本規範全文,也不可省略「載入不到即中斷」這句:
```markdown
## 共用規範(必要前置)
先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝,
依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。
preflight 的第一件事是依 `/jsc-shared:spec-version-guard` 比對遠端與當前實際載入版本,不符即中斷本 skill。
本 skill 需要的規範:`spec-version-guard`、`spec-output`、`spec-execution`、`spec-gitea`、…(依各 skill 實際需要的規範清單列出)
```
- 最後一行的規範清單**只列名稱**,不附一行摘要(摘要是規範內容的重抄,會與本文漂移不一致;需要摘要時直接載入該 spec 看本文)。
- 清單順序建議照該 skill 內文實際用到的先後排列,方便對照;`spec-version-guard` 因為是最前置的檢查,習慣上放在清單最前面。
## 適用範圍
| 情境 | 是否適用本規範 |
| --- | --- |
| 任何會在檔頭載入一個或多個 `/jsc-shared:spec-xxx` 的 skill | 適用,且必須放在所有其他規範載入之前 |
| skill 本身就是某個 `spec-xxx`(例如 `spec-gitea`、`spec-dockerfile`) | 不適用;規範檔本身不需要也不應該引用本規範,避免循環依賴 |
| 使用者直接呼叫 `/jsc-shared:spec-preflight` 詢問內容 | 不適用「執行前載入」的情境,直接依本檔內容回答即可 |