feat(git-safety,model): 分支一律先確認、模型 id 改以 transcript 實際值為準 #13

Closed
jiantw83 wants to merge 9 commits from feat/branch-confirmation-and-model-source into develop
6 changed files with 64 additions and 13 deletions
Showing only changes of commit fcea8ee48c - Show all commits
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-shared",
"version": "0.2.2",
"version": "0.2.3",
"description": "JSC 跨 AI 助理共用規範 skills plugin(Claude Code / Codex / Antigravity / OpenCode / GitHub Copilot CLI),`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-code/jsc-doc/jsc-persona/jsc-shared,plugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準;於 Claude Code 以 /jsc-shared: 前綴呼叫。",
"skills": "./skills",
"author": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-shared",
"version": "0.2.2",
"version": "0.2.3",
"description": "JSC 跨 AI 助理共用規範 skills plugin,`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-code/jsc-doc/jsc-persona/jsc-shared,plugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準。",
"skills": "./skills"
}
+2 -2
View File
@@ -141,8 +141,8 @@ shared/
| --- | --- | --- |
| `models` | 查詢目前可用哪些模型並依 `spec-model` 的標籤體系標註,維護 `~/.claude/jsc/models.json` 快取,依任務類型推薦模型或檢查當前模型是否符合指定模型。是 `spec-model` 的唯一可執行入口——其他 skill 需要模型清單或推薦時一律呼叫本 skill,不自行重寫探測或推薦邏輯 | `/jsc-shared:models`;可帶 `--refresh`(重跑探測與 smoke test)、`--task <analysis\|implement\|review\|summary\|persona>`(依對映表推薦模型)、`--check <model>`(比對指定模型與當前模型)、`--json` |
| `plan-wiki` | 逐步詢問使用者計畫內容,並把每一輪已確認的計畫草稿直接同步到指定 Gitea wiki 的目錄頁與計畫頁;目錄頁為四欄表格,計畫列的「已產生」欄初始為 `[ ]`,待 `todo-wiki` 依該計畫產生 TODO 頁後才改為 `[x]`;全程不建立本機計畫檔、草稿檔、暫存 JSON body 或 wiki clone | `/jsc-shared:plan-wiki`;可帶 `--wiki-repo <owner/repo>`、`--index <目錄頁title>`、`--project <計畫名稱>`、`--page <計畫頁title>`、`--host <gitea主機>`、`--yes` |
| `todo-wiki` | 把「需求 → 分析 → 產生鎖定模型的 TODO 清單 → 同步到 Gitea wiki 目錄與頁面」固定成不落地檔案的流程;開工前先從目錄頁挑一個尚未產生代辦的計畫(可不選),目錄頁的 TODO 列「已完成」欄初始為 `[ ]`,待 `do-wiki` 執行完該 TODO 頁全部項目後才改為 `[x]`;不產生本機 `todo.md`,只寫入指定 wiki 目錄頁與 todo 頁 | `/jsc-shared:todo-wiki`;可帶 `--source <需求描述\|檔案路徑\|議題編號>`、`--impl-model <id\|alias>`、`--wiki-repo <owner/repo>`、`--wiki-index <目錄頁title>`、`--wiki-project <計畫名稱>`、`--wiki-page <todo頁title>`、`--append\|--overwrite`、`--yes` |
| `do-wiki` | 讀取 `todo-wiki` 產生、帶鎖定模型 frontmatter 的 Gitea wiki TODO 頁並逐項執行;開工前先從目錄頁挑一份未完成的代辦,沒有就直接結束;比對當前模型與頁面 `model` 不符就停止;每完成一項就地勾選並立即回寫該 wiki 頁、讀回確認成功才繼續下一項;全部完成後回目錄頁把該代辦列「已完成」改為 `[x]` | `/jsc-shared:do-wiki`;可帶 `--wiki-repo <owner/repo>`、`--wiki-page <todo頁title>`、`--yes` |
| `todo-wiki` | 把「需求 → 分析 → 產生鎖定模型的 TODO 清單 → 同步到 Gitea wiki 目錄與頁面」固定成不落地檔案的流程;開工前先從目錄頁挑一個尚未產生代辦的計畫(可不選),目錄頁的 TODO 列「已完成」欄初始為 `○`,待 `do-wiki` 執行完該 TODO 頁全部項目後才改為 `●`;checklist 依專案或相依性分組、組內編號自 1 起算、frontmatter 帶 `max_parallel` 標明最多可平行處理的群組數;不產生本機 `todo.md`,只寫入指定 wiki 目錄頁與 todo 頁 | `/jsc-shared:todo-wiki`;可帶 `--source <需求描述\|檔案路徑\|議題編號>`、`--impl-model <id\|alias>`、`--wiki-repo <owner/repo>`、`--wiki-index <目錄頁title>`、`--wiki-project <計畫名稱>`、`--wiki-page <todo頁title>`、`--append\|--overwrite`、`--yes` |
| `do-wiki` | 讀取 `todo-wiki` 產生、帶鎖定模型 frontmatter 的 Gitea wiki TODO 頁並逐項執行;開工前先產生唯一工作證,再從目錄頁挑一份未完成的代辦,沒有就直接結束;比對當前模型與頁面 `model` 不符就停止;改以群組為單位領取——找出未被工作證標註且未完成的群組標註後才在組內逐項執行,全被標註時列出各群組最後更新時間詢問是否取代;每完成一項就地勾選並立即回寫該 wiki 頁、讀回確認成功才繼續下一項;群組完成與 session 停止時釋放工作證;全部完成後回目錄頁把該代辦列「已完成」由 `○` 改為 `●` | `/jsc-shared:do-wiki`;可帶 `--wiki-repo <owner/repo>`、`--wiki-page <todo頁title>`、`--yes` |
### 整組 plugin 安裝管理
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-shared",
"version": "0.2.2",
"version": "0.2.3",
"description": "JSC 跨 AI 助理共用規範 skills plugin,`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-code/jsc-doc/jsc-persona/jsc-shared,plugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準;於 Antigravity 以 /jsc-shared: 前綴呼叫。",
"skills": "./skills"
}
+43 -5
View File
@@ -1,6 +1,6 @@
---
name: do-wiki
description: 讀取 `todo-wiki` 產生、帶鎖定模型 frontmatter 的 Gitea wiki TODO 頁並逐項執行:開工前先讀目錄頁挑一份「已完成」為未勾選的代辦(沒有就直接結束);檢查頁面 `## 0.` 的六條強制規則並比對當前模型,不符就停止;讀取需求彙整與既有 checklist(已勾選視為完成不重做);逐項執行——完成一項就地把 `- [ ]` 改 `- [x]` 並補上完成時間,立即回寫該 wiki 頁並讀回確認成功才能繼續下一項,任一步失敗立刻停止;全部項目完成後回目錄頁把該代辦列「已完成」改為 `●`。當使用者說要執行 wiki TODO、跑 do-wiki、依 wiki 清單實作、接手某份 Gitea wiki 代辦、或提到 do-wiki skill 時觸發。不適用於:把需求分析並產生 TODO 清單同步到 wiki(用 `/jsc-shared:todo-wiki`)、逐步建立計畫並同步 wiki(用 `/jsc-shared:plan-wiki`)。
description: 讀取 `todo-wiki` 產生、帶鎖定模型 frontmatter 的 Gitea wiki TODO 頁並逐項執行:開工前先產生唯一工作證並讀目錄頁挑一份「已完成」為未勾選的代辦(沒有就直接結束);檢查頁面 `## 0.` 的六條強制規則並比對當前模型,不符就停止;讀取需求彙整與既有 checklist(已勾選視為完成不重做);接著領取一個未被工作證標註且未完成的群組(全被標註時列出各群組最後更新時間詢問是否取代),標註成功才在該群組內逐項執行——完成一項就地把 `- [ ]` 改 `- [x]` 並補上完成時間,立即回寫該 wiki 頁並讀回確認成功才能繼續下一項,任一步失敗立刻停止;群組完成與 session 停止時釋放工作證;全部項目完成後回目錄頁把該代辦列「已完成」改為 `●`。當使用者說要執行 wiki TODO、跑 do-wiki、依 wiki 清單實作、接手某份 Gitea wiki 代辦、或提到 do-wiki skill 時觸發。不適用於:把需求分析並產生 TODO 清單同步到 wiki(用 `/jsc-shared:todo-wiki`)、逐步建立計畫並同步 wiki(用 `/jsc-shared:plan-wiki`)。
argument-hint: "[--wiki-repo <owner/repo>] [--wiki-index CONTENTS] [--wiki-page <既有 TODO 頁 title>] [--yes]"
---
@@ -10,11 +10,13 @@ argument-hint: "[--wiki-repo <owner/repo>] [--wiki-index CONTENTS] [--wiki-page
| 階段 | 做什麼 | 產出 |
| --- | --- | --- |
| -1. 產生工作證 | 產生本次唯一工作證 | `WP_{yyyyMMdd}_{HHmmss}_{6 碼}` |
| 0. 挑代辦 | 讀目錄頁列出所有未完成的 TODO 列,單選一份 | 本次執行目標的 TODO 頁 `path` |
| 1. 讀取目標 TODO 頁 | 查表取得 `path` 並讀取內容 | TODO 頁完整 Markdown |
| 2. 檢查強制規則 | 解析 `## 0.` 區塊六條規則,比對當前模型 | 相符才繼續,不符則停止 |
| 3. 了解需求彙整 | 讀 frontmatter `scope` 與需求段落,盤點既有 checklist | 待執行項目清單 |
| 4. 逐項執行並即時回寫 | 單項循環:執行 → 勾選 → 回寫 → 讀回確認 | 全部項目完成的 TODO 頁 |
| 3.5 領取群組 | 找未被標註且未完成的群組,標上工作證並回寫 | 已領取的群組 |
| 4. 逐項執行並即時回寫 | **在已領取群組內**逐項執行並即時回寫 | 全部項目完成的 TODO 頁 |
| 收尾 | 回目錄頁把該代辦列「已完成」改 `●` | 讀回確認成功的目錄頁 |
## 共用規範(必要前置)
@@ -32,7 +34,17 @@ argument-hint: "[--wiki-repo <owner/repo>] [--wiki-index CONTENTS] [--wiki-page
| `--wiki-repo` | 指定要讀取的 Gitea wiki repo,例如 `knowledges/Plan`。未帶時依 `spec-ask-user` 詢問,不臆測。 |
| `--wiki-index` | 目錄頁 title;未帶時固定使用 `CONTENTS`,不詢問。 |
| `--wiki-page` | 直接指定既有 TODO 頁 title;有帶時跳過階段 0 的挑選詢問,直接查表取得對應 `path` 進入階段 1。 |
| `--yes` | 略過一般性確認;不得略過模型不符、目標 wiki 不明、或 wiki 回寫/讀回失敗後的停止。 |
| `--yes` | 略過一般性確認;不得略過模型不符、目標 wiki 不明、工作證取代確認、或 wiki 回寫/讀回失敗後的停止。 |
## 階段 -1:產生工作證
在**接觸任何 wiki 內容之前**,先產生本次唯一工作證,格式固定 `WP_{yyyyMMdd}_{HHmmss}_{6 碼大寫英數隨機}`(時間為 Asia/Taipei,依 `/jsc-shared:spec-time-log`),並依同 spec 輸出一行:
```
[yyyy/MM/dd HH:mm:ss][工作證][INF]: 本次工作證 WP_20260819_100000_A1B2C3
```
工作證在本次 session 全程固定不變。
## 階段 0:從目錄頁挑一份未完成代辦
@@ -65,18 +77,44 @@ argument-hint: "[--wiki-repo <owner/repo>] [--wiki-index CONTENTS] [--wiki-page
- **do-wiki 執行期的中間成果不得落地**:進度摘要、待辦排序、分析過程只留在對話內容,不得寫成本機草稿檔、暫存 JSON、或任何用來傳遞中間成果的檔案;不得 clone wiki repo;request body 一律由工具呼叫或記憶內容直接送出,不得用 `@file` 形式。
- **清單項目本身要求新增或修改的專案原始碼屬正常產出**:若某個 checklist 項目的實作方式就是「新增/修改某個檔案」,直接依該項目要求編輯專案內的原始碼、文件或設定檔,這不算落地限制的例外,是該項目的正常交付物。
## 階段 3.5:領取群組
1. 掃描 TODO 頁所有 `## 群組 …` 標題,解析群組代號、工作證欄、相依標註。
2. 取出「工作證為 `無`、組內仍有 `- [ ]`、且相依群組皆已全數完成」的可領取群組。
3. 候選多於一組時依 `/jsc-shared:spec-ask-user` 以單選呈現(候選 ≤4 用 `AskUserQuestion` 並含「其他」,>4 改文字編號列出)。
4. 把該群組標題行改寫為 `(工作證:{本次工作證}|領取:{yyyy/MM/dd HH:mm:ss})`,**立即回寫 wiki 並讀回解碼比對成功**才可進入階段 4;失敗立刻停止。
### 全數被標註時的取代流程
當「沒有任何可領取群組、但仍有未完成群組」時,**不設固定逾時門檻**,改為列出所有已被標註群組的表格(欄位:群組代號、工作證、領取時間、該群組最後更新時間、未完成項數),依 `/jsc-shared:spec-ask-user` 詢問使用者是否要取代其中一組的工作證改由本次工作證接手;使用者選擇不取代時,輸出:
```
[yyyy/MM/dd HH:mm:ss][工作證][INF]: 所有群組皆已被領取且使用者未指定取代,本次不進行任何修改。
```
後結束。取代屬破壞性決策,**`--yes` 不得略過**本次詢問。
## 階段 4:逐項執行並即時回寫
依序處理階段 3 篩選出的每一個未勾選項目,單項循環固定四步,**任一步失敗立刻停止,不得執行下一項;不得多項一起補勾**:
依序處理**階段 3.5 已領取群組內**的每一個未勾選項目,單項循環固定四步,**任一步失敗立刻停止,不得執行下一項;不得多項一起補勾**:
1. **執行**:依該項目的實作方式與驗收條件完成工作(可能是編輯專案檔案、可能是純分析)。
2. **就地勾選**:把該行 `- [ ]` 改成 `- [x]`,並在行末附上「(完成:`yyyy/MM/dd HH:mm:ss`)」(Asia/Taipei)。
3. **回寫 wiki**:以 `tea wiki edit`(或 `PATCH /repos/<owner>/<repo>/wiki/page/<path>`)寫回整份頁面內容。**`tea wiki edit` 陷阱**:其用法為 `tea wiki edit [options] <page>`,`<page>` 需帶 `path`;若省略 `--title`,tea 會把 `<page>` 當成新 title 送出並導致頁面被改名。**每次呼叫都必須同時帶 `--title`(原 title)與 `--content`(完整內容)**,否則勾選一次就改名一次。
4. **讀回確認**:重新讀取該頁,確認內容已更新且與預期一致(`content_base64` 需先 base64 解碼再比對);若回寫或讀回確認失敗,立刻停止,不得繼續下一項。
該群組項目全數 `- [x]` 後,先執行群組釋放(見下節),再回到階段 3.5 領取下一組。
## 釋放工作證
兩個釋放時機:
- **群組完成即釋放**:該群組全數 `- [x]` 時,把標題行改回 `(工作證:無)`,回寫並讀回確認。
- **session 停止即釋放**:本次流程正常結束、使用者中止、或因錯誤停止而準備收工前,把仍掛著本次工作證的所有群組一律改回 `(工作證:無)` 並回寫讀回確認,避免留下無人接手的殘留標註。
## 收尾:全部完成後回寫目錄頁「已完成」
1. 只有本次 TODO 頁**所有**項目皆為 `- [x]` 時才可進行;只要還有未勾項目就不得勾選目錄頁。
1. 只有**所有群組**的所有項目皆為 `- [x]`,**且本次工作證已全部釋放**時才可進行;只要還有未勾項目或未釋放的工作證就不得勾選目錄頁。
2. 依 `spec-wiki-contents`〔回寫規則〕,回目錄頁把該 TODO 列的「已完成」由 `○` 改為 `●`。
3. 讀回目錄頁確認寫入成功;失敗則停止並回報,不得視為已完成。
+16 -3
View File
@@ -1,6 +1,6 @@
---
name: todo-wiki
description: 把「需求 → 分析 → 產生鎖定模型的 TODO 清單 → 同步到 Gitea wiki 目錄與頁面」固定成不落地檔案的流程:先依 `/jsc-shared:spec-model` 的「需求分析」任務挑出分析模型,當前模型不符就停止;接著讀取來源(需求描述、本機檔案,或走 `/jsc-shared:spec-issue-read` 讀取的 Gitea 議題)並釐清需求,任何不清楚之處依 `/jsc-shared:spec-ask-user` 詢問;再依「依清單實作」任務挑出實作模型或採用使用者指定;最後把帶 `model`/`model_alias`/`model_reason`/`analyzed_by`/`analyzed_at`/`scope` frontmatter、強制規則區塊,以及具備實作方式/驗收條件/來源依據/必要時建議修改內容的 TODO 內容直接同步到指定 Gitea wiki 目錄頁與 todo 頁。當使用者說要把需求整理成 wiki TODO、同步 todo 到 Gitea wiki、需求轉 todo-wiki、指定模型 todo wiki、或提到 todo-wiki skill 時觸發。不適用於:產生本機 todo.md、把需求拆分成多個 Gitea 議題(用 `/jsc-doc:issues-analyze`)、實作既有 Gitea 議題的 TODO(用 `/jsc-code:issues`)。
description: 把「需求 → 分析 → 產生鎖定模型的 TODO 清單 → 同步到 Gitea wiki 目錄與頁面」固定成不落地檔案的流程:先依 `/jsc-shared:spec-model` 的「需求分析」任務挑出分析模型,當前模型不符就停止;接著讀取來源(需求描述、本機檔案,或走 `/jsc-shared:spec-issue-read` 讀取的 Gitea 議題)並釐清需求,任何不清楚之處依 `/jsc-shared:spec-ask-user` 詢問;再依「依清單實作」任務挑出實作模型或採用使用者指定;最後把帶 `model`/`model_alias`/`model_reason`/`analyzed_by`/`analyzed_at`/`scope`/`max_parallel` frontmatter、強制規則區塊,以及具備實作方式/驗收條件/來源依據/必要時建議修改內容的 TODO 內容直接同步到指定 Gitea wiki 目錄頁與 todo 頁;checklist 依專案或相依性分組、組內編號自 1 起算、frontmatter 併帶 `max_parallel` 標明最多可平行處理的群組數。當使用者說要把需求整理成 wiki TODO、同步 todo 到 Gitea wiki、需求轉 todo-wiki、指定模型 todo wiki、或提到 todo-wiki skill 時觸發。不適用於:產生本機 todo.md、把需求拆分成多個 Gitea 議題(用 `/jsc-doc:issues-analyze`)、實作既有 Gitea 議題的 TODO(用 `/jsc-code:issues`)。
argument-hint: "[--source <需求描述|檔案路徑|議題編號>] [--impl-model <id|alias>] [--wiki-repo <owner/repo>] [--wiki-index <英文系統名稱>_<中文系統名稱>] [--wiki-project <英文系統名稱>_<中文系統名稱>] [--wiki-page <既有頁 title|TODO_<yyyyMMdd>_<HASH>>] [--append|--overwrite] [--yes]"
---
@@ -118,9 +118,12 @@ model_reason: <階段 3 產出的理由>
analyzed_by: <階段 1 確認的分析模型 id>
analyzed_at: <yyyy/MM/dd HH:mm:ss,Asia/Taipei>
scope: <階段 2 產出的 scope>
max_parallel: <X,可同時開工的群組數上限>
---
```
**`X` 的計算**:X = 彼此沒有前後相依、可同時開工的群組數上限;相依鏈上的後續群組不重複計入(例:A、B 無相依、C 相依 A 與 B → X = 2)。
### 強制規則區塊
固定加入:
@@ -143,9 +146,17 @@ scope: <階段 2 產出的 scope>
### checklist
- **先分組再列項**:checklist 必須依**專案或相依性**分組,每個群組一個 H2 標題,**每組編號從 1 開始**、不跨群組連號,標題格式:
```markdown
## 群組 {代號}:{群組名稱}(工作證:{工作證編號}|領取:{yyyy/MM/dd HH:mm:ss})
```
尚未被領取時固定寫成 `(工作證:無)`,**不保留**「|領取:」欄位。
- **群組相依標示**:群組若有前置相依,於群組名稱後加註 `(相依:{前置群組代號})`,例如 `## 群組 C:文件與版號同步(相依:A、B)(工作證:無)`;**未標註相依即視為無相依,可立即開工**。此標註是 `max_parallel` 的計算依據,也是 `do-wiki` 判斷群組可否開工的依據。
- 逐項使用 `- [ ] **編號 短標題**:具體內容`。
- 內容需動詞+對象+實作方式+驗收條件+來源依據齊備,並能舉證對應 `path:line` 或需求彙整中的哪一句;文件或程式修改時,必要時附上 `建議修改內容`。
- 依影響範圍由小到大排序;範圍相同時前置依賴排前面。
- 排序分兩層:**群組之間**依相依關係排序(無相依者在前,有相依的群組排在其所有前置群組之後);**群組之內**依影響範圍由小到大排序,範圍相同時前置依賴排前面。
- 不得加入需求來源未提及、也無法合理推得的項目;有疑慮者標「需人工確認」。
## 階段 5:讀取既有 wiki 頁並決定寫入策略
@@ -160,7 +171,7 @@ scope: <階段 2 產出的 scope>
| 狀況 | 動作 |
| --- | --- |
| 頁面不存在 | 建立新 todo 頁。 |
| 頁面存在且 frontmatter `model` 相同 | 附加到頁面最後:加 `---` 分隔與 `## 追加(<yyyy/MM/dd HH:mm:ss>)` 標題,接新的 checklist 項目;frontmatter 只更新 `analyzed_at`。 |
| 頁面存在且 frontmatter `model` 相同 | 附加到頁面最後:加 `---` 分隔與 `## 追加(<yyyy/MM/dd HH:mm:ss>)` 標題,接新的 checklist 項目;**追加內容同樣要自成群組**(群組代號延續既有代號往後編、組內編號從 1 起算),並**重算 `max_parallel` 寫回 frontmatter**;frontmatter 更新 `analyzed_at` 與 `max_parallel` 兩欄。 |
| 頁面存在且 frontmatter `model` 不同 | 停下來詢問使用者是否覆蓋、沿用舊模型附加、或取消;未得同意不得寫入。 |
| 頁面存在但沒有 frontmatter | 視為不同模型處理。 |
@@ -202,6 +213,8 @@ API 寫入方式:
| 分析模型 | `analyzed_by` |
| 實作模型 | `model` / `model_alias`,並註明推薦或使用者指定 |
| 已完成項目數 | 本次實際完成且已回寫確認的 checklist 項目數 |
| 群組數 | 本次產生的群組數與各群組代號 |
| 最多平行處理數 | frontmatter 的 `max_parallel`,並註明計算依據 |
| Wiki repo | `<owner/repo>` |
| 目錄頁 | URL;若使用者明確不要更新目錄頁,填「未更新(使用者選擇不更新目錄頁)」 |
| Todo 頁 | URL |