# 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 - [x] 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,不搬檔) - [x] 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 相容 - [x] 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 全部完成 - [x] 1.1 建 `template/profiles/repo/CLAUDE.md`(repo 憲法範本) - 服務:**G4** - 來源:現行 `template/CLAUDE.md` 演進;加「上游指針」一行、「站號怎麼標在 task 上」一段、 W3 must-read 注入點一段 - 驗收:`grep -c "上游" ≥ 1`;全文不含任何實例專名 - [x] 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 的內容要抽象化,專案名留給實例填) - [x] 1.3 `install.sh` 加 `--profile=repo|orchestrator` + 自動偵測 + 一次性人確認 - 服務:**G4** - 偵測規則:目前目錄下存在多個各自帶 `.git` 的子目錄 → 建議 orchestrator - 驗收:三種呼叫(明示 repo/明示 orchestrator/不指定走偵測)各跑一次乾淨環境, 貼出各自產生的 `system-dev/.profile` 內容 - 注意:**確認在寫入任何檔案之前**問,別裝了一半才問 - [x] 1.4 `install.sh` 改讀 manifest 鋪設產物 + 產 `.template-manifest` - 服務:**G4**、G6 - 驗收:repo profile 裝出的檔案集合 = `common.tsv ∪ repo.tsv`, 且**不含** orchestrator 專屬檔(`ls` 對照貼出) - [x] 1.5 CLAUDE.md 三段組裝(框架區界標 + 本地補充區界標 + sha256) - 服務:**G4** - 驗收:裝完的 CLAUDE.md 含 `sdt:framework begin/end` 與 `sdt:local begin/end` 四個界標, 且 `sha256` 值與框架區實際內容相符(重算比對貼出) - [x] 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 界標補植未做** - [x] 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 0 - [ ] `bash scripts/sdd-active-check.sh docs/3-specs` 回 exit 0 - [ ] 兩處 VERSION = 1.19.0,CHANGELOG 已寫 - [ ] design.md 與實作一致(如有出入需更新 design,不是默默改 code) --- ## 狀態說明 | 標記 | 意義 | |------|------| | `[ ]` | 未開始 | | `[🔄]` | 進行中(當前 session)| | `[x]` | 完成(有驗收證據)| | `[~]` | 暫緩(說明原因)| | `[!]` | 阻擋中(說明阻擋原因)|