SDD: docs/3-specs/jdd-dual-profile(draft → active,leo 2026-08-05 回「開工」)
範圍:總管指定的「防炸兩件 → Phase 0 → Phase 1」,Phase 2 以後未開工。
■ 防炸(排在所有 task 之前,因為它們炸的是既有的東西)
- check-no-instance-names.sh + instance-names.txt:框架範本不得混入實例專名
基線實測 22 行命中(非先前誤報的 20)→ 9 行無損泛化改寫、13 行檔級豁免記帳待 W3 搬走
拒絕假性清理(把專名換成模糊詞=資訊消失、分層問題還在)
- check-legacy-paths.sh:已發佈腳本引用的 35 條遠端路徑只增不移
舊實例跑的是舊腳本、路徑寫死;搬檔=整排 404 且不會有下一次更新來修它(1.16.0 前科)
■ Phase 0 地基
- template/manifest/{common,repo,orchestrator}.tsv:安裝清單單一真相源
修好 install/update 兩份硬編清單的既有漂移——install 從不裝 wiki-first-search /
subagent-wiki-guard / publish-lag-check / decisions-summary,但 update 會
⇒ 乾淨安裝反而拿不到 1.16/1.17/1.18 的招牌功能
- .claude/hooks/lib/role-lib.sh:scope×role 兩軸機械判定,零自陳
身分矩陣六組實測全通過,含「成員 repo × orchestrator」不存在的格子擋下
- .sdt-framework-dev:框架開發標記(官方沒有 --framework-dev 這個參數,實查非記憶)
■ Phase 1 雙 profile
- profiles/{repo,orchestrator}/CLAUDE.md 兩部憲法
- install.sh:--profile + 自動偵測+寫檔前確認、manifest 驅動、
CLAUDE.md 三段組裝(框架區/本地補充區界標+sha256)、.profile、.template-manifest、
settings.json 寫入 env.AGENT_ROLE 預設
- update.sh:漂移偵測(不覆蓋手改檔、另存 .new、白話清單)+ 基準快照隨更新前進
- template/CLAUDE.md 原路徑凍結留底(相容)
■ 順手修掉兩個舊 bug(都在本次要動的函式裡)
- add_if_missing 少了 mkdir -p ⇒ 新目錄的檔 curl 失敗但 VERSION 照升(2026-07 記「待回報」至今未修)
- 下載健全性只用 [ -s ]=非空即接受 ⇒ 404 頁面會無聲覆寫好檔
(SKILL.md 260→1 行的機制;同一支腳本的版本號那條路早就防了,檔案這條沒防)
■ 實測(非推論)
- G4 憲法分流:兩個乾淨環境各裝一次,orchestrator 版含 SDD 三件式關鍵字 0 次、
repo 版含上游指針 8 次;界標 4/4;sha 宣告與實算相符
- G7 CI 擋實例名:注入違規行 → fail 並指出 sdd-check.md:77,exit 1;還原後 exit 0
- 漂移偵測:手改兩支 hook → 正確報 2 支、手改內容保住、產 .new;
解掉後歸零;連跑三輪冪等
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
15 KiB
jdd-dual-profile — Tasks
權威來源:此檔案是進度真相,不是 CLAUDE.md 或對話。 規則:動手前標 [🔄],完成立刻標 [x],不批次更新。 每一項都標「服務哪條 Gherkin」(G1–G7 定義見
requirements.md§四)。 🟢 status: active(2026-08-05 leo 回「開工」)。 進度:防炸兩閘 + Phase 0 + Phase 1 已完成(Phase 1 有兩項 ◐,見下)。 Phase 2 以後未經確認不得開工(總管指定:先停下驗 Gherkin)。
Gherkin 對照速查
| 號 | 一句話 | 來源 |
|---|---|---|
| G1 | PM 總管優先補接縫而非做新功能 | JDD §七 |
| G2 | 考生改考卷被攔截 | JDD §七 |
| G3 | 進度以站計量 | JDD §七 |
| G4 | 憲法分流不靠判斷 | 分離 §七 |
| G5 | 政策包即插即用(本波只到 ◐ 半通) | 分離 §七 |
| G6 | 實例改機制被攔 | 分離 §七 |
| G7 | 框架混入實例名被 CI 擋 | 分離 §七 |
Phase 0:地基(manifest + 兩軸判定)
前置條件
- leo confirm 本 SDD,frontmatter 由
draft改active
Tasks
-
0.1 定義 manifest 格式並產出三份
template/manifest/{common,repo,orchestrator}.tsv- 服務:G4(分流的資料基礎)、G6(產物區清單的單一來源)
- 欄位:
dest class profile;class ∈overwrite|keep|add-if-missing|keep-with-template - 驗收:三份 manifest 涵蓋現行 install.sh 硬編的每一個
download_if_missing目標, 逐項比對零遺漏(貼比對輸出) - 注意:既有檔一律標
common且 dest 路徑與現況完全相同(決策 D3,不搬檔)
-
0.2 寫
template/.claude/hooks/lib/role-lib.sh(兩軸判定函式庫)- 服務:G2、G6
- 內容:
sdt_repo_root/sdt_rel_path/sdt_scope/sdt_role/sdt_assert_identity/sdt_file_path_from_stdin(jq→python3→grep 三段 fallback) - 驗收:以四組身分(orchestrator×orchestrator、orchestrator×engineer、 repo×engineer、repo×orchestrator)跑單元測試,最後一組回 exit 2;貼四組輸出
- 注意:不得用
CLAUDE_PROJECT_DIR(雲端可跑);bash 3.2 相容
-
0.3 立 marker 檔約定:
system-dev/.profile、system-dev/.template-manifest、.sdt-framework-dev- 服務:G4、G6
- 驗收:三個檔的格式各寫一段規格進 design 的附錄,並在框架 repo 自己放一份
.sdt-framework-dev(commit) - 注意:
--framework-dev不是官方 CLI flag(決策 D9),別去找那個參數
Phase 1:雙 profile 與 CLAUDE.md 生成
前置條件:Phase 0 全部完成
-
1.1 建
template/profiles/repo/CLAUDE.md(repo 憲法範本)- 服務:G4
- 來源:現行
template/CLAUDE.md演進;加「上游指針」一行、「站號怎麼標在 task 上」一段、 W3 must-read 注入點一段 - 驗收:
grep -c "上游" ≥ 1;全文不含任何實例專名
-
1.2 建
template/profiles/orchestrator/CLAUDE.md(總管憲法範本)- 服務:G4、G3
- 內容:效忠 root/journeys、JDD 全術語表、sprint 站號全流程、 進度語言「J-x 已點亮 n/m 站」、問題升級階梯三級(藍圖 §5.5)、W3 must-read 注入點
- 驗收:
grep -c "SDD 三件式\|requirements.md" = 0(G4 明文:總管版無 SDD 三件式細節) - 注意:不得出現任何實例專名(藍圖 v3 的內容要抽象化,專案名留給實例填)
-
1.3
install.sh加--profile=repo|orchestrator+ 自動偵測 + 一次性人確認- 服務:G4
- 偵測規則:目前目錄下存在多個各自帶
.git的子目錄 → 建議 orchestrator - 驗收:三種呼叫(明示 repo/明示 orchestrator/不指定走偵測)各跑一次乾淨環境,
貼出各自產生的
system-dev/.profile內容 - 注意:確認在寫入任何檔案之前問,別裝了一半才問
-
1.4
install.sh改讀 manifest 鋪設產物 + 產.template-manifest- 服務:G4、G6
- 驗收:repo profile 裝出的檔案集合 =
common.tsv ∪ repo.tsv, 且不含 orchestrator 專屬檔(ls對照貼出)
-
1.5 CLAUDE.md 三段組裝(框架區界標 + 本地補充區界標 + sha256)
- 服務:G4
- 驗收:裝完的 CLAUDE.md 含
sdt:framework begin/end與sdt:local begin/end四個界標, 且sha256值與框架區實際內容相符(重算比對貼出)
-
1.6
install.sh的build_hooks_json()加 profile 維度 + 寫入env.AGENT_ROLE預設- 服務:G2、G6
- 驗收:兩 profile 各自產生的
settings.json中,hook 掛載順序符合 design §4.4; orchestrator 實例的env.AGENT_ROLE = orchestrator、repo 實例 =engineer
-
[~] 1.7
update.sh改讀 manifest + 三態判定 + 漂移清單輸出- 服務:G6(機械閘 #3)
- 驗收:在 InkStoneCo 實例上跑,漂移清單恰好列出 4 支
(
pre-write-guard.sh/sdd-guard.sh/subagent-wiki-guard.sh/wiki-first-search.sh, 見 design §0.4 基線),貼完整輸出 - 注意:漂移檔不覆蓋,新版另存
<檔>.new;輸出用白話(leo 一眼看得懂該做什麼) - 現況:◐ 漂移偵測+基準維護已實作並實測;但 update.sh 的檔案清單尚未改讀 manifest(仍是自己那份硬編),install/update 清單漂移的根因只修了一半
-
[~] 1.8
update.sh舊實例遷移:無 manifest → 一次性補植 + CLAUDE.md 界標補植- 服務:G4、G6
- 驗收:拿一份 1.18.0 的實例副本跑兩次 update,第二次為 no-op(冪等,貼兩次輸出對照)
- 注意:舊 CLAUDE.md 整份包進
sdt:local區,一個字都不能掉 - 現況:◐ 舊實例無 manifest → 首輪自動建基準(已實測);CLAUDE.md 界標補植未做
-
1.9
template/CLAUDE.md原路徑保留轉址說明(向下相容)- 服務:G4
- 驗收:舊版 update.sh 對該路徑的 curl 仍回 200(決策 D3)
Phase 2:JDD 文件範本(orchestrator profile)
前置條件:Phase 1 完成(範本要靠 manifest 才鋪得下去)
-
2.1
docs/root.md.template(白話根文件範本)- 服務:G1
- 內容:JDD §3.1 格式原樣 + 三條規則(來源標記必附、禁技術名詞、🔴 卡必附對帳日)
- 驗收:範本自身通得過 task 3.2 的 J4/J8 檢查(自己吃自己狗糧)
-
2.2
docs/journeys.md.template(PM 驗收文件範本)- 服務:G1、G3
- 內容:JDD §3.2 三層巢狀 +「附:站點索引表」段 + 站全域編號/引用不重抄的註記
- 驗收:範本含站點索引表且欄位為「站|被哪些 Journey 經過|改動時重考範圍」
-
2.3
docs/sprint.md.template(站號 sprint)+ tasks.md 站號欄位約定- 服務:G3
- 內容:JDD §五 四步流程、順序鐵律「先認領 → 認領不足才新增 → 新增必掛站」、 起訖日與到期結算欄
- 驗收:範本能被 task 3.4 的 J6 判準讀出「本 sprint 指定站」與「未點亮站」
-
2.4
docs/triage-map.md.template(分診表格式,內容留實例)- 服務:G1
- 驗收:只有欄位與規則,零實例內容(通得過 task 4.1 的專名檢查)
-
2.5
docs/plugin-load-order.md(W3 插槽文件)+ 兩份憲法的 must-read 注入點- 服務:G5(半通的那一半)
- 內容:分離 §五 四步載入順序原文 +「政策包=官方 plugin,框架不發明平行格式」的約定
- 驗收:兩份 profile CLAUDE.md 各含一段可被 plugin SessionStart hook 填入的注入點標題
-
2.6 JDD 術語表寫進 orchestrator 憲法(Journey 取代 CP,禁用舊詞)
- 服務:G3
- 驗收:術語表七詞(Journey/Station/通關/點亮/對帳/完備/輪子卡·賭注卡)齊全,
且標明
CP.yaml/CPDO.md屬技術軌內圈保留原名
Phase 3:封路 hook
前置條件:Phase 0(role-lib)+ Phase 2(有檔可擋)
-
3.1
role-guard.sh(J1+J2+J3,common)- 服務:G2(命門)
- 內容:orchestrator 禁寫 code 路徑/禁寫 tasks·requirements·design;
engineer 禁寫 journeys·root·
*.feature·md 內 Gherkin 區塊;矩陣空格 exit 2 - 驗收:六組實測各貼 stdout/exit code——
① orchestrator 寫
.py→ 擋 ② orchestrator 寫tasks.md→ 擋 ③ engineer 改journeys.md的 Gherkin → 擋(這條就是 G2) ④ engineer 寫.py→ 放行 ⑤ orchestrator 寫journeys.md→ 放行 ⑥ repo profile ×AGENT_ROLE=orchestrator→ 擋並要求修正環境 - 注意:Gherkin 區塊偵測要涵蓋 md 內的 ```gherkin fence 與
- **G-x.y** Given行式
-
3.2
jdd-format-guard.sh(J4+J5+J8,common)- 服務:G1、G3
- J4:
root.md🔴 卡缺【要驗證+對帳日】→ 擋並指行號 - J5:
tasks.md新增行缺站號 → 擋(Edit 看new_string,Write 比對現檔差異) - J8:
root.md/journeys.md技術名詞黑名單命中 → 擋並列詞+行號 - 驗收:三條各一組正例一組反例,共六次實測貼輸出
- 注意:J5 只判新增行,改既有行不擋(否則格式修正都做不了);誠實限制寫進註解
-
3.3
station-done-guard.sh(J6,common,掛 Stop/TaskCompleted)- 服務:G3
- 判準:本 sprint 指定站的 Gherkin 全綠才算收工;「tasks 全關」不算
- 驗收:造一個「tasks 全關但站 Gherkin 未綠」的情境 → 被退回(貼 exit 2 輸出)
- 注意:框架內沒有既有的 sprint 收尾 hook(
delivery-police.sh只在 InkStoneCo 實例), 這是新增不是修改;W4 時實例那支要退役,別兩處維護
-
3.4
regression-scope.sh(J7,common)- 服務:G3
- 行為:偵測站相關實作變動 → 讀 journeys.md 站點索引表 → 列需重考的 Journey/Gherkin
- 驗收:改動某站的實作檔後,輸出正確列出該站被哪些 Journey 經過(貼輸出)
- 注意:提醒不阻擋(exit 0)
-
3.5
install-artifact-guard.sh(S1,common)- 服務:G6
- 行為:寫入
.claude/hooks//system-dev/範本區/plugin 安裝目錄 → 擋, 提示「機制變更走框架/政策包 repo 提案」;.sdt-framework-dev或SDT_FRAMEWORK_DEV=1放行 - 驗收:① 實例 session 編輯
.claude/hooks/任一檔 → 擋(這條就是 G6) ② 框架 repo(有 marker)編輯同路徑 → 放行。兩組都貼輸出 - 注意:「範本區」的定義來自 manifest(class=overwrite 者),不要另寫一份路徑表
-
3.6
orchestrator-scope-guard.sh(S4,orchestrator profile 專屬)- 服務:G6
- 來源:改寫自 InkStoneCo 實例的
guard-cross-project.sh(上收進框架,決策 D6) - 抽象化重點:子 repo 目錄清單、autodispatch 白名單由實例設定檔提供, 範本內零實例專名(通得過 task 4.1)
- 驗收:以假造的成員目錄結構跑三組——寫子 repo 的
.py→ 擋/寫子 repo 的.md→ 放行/CHILD_SESSION=1且在白名單內 → 放行 - 注意:職責與 3.1 不重疊——3.1 管「角色能寫什麼類型」,本支管「總管能進哪個位置」
-
3.7 改
session-start-recall.sh:依 profile 分流注入【改既有】- 服務:G3、G4
- orchestrator:root/journeys 摘要 + 本 sprint 未點亮站(治「起牀沒事做」)
- repo:維持現行 principles/status/mistakes
- 驗收:兩 profile 各開一次 session,貼注入內容對照(orchestrator 那份要出現站號)
-
3.8 hook 全鏈掛載順序實測(design §4.4)
- 服務:G2、G6
- 驗收:故意觸發多條規則的一次寫入,確認錯誤訊息來自最外層那條(範圍大的先擋)
Phase 4:框架側 CI 與清潔
前置條件:Phase 1(manifest 定義了「範本區」)
-
4.1
scripts/check-no-instance-names.sh+scripts/instance-names.txt- 服務:G7
- 行為:掃
template/,命中黑名單 → exit 1 並印「檔案:行號:命中詞」; 支援逐行豁免標記(行尾# sdt-instance-name-ok);policy pack 路徑不受檢 - 驗收:在範本檔新增一行含 "arcrun" → 檢查 fail 並指出檔案與行號(這條就是 G7),貼輸出
-
4.2 現況 20 行命中的分診處置(design §0.5)
- 服務:G7
- (a) 6 行註解/舉例 → 改寫成通用敘述
- (b) 3 行政策內容 + (c) 13 行 L2 產物 → 標
# sdt-instance-name-ok+ 一行「W3 搬遷」註記 - 驗收:處置後
check-no-instance-names.sh回 exit 0,且豁免行數 = 16(貼清單) - 注意:禁止假性清理(把 arcrun 改寫成「某工作流引擎」=資訊消失、問題還在)
-
4.3 掛 pre-commit / CI
- 服務:G7
- 驗收:
bash scripts/check-no-instance-names.sh在 CI 步驟中被呼叫,故意違規的 commit 被擋
Phase 5:出貨(ship-check)
前置條件:Phase 0–4 全部完成
-
5.1 CHANGELOG + VERSION bump(兩處:
template/.claude/VERSION+template/system-dev/VERSION)- 服務:全部
- 版號:1.18.0 → 1.19.0(新功能、向下相容)
- 驗收:兩個 VERSION 檔內容一致;CHANGELOG 用用戶語言寫「這一版你會多出什麼」
- 注意:版本號是 leo 唯一的驗收介面——沒動=等於沒交付
-
5.2 乾淨環境雙 profile 安裝實測(含計時)
- 服務:G4
- 驗收:兩個全新空目錄各裝一次,各記錄實際耗時(分離 §八 預測①:各 < 10 分鐘),
貼安裝輸出 +
ls -R檔案清單對照
-
5.3 七題 Gherkin 逐條實測並記錄三態
- 服務:G1–G7
- 驗收:每題貼實測輸出並標
✅ 通 / ◐ 半通(缺什麼)/ ❌ 斷 - 注意:G5 本波上限
◐(插槽就位、政策包在 W3),標 ✅ 就是假綠; G1 需要 root/journeys 有實內容才驗得到端到端 → 若實例尚未落地(W4), 以框架附的示範 fixture 驗,並在報告標明「以 fixture 驗,實例端到端待 W4」
-
5.4 回報總管:交付物、三態表、與規格假設不符的清單
- 服務:全部
- 驗收:報告含 design §0 全部實查發現 + 本波實際落地的 hook 數(改既有 vs 新增)
完成定義
整個 SDD 完成 = 以下全部達成:
- 所有 tasks 標 [x]
- G1–G7 逐題有實測證據,且無任何一題為
❌ 斷(G5 可為◐) bash scripts/check-no-instance-names.sh回 exit 0bash scripts/sdd-active-check.sh docs/3-specs回 exit 0- 兩處 VERSION = 1.19.0,CHANGELOG 已寫
- design.md 與實作一致(如有出入需更新 design,不是默默改 code)
狀態說明
| 標記 | 意義 |
|---|---|
[ ] |
未開始 |
[🔄] |
進行中(當前 session) |
[x] |
完成(有驗收證據) |
[~] |
暫緩(說明原因) |
[!] |
阻擋中(說明阻擋原因) |