依 D22 翻正舊 ignore 政策:本 repo 自己的 SDD 進版控 + 新增 jdd-dual-profile 卷

🔴 修的病:這個框架 repo 自己的 5 份 SDD 全部被 .gitignore 擋在版控之外,
只活在一台硬碟上——clone 不到、雲端 CC 讀不到、沒備份。SDD 是進度真相源,
「框架 repo 沒吃自己的狗糧」。

依據 D22(已翻案):Gitea private 除機敏值外全 push,雲端工人靠 clone,docs 缺=斷糧;
只有 GitHub mirror 才嚴篩,而 docs 整包已在 github-publish-exclude.txt。

.gitignore 改法:整條擋 → 只擋子項(/*)+ 逐個放行真 SDD。
與 template/ 底下逐位元組相同的自裝副本(TEMPLATE-sdd/、SDD-LIFECYCLE.md)續擋。

新增 docs/3-specs/jdd-dual-profile/(status: draft,等 leo confirm 才升 active):
JDD(PM 軌 root/journeys/角色權限/站號 sprint)與雙 profile 合成一卷,
33 條 task/6 phase,每條掛服務哪條 Gherkin(G1–G7)。
新增 hook 6 支、改既有 hook 1 支。**0 行實作**。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 23:22:14 +08:00
parent dc4fe67e15
commit 2a8c259d08
12 changed files with 1726 additions and 1 deletions
@@ -0,0 +1,229 @@
# jdd-dual-profile — Requirements
> 建立:2026-08-05 | 最後更新:2026-08-05
> 負責人:system-dev-template CC
> 來源:InkStoneCo 總管交辦 **W2**`InkStoneCo/system-dev/docs/3-specs/pending-changes.md`
> 「[proposal] 總管系統藍圖 v3 三件套落地安排」§三 W2)
> 需求輸入:《JDD 導入規格》§三/四/五/六 +《分離導入規格》§三/六 +《總管系統藍圖 v3》§3/§4/§5.5
> 狀態:**等 leo confirm,未實作**
---
## 為什麼合成一份(不是兩份 SDD)
JDD 的角色權限 hook 必須靠 profile 分流才成立——「總管版憲法」與「repo 版憲法」是同一支
CLAUDE.md 生成流程的兩個輸出。拆兩份 SDD 會把 CLAUDE.md 生成、manifest、install/update
改造各做兩遍,且第二遍必然要推翻第一遍的檔案佈局。總管裁定:合成一份。
---
## 一、Epic
| Epic | 一句話 | 需求輸入 |
|------|--------|---------|
| **E1 雙 profile 框架** | 同一個 template 能裝出「總管級」或「repo 級」兩種實例,憲法由安裝位置決定、不靠 agent 自我判斷 | 分離 §三 |
| **E2 PM 軌文件(JDD** | 框架提供 `root.md` / `journeys.md` 兩份範本與格式紀律,讓驗收線從「tasks 全關」換成「站的 Gherkin 全綠」 | JDD §三、§五 |
| **E3 角色封路** | orchestratorengineer 的可寫範圍用 hook 機械強制,不靠 prompt 叮嚀 | JDD §四、§六 |
| **E4 防糾纏** | 實例不改機制、框架不含實例資料,兩條鐵律各配機械閘;update 能報出被手改過的檔 | 分離 §一、§六 |
**明確不在本 SDD 範圍**W3 才做):arcrun-policy plugin 本體、政策包內容搬遷、
marketplace 發行。本 SDD 只負責**留好插槽**(載入順序文件化 + profile 憲法的 must-read 注入點)。
---
## 二、User Story EARS
### E1 雙 profile 框架
**US-1.1**:身為安裝者,我要一條指令就裝出正確的那部憲法,不必自己判斷該裝哪些檔。
- `EARS-1.1.1` When 安裝者執行 `install.sh --profile=orchestrator`the system shall
只鋪設 orchestrator profile 宣告的產物,且不鋪設 repo profile 專屬的產物。
- `EARS-1.1.2` When 安裝者執行 `install.sh --profile=repo`the system shall
只鋪設 repo profile 宣告的產物(含 SDD 三件式與 repo 級 wiki 規範)。
- `EARS-1.1.3` When 安裝者未指定 `--profile`the system shall 自動偵測
(目前目錄下存在多個各自帶 `.git` 的子目錄 → 建議 orchestrator),
**並在寫入任何檔案前要求人確認一次**;確認結果寫入 marker 檔,之後不再問。
- `EARS-1.1.4` The system shall 在安裝完成後於 `system-dev/.profile` 留下單行 profile 名,
作為所有 hook 判定 scope 的唯一機器可讀來源。
**US-1.2**:身為框架維護者,我要 common 與兩個 profile 共用**一條版本流**,不開第二個 repo。
- `EARS-1.2.1` The system shall 以單一 `VERSION` 檔涵蓋 common 與所有 profile 的變更。
- `EARS-1.2.2` When 執行 update 而該實例所屬 profile 的產物本版未變動,the system shall
對該 profile 的產物 no-op(不下載、不覆蓋、不在報表列為「已更新」)。
**US-1.3**:身為安裝者,我要 CLAUDE.md 由 profile 範本生成,而我自己補的內容永遠不會被更新洗掉。
- `EARS-1.3.1` The system shall 把生成的 CLAUDE.md 切成「框架區」與「本地補充區」,
兩區以機器可辨識的界標分隔。
- `EARS-1.3.2` While 執行 updatethe system shall 只覆蓋框架區、**絕不動本地補充區**。
- `EARS-1.3.3` If 框架區內容與本版原始範本不一致(=被手改過),then the system shall
不覆蓋該檔、將它列入漂移清單,並提示「回框架提案 or 放棄本地改動」。
### E2 PM 軌文件(JDD
**US-2.1**:身為總管(PM),我要一份白話根文件,讓不懂技術的人讀了能勾或搖頭。
- `EARS-2.1.1` The system shall 於 orchestrator profile 提供 `root.md` 範本,
格式為「一句白話 + 來源標記 + 紅綠燈」。
- `EARS-2.1.2` If `root.md` 中任一 🔴 卡缺少【要驗證 + 對帳日】,then the system shall
在寫入當下攔截並指出行號。
- `EARS-2.1.3` If `root.md``journeys.md` 出現技術名詞黑名單詞(API/DB/WASM/MCP
endpointschema…),then the system shall 攔截並列出命中詞與行號。
**US-2.2**:身為總管,我要 `journeys.md` 承載「角色 → Journey → Station → Gherkin」三層,
並附站點索引表供回歸考查範圍。
- `EARS-2.2.1` The system shall 於 orchestrator profile 提供 `journeys.md` 範本,
含三層巢狀結構與「附:站點索引表」段。
- `EARS-2.2.2` The system shall 在範本內以註記聲明:站全域編號、跨 Journey 共享、
重複出現只寫引用不重抄;Gherkin 的 Then 只寫使用者看得到/感覺到的結果。
**US-2.3**:身為 routine/總管,我要 sprint 的單位是「一組站號」,起牀就有明確的「離通關還缺什麼」。
- `EARS-2.3.1` The system shall 於 orchestrator profile 提供 sprint 範本,
以站號(而非 task 批次)為單位,含起訖日與到期結算欄。
- `EARS-2.3.2` If `tasks.md` 中**新增**的 task 條目未標注它服務哪一站,then the system shall 攔截。
- `EARS-2.3.3` When sprint 收尾驗收,the system shall 以「指定站的 Gherkin 全綠」為判準,
而非「tasks 全關」。
- `EARS-2.3.4` When 偵測到某站相關實作變動,the system shall 查站點索引表並列出需重考的
JourneyGherkin 清單(提醒,不阻擋)。
### E3 角色封路
**US-3.1**:身為系統,我要 agent 的身分由兩個機械來源決定,沒有任何一格靠 agent 自陳。
- `EARS-3.1.1` The system shall 以 `system-dev/.profile` 決定 **scope 軸**
以環境變數 `AGENT_ROLE` 決定 **role 軸**
- `EARS-3.1.2` If `AGENT_ROLE` 未設定,then the system shall 依 scope 推定預設 role
orchestrator profile → orchestratorrepo profile → engineer),不詢問 agent。
- `EARS-3.1.3` If 身分組合落在「repo profile × orchestrator」這個**不存在的格子**
then the system shall 攔截並要求修正環境變數,不得靜默降級。
**US-3.2**:身為系統,我要 orchestrator 寫不了 code、改不了技術軌文件。
- `EARS-3.2.1` If role 為 orchestrator 且寫入目標是程式碼路徑(`src/**``*.py``*.ts`
`*.go``*.sh` 等),then the system shall 攔截(exit 2)。
- `EARS-3.2.2` If role 為 orchestrator 且寫入目標是 `tasks.md` / `requirements.md` /
`design.md`then the system shall 攔截。
**US-3.3**:身為系統,我要 engineer 改不了考卷。
- `EARS-3.3.1` If role 為 engineer 且寫入目標是 `journeys.md` / `root.md` /
任何 `*.feature` 或 md 內的 Gherkin 區塊,then the system shall 攔截。
- `EARS-3.3.2` The system shall 在攔截訊息中說明「考生不能改考卷」與正確做法
(回報給 PM,由 PM 改站或改考題)。
**US-3.4**:身為 session,我醒來時世界已就位,不需要「知道」有哪些機制存在。
- `EARS-3.4.1` When SessionStartthe system shall 依 profile 注入對應的必讀
orchestratorroot/journeys 與本 sprint 未點亮站;repo:現行 status/principles/mistakes)。
- `EARS-3.4.2` The system shall 於 profile 憲法留下 policy plugin 的 must-read 注入點,
使 W3 的 plugin SessionStart hook 能把政策必讀推到眼前,而框架本身不新造外掛格式。
### E4 防糾纏
**US-4.1**:身為框架維護者,我要實例改不了機制——要改就回框架提案。
- `EARS-4.1.1` If 寫入目標落在安裝產物區(`.claude/hooks/``system-dev/` 範本區、
plugin 安裝目錄),then the system shall 攔截並提示「機制變更走框架/政策包 repo 提案」。
- `EARS-4.1.2` While session 帶有框架開發標記(框架 repo 根目錄存在 `.sdt-framework-dev`
或環境變數 `SDT_FRAMEWORK_DEV=1`),the system shall 放行 EARS-4.1.1。
**US-4.2**:身為框架維護者,我要框架範本裡混進實例專名時 CI 就擋下。
- `EARS-4.2.1` When CI 執行,the system shall 掃描範本區,命中實例專名黑名單 → fail
並指出檔案與行號。
- `EARS-4.2.2` The system shall 讓黑名單住在可維護的設定檔,並提供**逐行豁免標記**
(留痕可審),供尚未搬遷的政策內容過渡使用。
- `EARS-4.2.3` The system shall 不對 policy pack 套用本檢查(政策包本來就是一家之言)。
**US-4.3**:身為安裝者,我要 update 告訴我「哪些檔被手改過」。
- `EARS-4.3.1` When 執行 updatethe system shall 比對每個安裝產物的實際雜湊與 manifest
記錄的雜湊,差異者列入漂移清單並逐項提示處置選項。
- `EARS-4.3.2` The system shall 對漂移檔採「不覆蓋 + 另存新版供 diff」策略,不靜默覆寫。
---
## 三、非功能需求
| 項 | 要求 | 為什麼 |
|---|---|---|
| 向下相容 | 既有實例(1.18.x)跑 update **不得 404**;已安裝檔案的遠端路徑不得搬移 | 舊實例跑的是**舊** update.sh,檔案清單與 base URL 寫死在裡面;1.16.0 已被「來源改動=自動更新死掉」咬過一次 |
| 雲端可跑 | 所有 hook 只用 repo 相對路徑與 POSIX 工具,不假設本機絕對路徑 | 分離 §三 common「封路 hook 工具箱(雲端可跑)」 |
| 容錯 | hook 解析失敗(拿不到 file_path/無 jq)一律放行並留痕,不誤殺 | 沿既有 hook 慣例(sdd-guard、wiki-secret-scan |
| 誠實限制 | 每支 hook 頂部註明「擋語法層、擋不了 bash 繞道」,不宣稱不可繞過 | 沿既有 hook 慣例 |
| 安裝時間 | 乾淨環境雙 profile 各 < 10 分鐘 | 分離 §八 arch_iteration 預測① |
| bash 版本 | 相容 macOS bash 3.2(空陣列展開需先判長度) | install.sh 既有踩過的坑 |
---
## 四、驗收 Gherkin(唯一驗收線,tasks 逐條掛號)
> 來源:《JDD 導入規格》§七 三題(G1–G3)+《分離導入規格》§七 四題(G4–G7),原文照抄。
```gherkin
# ── G1JDD §七之一)
Scenario: PM 總管優先補接縫而非做新功能
Given commit push
And root.md journeys.md J-1
When PM J-1
Then push
And
# ── G2JDD §七之二)
Scenario: 考生改考卷被攔截
Given engineer subagent Gherkin
When journeys.md Gherkin
Then hook
# ── G3JDD §七之三)
Scenario: 進度以站計量
Given sprint
When PM
Then J-x n/m tasks
# ── G4(分離 §七之一)
Scenario: 憲法分流不靠判斷
Given template profile
When repo session
Then CLAUDE.md SDD
When repo session
Then CLAUDE.md repo
# ── G5(分離 §七之二)— 本 SDD 只負責插槽,Then 的後半由 W3 兌現
Scenario: 政策包即插即用
Given repo profile
When arcrun-policy plugin spawn engineer
Then hook python primer session
And engineer Arcrun
# ── G6(分離 §七之三)
Scenario: 實例改機制被攔
Given session --framework-dev
When .claude/hooks/
Then hook
# ── G7(分離 §七之四)
Scenario: 框架混入實例名被 CI 擋
Given "arcrun"
When CI
Then fail
```
**G5 的範圍切割(重要)**:本 SDD 交付的是 GivenWhen 能成立的**插槽**——
乾淨實例裝得出 repo profile、載入順序文件化、profile 憲法有 must-read 注入點。
`Then` 的兩句(白名單 hook 攔 python、primer 出現)由 **W3 的 arcrun-policy plugin** 兌現。
W2 收工時 G5 記 `◐ 半通(插槽就位,政策包未做)`,不得標 ✅。
---
## 五、關聯
- 上游提案:`InkStoneCo/system-dev/docs/3-specs/pending-changes.md` §三 W2
- 需求輸入原件:`~/Desktop/總管/JDD-template-upgrade.md``~/Desktop/總管/分離導入規格.md`
`~/Desktop/總管/總管系統藍圖v3.md`
- 生命週期規則:`docs/3-specs/SDD-LIFECYCLE.md`
- 下一波:W3 arcrun-policy plugin(本 SDD 的 G5 後半)