Files
meta/references/wp01-baseline-decisions.md
T
jiantw83 b8b5737bc3 docs(wp01-baseline): 新增定案規格與待辦校正兩份參考文件
What:新增兩份文件。wp01-baseline-decisions.md 收錄十項技術定案(雜湊分隔符、計畫名稱正規化、跨存取庫工作包編號起算、PLAN_CONTENTS 存取庫欄格式、工作日誌週次雜湊、舊日誌拆頁、輸出原則 lint 化範圍、CPM 圖涵蓋範圍、不監看時的相依判定、PR 疊包上限),並補上五個未註冊存取庫(code、doc、persona、shared、code-review)去向決議:全部不納入 marketplace 正本,維持獨立系統。wp01-todo-corrections.md 收錄 TODO.md 十五項狀態過期校正與五項數字更新。

Why:分析階段裁定的規格內容原本只寫在分析頁全文裡,後續工作包每次要引用都得回頭翻找。整理成獨立文件,附出處與具體例子,工作包可以直接引用,不必重新確認脈絡。另外,TODO.md 本身不在任何 git 存取庫底下,沒有分支也沒有 PR 可走,校正意見沒有地方能落地,只能整理成清單交使用者手動核對。

How:定案文件逐項附出處(對應分析頁或測試計畫段落)與可驗證的具體例子,方便日後照抄核對。待辦校正文件依「狀態過期」與「數字更新」分兩節整理,開頭寫明無法走 PR 的原因,並註明資料來源是同一輪盤點、以各存取庫 origin/develop 為準逐一核對得出。

Who:WP-01 定案規格交付包。
2026-09-08 09:08:36 +08:00

189 lines
17 KiB
Markdown
Raw 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.
# 十項定案規格
這份文件收錄分析頁裡十項技術裁定的定案內容,每項附出處與具體例子,供後續工作包直接引用,不必回頭翻找分析頁全文。
## N-01:雜湊輸入分隔符
**裁決**:多個欄位(例如計畫名稱與存取庫路徑)要接成一個雜湊輸入字串時,固定用直線號 `|` 當分隔符。組法收在 `hash-id` 的 `key` 子命令這個單一入口,各技能不再自己接字串。
**出處**:「工作分解結構(WBS)」層1 共用腳本表格,工作包名稱「hash-id 加 key 子命令:分隔符 `|`、四道正規化、組法收單一入口」;測試計畫「雜湊組法收單一入口」小節第一個 TDD 循環,斷言 `hash-id key "我的計畫" "plugins/sdlc"` 與 `hash-id "我的計畫|plugins/sdlc"` 輸出同一個 40 碼雜湊。
**例外**:本份分析頁自己的雜湊輸入不吃 `{owner}/{repo}`,只用計畫名稱,理由是這一輪盤點橫跨 11 個存取庫,綁任一個存取庫都是錯的。這是單一頁面的特例,不是分隔符定案本身跟著變。
**例子**:
```
hash-id key "我的計畫" "plugins/sdlc"
# 與下面這行輸出同一個 40 碼大寫 SHA-1
hash-id "我的計畫|plugins/sdlc"
```
## N-02:計畫名稱正規化規則
**裁決**:計畫名稱進雜湊前,固定套四道正規化,依序是:
1. Unicode NFC 正規化
2. 去除頭尾空白
3. 內部連續空白壓成一個半形空白
4. 英數字元全形轉半形
大小寫不在正規化範圍內,維持原樣、視為不同名稱。
**出處**:測試計畫「雜湊組法收單一入口」小節第二個 TDD 循環,斷言「我的 計畫」「我的 計畫」「我的計畫 」三種輸入正規化後相同,而「ABC 計畫」與「abc 計畫」不同;最小實作寫明四道正規化內容。
**例子**:
- `我的 計畫`、`我的 計畫`(全形空白)、`我的 計畫`(兩個半形空白)→ 正規化後同一個結果,雜湊相同,第二次建立同名計畫會被擋下
- `ABC 計畫` 與 `abc 計畫` → 正規化後仍不同,雜湊不同,兩者當成不同計畫
可直接貼進測試檔的指令:
```
hash-id key "我的 計畫" "plugins/sdlc"
hash-id key "我的 計畫" "plugins/sdlc"
hash-id key "我的 計畫" "plugins/sdlc"
# 三行輸出同一個 40 碼雜湊
hash-id key "ABC 計畫" "plugins/sdlc"
hash-id key "abc 計畫" "plugins/sdlc"
# 兩行輸出不同雜湊,這是反例,證明大小寫不會被正規化抹掉
```
## N-05:跨存取庫工作包編號起算
**裁決**:每一份分析頁的工作包編號各自從 `WP-01` 起算,不跨頁連號。因此鎖定工作包不能只看編號,要在前面加上該分析頁自己的雜湊當複合鍵,兩份不同分析頁裡同編號的工作包才不會互搶同一把鎖。
**出處**:「工作分解結構(WBS)」層2 技能行為表格,處理 analyze 頁名與跨庫的工作包名稱寫明「各頁 WP-01 起算」;對應 TDD 小節斷言兩份不同分析頁各自的「雜湊組法收單一入口」下游工作包不互相搶鎖,最小實作是把鎖鍵改成「`{分析頁雜湊}#WP-NN`」複合鍵。
**例子**:分析頁 A 與分析頁 B 各有自己的第二個工作包。鎖鍵分別是 `{分析頁A雜湊}#WP-02` 與 `{分析頁B雜湊}#WP-02`,領取其中一個不影響另一個,兩邊各自從 1 起算。
## N-07:`PLAN_CONTENTS` 存取庫欄格式
**裁決**:`PLAN_CONTENTS` 目錄頁的存取庫欄改成清單,同一行、多個值用頓號分隔,不拆成多行子條列。
**出處**:「工作分解結構(WBS)」層2 技能行為表格,工作包名稱「`PLAN_CONTENTS` 存取庫欄改清單,同行頓號分隔」;對應 TDD 小節斷言那一行 upsert 後讀得回多個值,最小實作是改範本並在寫入時以頓號串接。
**例子**:
```
- 存取庫:plugins/sdlc、plugins/log
```
## L-03:年月週次進雜湊輸入
**裁決**:工作日誌頁名的雜湊輸入改吃「年-月-週次」字串(例如 `2026-09-W1`),取代原本的 `{owner}/{repo}`。週次字串進的是雜湊輸入本身,不是先照舊算出雜湊再在頁名後面加後綴。
**出處**:測試計畫「一週一頁工作日誌」小節第一個 TDD 循環,斷言三個不同存取庫、同一週的三筆日誌落在同一頁,且雜湊輸入不含 `{owner}/{repo}`,最小實作是「頁名改吃週次字串」。
**例子**:`plugins/sdlc`、`plugins/log`、`plugins/meta` 三個存取庫在同一週(週五落在 2026-09-04)各寫一筆日誌。三筆都算出同一個雜湊、落在同一頁 `LOG_{hash(2026-09-W1)}`,各自在頁面內容裡帶自己的存取庫欄位。
可直接貼進測試檔的指令:
```
worklog-target.sh week 2026-09-04
# 輸出:2026-09-W1
```
邊界情況(反例,跨月份):`2026-08-28` 是 8 月最後一個週五,算出 `2026-08-W4`;隔一週的 `2026-09-04` 只差 7 天,卻因為跨了月份算出 `2026-09-W1`。兩者雜湊不同、落在不同頁,不能因為「只差一週」就假設落在同一頁。
```
worklog-target.sh week 2026-08-28
# 輸出:2026-08-W4
```
## L-05:舊日誌拆頁
**裁決**:舊制一庫一頁的工作日誌,依每筆條目自己的日期拆進對應的週頁,不整頁原樣搬過去。拆頁動作可重跑不重複(用條目內容雜湊去重),拆不出日期的條目列進待處理清單,不猜日期也不丟棄。
**出處**:「工作分解結構(WBS)」層3 搬遷與清理表格,工作包名稱「舊一庫一頁日誌依條目日期拆進各週頁,可重跑」,標明「不可逆」;對應 TDD 小節斷言含日期的條目落到正確週頁、沒日期的條目列進待處理清單且不丟掉,同一份輸入跑兩次不產生重複條目。
**例子**:舊頁裡四筆條目:
| 條目 | 日期 | 落頁 |
| --- | --- | --- |
| 條目一 | 2026-08-14 | `LOG_{hash(2026-08-W2)}` |
| 條目二 | 2026-08-28 | `LOG_{hash(2026-08-W4)}` |
| 條目三 | 2026-09-04 | `LOG_{hash(2026-09-W1)}` |
| 條目四 | 無日期欄位 | 列進待處理清單,不猜週次 |
三筆有日期的條目各自落進對應週頁;第四筆沒有日期,列進一份待處理清單交人工確認,不強行歸入任何一週。同一份舊頁重跑一次拆頁,用條目內容雜湊去重,不會讓已經拆過的四筆再多出一份——重跑後 `LOG_{hash(2026-08-W2)}` 頁裡條目一依然只有一份,不是兩份。
## O-09:六條輸出原則裡哪幾條進得了 lint
**裁決**:六條輸出原則裡,只有「避免書面語」與「問句要放句尾」這兩條寫成 `ste100-lint.sh` 裡的程式化判定;其餘四條要靠語意判斷,不硬塞進 lint。
**出處**:「工作分解結構(WBS)」層2 技能行為表格,工作包名稱「`ste100-lint.sh` 補書面語詞彙與問句位置,加名詞展開寫法檢查」,註記「O-09 定案」;對應 TDD 小節有兩個判定,一個餵「請您進行身分驗證確認之動作」斷言抓得到書面語並建議改寫,另一個餵「請告訴我目的地,以便為您查詢班機」斷言抓得到問句不在句尾。
**例子**:
- 輸入「請您進行身分驗證確認之動作」→ 判定為書面語,建議改寫成「請幫我確認您的身分」
- 輸入「請告訴我目的地,以便為您查詢班機」→ 判定為問句不在句尾,應改成先問句、後補充理由
## A-12:關鍵路徑圖涵蓋所有工作包
**裁決**:「涵蓋所有工作包」是指關鍵路徑圖上要畫出全部工作包,不是把 WBS 拆成每一包都串在同一條鏈上。圖裡只有真正的最長鏈標成關鍵路徑,其餘工作包照自己實際的相依邊掛上去,不為了「全部在一條鏈上」而編造假的先後順序。
**出處**:分析頁「關鍵路徑(CPM)」節開頭:「本圖收進全部 55 個工作包(2026-09-07 裁示:關鍵路徑圖必須涵蓋所有工作包)」,並註明「`crit` 只標最長那一條鏈,其餘照自己的相依邊掛,不串成假的先後順序」。
**例子**:55 個工作包全部畫進甘特圖;只有一條鏈(定案交付包 → 雜湊組法收單一入口 → 一週一頁工作日誌 → 舊日誌拆頁)標成關鍵路徑,其餘工作包各自照自己的相依關係接線,沒有相依的直接從錨點日期起排,不硬接到關鍵路徑上。
可直接比對的斷言:
- 甘特圖節點總數:55(等於分析頁工作包總數,一個都不能少)
- 標 `crit` 的節點數:4(就是上面那條鏈),其餘 51 個工作包不掛 `crit`
- 反例:沒有相依的工作包(例如一個獨立的小型修正包)不會被接在關鍵路徑任何一個節點後面,而是直接從錨點日期起排;如果檢查發現它被接進了那條 4 節點的鏈,就是誤把「涵蓋」做成了「全部串成一條鏈」
## I-07:不監看時的相依判定
**裁決**:implement 階段選擇不監看 PR 時,判斷某個工作包是否「已完成」要同時滿足兩個條件:狀態欄本身寫著「已完成」,而且那個工作包對應的 commit 真的在目前分支的歷史裡(用 `git merge-base --is-ancestor` 判定,狀態欄要多存一個 commit 欄位)。兩個條件都成立才放行,只滿足其中一條不算。
這個判法跟「PR 已合併」不衝突:監看模式下 PR 合併之後,commit 自然會進到分支歷史裡,兩個條件同時成立;不監看模式下沒有實際等 PR 合併,改靠這兩個條件直接對真實的 git 歷史查驗,效果等同,但不必守著輪詢。
**出處**:測試計畫「implement PR 監看二選一」小節第二個 TDD 循環,斷言相依包狀態欄寫「已完成」但其 commit 不在目前分支歷史裡時不放行,兩條都成立才放行;使用者故事驗收計畫「PR 沒人審把階段掛住」失敗流程一列寫明「相依判定改吃『狀態欄加 git 祖先』」。
**例子**:某個工作包的狀態欄寫「已完成」、commit 欄記著一個 40 碼 SHA-1。查驗時執行 `git merge-base --is-ancestor {該commit} HEAD`;結束碼 0 才判定它真的完成,可以讓依賴它的下一包開工;結束碼非 0(commit 不在目前分支歷史)即使狀態欄寫完成也不放行。
反例(另一半條件不成立):狀態欄寫「進行中」,commit 欄記的 commit 其實已經是 HEAD 的祖先(`git merge-base --is-ancestor` 結束碼 0)。這種情況一樣不放行——兩個條件要同時成立,狀態欄沒寫「已完成」,光是 commit 在歷史裡也不夠。
## I-09:同一張 PR 疊多個工作包要不要收斂
**裁決**:不設上限,也不強制收斂。一張 PR 可以疊上任意數量的工作包;每次收尾時要印出目前這張 PR 疊了幾個工作包、累計改了幾行(用 `git diff --shortstat` 取得),讓疊加狀況看得見,但不會因為疊太多就被擋下。
**出處**:「定案規格交付包」工作包的測試計畫小節,列出十項定案的簡表,其中一項寫明「I-09 不設上限」;「implement PR 監看二選一」小節第四個 TDD 循環,斷言每次收尾都印出目前這張 PR 疊了幾包、累計幾行,最小實作是取 `git diff --shortstat` 與領取紀錄。
**例子**:同一張 PR 已經疊了 3 個工作包、累計改了 214 行。收尾時印出「本 PR 目前疊 3 包,累計 +180/-34 行」,然後照常繼續,不會因為已經疊了 3 包就強制先關閉這張 PR。
## 無繼承例子的工作包:`analyze-check.sh` 三合一靜態檢核
**說明**:這份文件收錄的十項技術定案加 F-01 決議,沒有一項對應到「三合一靜態檢核」這個工作包。逐一核對過 N-01、N-02、N-05、N-07、L-03、L-05、O-09、A-12、I-07、I-09、F-01,都不是這個工作包的裁決依據,硬套任何一項的例子都是誤導。
**如實記錄**:這個工作包沒有從十項技術定案加 F-01 決議裡繼承到的例子,動工時要自己另外準備測試資料——具體要涵蓋哪三種靜態檢核、各自的正常輸入與異常輸入長什麼樣子,留給工作包自己在分析頁或動工當下決定,不在這份文件裡代寫。
## F-01:五個未註冊存取庫的去向
盤點 jsc 技能組時,發現五個存取庫檔案完整、能動,但沒登錄進 `plugins/meta` marketplace 正本的 `.claude-plugin/marketplace.json`。這一節記下五個存取庫各自的決議,供 E 表重寫直接引用。
**裁決**:五個存取庫全部不納入正本,各自維持獨立系統。逐一列用途與決議:
| 存取庫 | 一句話用途 | 決議 |
| --- | --- | --- |
| `plugins/code`(jsc-code) | .NET/NuGet 升版、Gitea AI review findings 修復、存取庫批次同步、`TARGET.md` 每日待辦 | 不納入正本,維持獨立系統 |
| `plugins/doc`(jsc-doc) | Gitea 通知分組處理、docker 註解整理、議題分析與同步、工時日誌 | 不納入正本,維持獨立系統 |
| `plugins/persona`(jsc-persona) | AI 人格化記憶聊天,跟 SDLC 技能組完全不相干的獨立系統 | 不納入正本,維持獨立系統 |
| `plugins/shared`(jsc-shared) | 三十多支跨助理共用規格類技能(`spec-*`) | 不納入正本,維持獨立系統 |
| `plugins/code-review`(呼叫前綴 `jsc:`,不是 `jsc-code-review:`) | 以 GitHub Actions 為基礎的 RPG 攻防式 `git diff` review,跟正本裡互動式的 `jsc-review` 是兩套不同東西 | 不納入正本,維持獨立系統 |
**出處**:這一輪盤點(2026-09-07)裡使用者針對「五個未註冊存取庫逐一定去向」這一項待辦的明確答覆——五個全部不納入,不再逐一討論註冊、歸檔或刪除三選一。
**對 E 表的具體影響**:`meta/tools/delegate-spec.tsv` 本身已經是對的——現有 35 列,不含這五個存取庫的任何技能,不必再修。真正還記著這幾支技能、需要訂正的是 `/root/plugins/TODO.md` 第 652~655 行那份 E 表(設計討論用的表格,跟 `delegate-spec.tsv` 是兩份不同的東西)。決議之後,TODO.md 那份 E 表要照下面的方式修正,實際改檔案交給 WP-36(或 TODO.md 自己校正清單裡已經開著的 F-02 項):
- **E-13**(TODO.md 第 652 行,`jsc-doc:notifications`,定期讀 Gitea 通知分組提醒):整條移除。這支技能不會進正本,助理的技能清單裡永遠找不到它。
- **E-14**(TODO.md 第 653 行,`jsc-code:review-resolve`,巡檢 findings 有沒有新的未處理項目):整條移除,理由同上。
- **E-15**(TODO.md 第 654 行,原列 `jsc-pkg:pkg-update`、`jsc-code:nuget`):只留 `jsc-pkg:pkg-update` 那一半,`jsc-code:nuget` 那一半移除。
- **E-16**(TODO.md 第 655 行,原列 `jsc-code:sync`、`jsc-gitea:repo-sync`):只留 `jsc-gitea:repo-sync` 那一半,`jsc-code:sync` 那一半移除。
- **M-20**(TODO.md 第 934 行,`jsc-code:target` 跟助理待辦簿的關係要收攏成一套,還是只巡檢它的系統排程):這個問題本身不成立了。`jsc-code:target` 不在正本裡,助理的技能清單與委派判定清單都碰不到它,不會被觸發,也就沒有「兩份待辦互不知道」的風險。這一項直接關閉,不必再往下決議要收攏還是只巡檢。
`plugins/persona`、`plugins/shared` 沒有被 TODO.md 那份 E 表任何一列引用,純粹是盤點時發現的閒置存取庫,記下「維持獨立、不納入」即可,不需要再對 E 表或委派判定清單做任何修正。
**例子**:`meta/tools/delegate-spec.tsv` 現有 35 列,範圍剛好卡在 `ask` 到 `sdlc`,不含 `code`、`code-review`、`doc`、`persona`、`shared` 五個 domain 的任何一支技能——這份檔案本來就是決議之後該有的樣子,不必動它。要改的是 TODO.md 裡那份 E 表:核對 E-13 到 E-16、M-20 這五列,照上面的方式移除或裁半,不必再往回加東西,也不必幫已刪的那一半補回來。
**不是價值判斷**:五個存取庫都是完整、能動的系統,不納入正本不代表它們沒用或做得不好。`persona` 是另一條產品線,人格化聊天跟 SDLC 開發流程沒有交集;`shared` 是跨助理共用規格技能,服務對象是所有助理而不是單一 SDLC 流程;`code`、`doc`、`code-review` 三個雖然功能上跟 jsc 技能組相近(都碰 Gitea、都碰程式碼),但各自的呼叫方式、維運節奏、目標使用情境都不同,例如 `code-review` 連呼叫前綴都還是舊的 `jsc:`,跟正本裡 `jsc-review` 的互動式流程本來就是兩套設計。維持獨立系統,讓 jsc 技能組正本只收它管得到、巡檢得到的技能,才是對的做法。
## 跟 `wp01-todo-corrections.md` 的分工
這份文件收十項技術定案跟 F-01 決議,都是這一輪盤點裡定下來、可以直接引用的規格內容。
`TODO.md` 的狀態校正另外放在 [`wp01-todo-corrections.md`](wp01-todo-corrections.md),不併進這份文件;不能開 PR 的完整理由見該文件開頭。