依 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:
+18
-1
@@ -31,7 +31,24 @@ skills/editorial-image/
|
||||
/docs/README.md
|
||||
/docs/1-vision/
|
||||
/docs/2-architecture/
|
||||
/docs/3-specs/
|
||||
|
||||
# ── /docs/3-specs/ 例外(2026-08-05,依 D22 翻正舊政策)──────────────
|
||||
# D22 已翻案:Gitea private 除機敏值外全 push——雲端工人靠 clone,docs 缺=斷糧。
|
||||
# 舊規則把整個 3-specs 擋掉,害「本 repo 自己的 SDD」只活在一台硬碟上:
|
||||
# clone 不到、雲端 CC 讀不到、沒備份。SDD 是進度真相源,必須進版控。
|
||||
# 公開外洩風險已由 scripts/github-publish-exclude.txt 蓋掉(docs 整包不進 GitHub mirror)。
|
||||
#
|
||||
# 作法:只擋子項(用 /*),再逐個放行真 SDD。
|
||||
# 放行=本 repo 自己寫的規格(真相源)
|
||||
# 續擋=與 template/system-dev/docs/3-specs/ 逐位元組相同的自裝副本(零資訊、徒增重複)
|
||||
/docs/3-specs/*
|
||||
!/docs/3-specs/cross-repo-signing/
|
||||
!/docs/3-specs/install-layout/
|
||||
!/docs/3-specs/tasks-project-projection/
|
||||
!/docs/3-specs/wiki-architecture/
|
||||
!/docs/3-specs/jdd-dual-profile/
|
||||
!/docs/3-specs/pending-changes.md
|
||||
|
||||
/docs/4-guides/
|
||||
/docs/5-records/
|
||||
/docs/6-user/
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# cross-repo-signing — Design
|
||||
|
||||
> 狀態:已採納
|
||||
> 建立:2026-06-26 | 最後更新:2026-06-26
|
||||
> 負責人:leo(uncle6me-web)
|
||||
> 來源:issue #12(InkStoneCo 總管)
|
||||
|
||||
---
|
||||
|
||||
## 一句話說明
|
||||
|
||||
所有 repo(mira / graph-plugin / ingest-plugin / Arcrun / template…)共用 `uncle6me-web` 一個 GitHub 帳號發 issue/comment,author 全顯示同一帳號、看不出來源;制度化一條鐵律——**跨 repo 的 issue/comment 一律在開頭署名 `[<本 repo> CC]`**,靠內容層署名溯源。
|
||||
|
||||
---
|
||||
|
||||
## 背景與問題
|
||||
|
||||
- GitHub issue/comment 的 author = 發送帳號(gh token),**沒有 per-repo 身份這設定**。
|
||||
- `git config user.name` 只影響 commit 作者,**不影響 issue/comment author**。
|
||||
- 給每個 repo 開獨立帳號 = 多帳號自動化 = 踩「避免被 flag」鐵律,**不可**(見 issue-handle skill 第 3 節)。
|
||||
|
||||
→ 身份只能在**內容層自報**(約定),不是平台層。
|
||||
|
||||
現狀:CC 們已部分自發(「## 回報(arcrun CC)」「## 回報(graph CC)」),但靠當次自律、不一致(總管自己也常漏署)。本 SDD 把它制度化:寫成鐵律、一處改全 repo 繼承。
|
||||
|
||||
---
|
||||
|
||||
## 範圍
|
||||
|
||||
### 包含(In Scope)
|
||||
- 在 template 的 issue 處理指引(`template/.claude/commands/issue-handle.md`)加一節「跨 repo 署名鐵律」。
|
||||
- 因 issue-handle 是「讀/回/結案」的權威指引、所有 repo 透過 template 繼承,這是規則的正確落點。
|
||||
|
||||
### 不包含(Out of Scope)
|
||||
- 不改 CLAUDE.md(導航牌,不增長;規則細節歸 skill 內文,與既有「採集規則放 skill」一致)。
|
||||
- 不做任何平台層/自動化(不掛 hook、不改 gh 設定)——純內容約定。
|
||||
- 不回改各下游 repo 的歷史 comment。
|
||||
|
||||
---
|
||||
|
||||
## 設計
|
||||
|
||||
新增第 4 節「跨 repo 署名(鐵律)」於 issue-handle skill:
|
||||
|
||||
> **跨 repo 的 issue/comment 一律在開頭署名 `[<本 repo> CC]`**,因所有 repo 共用同一帳號、author 看不出來源,靠內容署名溯源。
|
||||
> - 收件方 CC 回報:`[graph-plugin CC]` / `[mira CC]` / `[ingest CC]` / `[arcrun CC]`…
|
||||
> - 總管下令/追問:`[InkStoneCo 總管]`
|
||||
> - 署名放 comment 第一行或標題式開頭(既有「## 回報(graph CC)」即合格)。
|
||||
|
||||
放在第 2 節(發給別的 repo)之後、第 3 節(flag 界線)之前——順著「跨 repo 互動」的脈絡。原第 3、4 節順延。
|
||||
|
||||
並把第 1 節「讀/回/結案」的 comment 範例帶上署名,讓署名在最常用路徑就被看見(不只躲在後面的鐵律節)。
|
||||
|
||||
---
|
||||
|
||||
## 決策理由
|
||||
|
||||
- **落點選 issue-handle skill 而非 CLAUDE.md**:CLAUDE.md 是導航牌、明令不增長;issue 互動規則屬 skill 內文,與「採集規則放 skill」同構。
|
||||
- **內容層而非平台層**:唯一不踩多帳號 flag 鐵律的解法。
|
||||
- **署名格式 `[<repo> CC]`**:沿用 CC 們已自發的形態,降低改變成本;總管用 `[InkStoneCo 總管]` 區隔下令角色。
|
||||
|
||||
---
|
||||
|
||||
## 升版
|
||||
|
||||
併入下一個 template 版本:1.11.0 → 1.12.0(規範新增、跨 repo 行為改變)。兩個 VERSION 同步。
|
||||
@@ -0,0 +1,146 @@
|
||||
# install-layout — Design
|
||||
|
||||
> 狀態:已採納
|
||||
> 建立:2026-06-26 | 最後更新:2026-06-26
|
||||
> 負責人:leo(uncle6me-web)
|
||||
|
||||
---
|
||||
|
||||
## 一句話說明
|
||||
|
||||
把工具安裝產物從「散落在用戶根目錄(docs/、scripts/、.claude/wiki、.claude/VERSION)」收斂成「只留 CC 死綁的 .claude/ + CLAUDE.md,其餘全進 system-dev/」,並為 wiki 改寫產物正式準備落點。
|
||||
|
||||
---
|
||||
|
||||
## 背景與問題
|
||||
|
||||
目標用戶是 low-code、只會叫 CC 做事的無技術用戶(見 memory user-profile-lowcode)。現行安裝有三個結構問題:
|
||||
|
||||
1. **污染用戶根目錄**:install 在根目錄鋪 `docs/`(七層子目錄)、update 時又生 `scripts/`,跟用戶自己的檔案混在一起,用戶分不清「哪個 docs 是工具的、哪個是我的」。
|
||||
2. **工具資料寄生在 CC 原生資料夾**:`wiki/` 和 `VERSION` 放在 `.claude/` 裡。`.claude/` 是 CC 原生機制目錄,不該塞工具自己的資料與版號。
|
||||
3. **wiki 改寫產物沒有正式落點**:`cards/`(改寫成 AI 自讀定稿 wiki 的落地處)install 從沒建立,導致實機(KB)自己長出 `.claude/wiki/cards/` 還自行 `git init`。位置該由工具準備,不靠用戶自救。
|
||||
|
||||
關鍵語義陷阱:現行 `docs/` 同時是「工具文件結構」與「用戶 raw source(原始文件來源)」。重構必須把這兩義拆開。
|
||||
|
||||
---
|
||||
|
||||
## 範圍
|
||||
|
||||
### 包含(In Scope)
|
||||
- 新增 `system-dev/` 作為工具所有「資料」的根:`system-dev/{VERSION,wiki/,docs/,scripts/}`。
|
||||
- `.claude/` 只保留 CC 死綁的三樣:`settings.json`、`commands/`、`hooks/`。
|
||||
- `wiki/`(含 cards/)、`VERSION`、工具的 `docs/`、`scripts/` 全部移到 `system-dev/`。
|
||||
- install.sh 正式建立 `system-dev/wiki/cards/`(放 `.gitkeep` 空桶佔位)。
|
||||
- 舊用戶遷移:update.sh 自動遷移 + session-start hook 自我防呆(雙保險)。
|
||||
- 同步更新所有路徑引用(CLAUDE.md、SKILL.md、wiki-init、sdd-check、wiki-capture、sdd-guard、session-start-recall、INDEX、decisions-summary、README)。
|
||||
|
||||
### 不包含(Out of Scope)
|
||||
- **不動用戶 raw source**:用戶自己的 `docs/`、Logseq `pages/+journals/`、Obsidian vault 根——工具只讀、不搬、不改名。
|
||||
- **不搬 commands/ 與 hooks/ 出 .claude/**:CC slash command 與 hook 註冊路徑死綁 `.claude/`(hooks 經討論決定務實留 .claude/)。
|
||||
- **不改 CLAUDE.md 位置**:CC 開 session 只讀根目錄/.claude 的 CLAUDE.md,留根。
|
||||
- 不重寫 wiki 內容本身(只準備落點與路徑;既有卡片內容遷移不改寫)。
|
||||
|
||||
---
|
||||
|
||||
## 設計
|
||||
|
||||
### 架構概覽
|
||||
|
||||
```
|
||||
用戶專案/
|
||||
├── CLAUDE.md ← CC 原生,留根
|
||||
├── .claude/ ← 只放 CC 機制檔
|
||||
│ ├── settings.json ← CC 原生(hook 在此註冊)
|
||||
│ ├── commands/*.md ← slash 指令,CC 死綁此路徑
|
||||
│ └── hooks/*.sh ← 留 .claude/(務實決定)
|
||||
└── system-dev/ ← 工具所有資料(新)
|
||||
├── VERSION ← 工具版號(從 .claude/VERSION 搬出)
|
||||
├── wiki/ ← 工具 wiki(從 .claude/wiki/ 搬出)
|
||||
│ ├── INDEX.md TAXONOMY.md status.md mistakes.md decisions-summary.md .wikiignore
|
||||
│ └── cards/ ← 【新】改寫產物落點,install 建好,.gitkeep 佔位
|
||||
├── docs/ ← 工具文件(從根 docs/ 搬出)
|
||||
│ ├── README.md SKILL.md
|
||||
│ └── 1-vision/ 2-architecture/ 3-specs/ 4-guides/ 5-records/ 6-user/
|
||||
└── scripts/ ← install.sh + update.sh,一開始就裝
|
||||
```
|
||||
|
||||
### 關鍵決策
|
||||
|
||||
| 決策 | 選擇 | 原因 | 放棄的選項 |
|
||||
|------|------|------|----------|
|
||||
| 工具資料落點 | 收進 `system-dev/` | 不污染用戶根目錄;用戶一眼分清工具 vs 自己的檔 | 散在根目錄(現狀,壞習慣) |
|
||||
| 資料夾命名 | `system-dev/`(明碼) | 用戶 ls 看得到、好找 | `.sdt/`、`.system-dev/`(隱藏,low-code 用戶不易發現) |
|
||||
| wiki/VERSION | 搬出 .claude/ | 工具資料不該寄生 CC 原生目錄 | 留 .claude/(現狀,職責混淆) |
|
||||
| commands/hooks | 留 .claude/ | CC 機制死綁;hooks 搬走只多一層路徑、無實益 | 全搬 system-dev/(settings.json 走不了,得留跳板) |
|
||||
| CLAUDE.md | 留根 | CC 自動讀,搬走整套導航/鐵律失效 | 搬 system-dev/(要留極薄跳板,等於沒搬) |
|
||||
| docs 雙語義 | 拆開:工具→system-dev/docs/,raw source 維持用戶處 | 解決「哪個 docs 是誰的」 | 全搬(會誤搬用戶內容)/ 全留(污染依舊) |
|
||||
| cards/ 落點 | install 正式建 + .gitkeep | 位置由工具準備,不靠用戶自救 | 不建(現狀,用戶自己長、自行 git init) |
|
||||
| 舊用戶遷移 | update 自動遷移 + hook 防呆雙保險 | low-code 用戶不會手動遷;不遷會默默壞 | 只靠 update(沒跑的人壞)/ 只靠手動(用戶不會做) |
|
||||
| 版本語意 | 1.9.0(中版號 + 自動遷移、向下相容到能升上來) | 提供自動遷移即非破壞性手動 | 2.0.0(若要求用戶手動遷才算) |
|
||||
| 舊腳本升級撞 404(1.9.1) | ① 發佈源保留 `template/.claude/VERSION` 相容墊片 ② 新腳本驗 REMOTE_VER 須像版號 | 1.8.x 舊腳本寫死抓舊 VERSION 路徑,搬走後 curl 回「404」字串、被當內容寫進 VERSION;墊片讓舊腳本不 404,格式驗證讓未來任何路徑變動都不污染 VERSION。**bump 時兩個 VERSION 檔須同步**(system-dev/VERSION 權威 + .claude/VERSION 墊片) | 不留墊片(舊用戶撞 404);只靠 README 改 curl(救不了已跑本機舊腳本的人) |
|
||||
| CLAUDE.md 等用戶檔遷移後仍寫舊路徑(1.9.2) | session-start hook 偵測 + 提示 CC 代修 | 遷移搬檔案位置,但 update.sh 鐵則「絕不碰 CLAUDE.md」(用戶資料)→ CLAUDE.md 內 `.claude/wiki` 變死引用,CC 照它找錯位置。讓腳本盲 sed 改用戶 CLAUDE.md 風險高(可能誤傷用戶自寫內容、破壞鐵則),改由 CC(懂語義、知道 raw source 的 `docs/` 要保留)代改 | 腳本自動 sed 改(誤傷風險 + 破鐵則);只寫 README(low-code 用戶不看) |
|
||||
| 重複 install 製造 wiki 並存(1.10.1) | **職責切分:install 只管「全新安裝」,一切已裝過的後續(更新/遷移/補新檔)歸 update。** ① install 偵測「裝過沒」(system-dev/ 或 .claude/wiki/ 或 .claude/VERSION 任一存在,不分新舊版)→ 不動任何東西,導去 update 並 exit ② update 的 migrate_dir:目的地已存在但舊位置仍有真資料 → 記 COEXIST 警告「並存需合併」,不靜默跳過、不自動合併 ③ install↔update 互相導向(update 遇全新專案也導回 install),閉環無死結 | 根因不是「舊結構」而是「重複 install」:判準該是裝過沒、不是哪個版本。用戶先 install(建空殼)→ 再 update(遷移被冪等擋掉)→ 真資料卡舊位置、空殼佔新位置、並存。切乾淨職責後,install 永不在已裝專案動手,從源頭杜絕並存 | 只擋舊結構(新版重裝照樣亂);腳本自動合併(覆蓋風險);migrate 靜默跳過(並存無聲、用戶不知資料分裂) |
|
||||
|
||||
### 介面定義:遷移行為(雙保險)
|
||||
|
||||
**第 1 層 — update.sh 自動遷移(冪等)**
|
||||
- 偵測舊位置存在 → 搬到 system-dev/:
|
||||
- `.claude/wiki/` → `system-dev/wiki/`(含 cards/、含 wiki/.git,用保留 .git 的搬法)
|
||||
- `.claude/VERSION` → `system-dev/VERSION`
|
||||
- 根 `docs/` 中**工具自己鋪的白名單路徑**(README.md、SKILL.md、3-specs/、2-architecture/、1-vision/、4-guides/、5-records/、6-user/)→ `system-dev/docs/`
|
||||
- **用戶自填的 docs 內容不搬**(白名單外的一律不動)
|
||||
- system-dev/ 已存在對應檔 → 略過(可重複跑)
|
||||
- 印出「已遷移 X → system-dev/」
|
||||
|
||||
**第 2 層 — session-start-recall.sh 自我防呆**
|
||||
- 開 session 檢查舊路徑 `.claude/wiki/` 是否還在:
|
||||
- 在 → 印「⚠️ 偵測到舊結構未遷移,跑 update.sh 或叫 CC 幫你遷移」
|
||||
- CC 見此訊息即知該遷,可當場用檔案工具搬
|
||||
|
||||
### 資料模型:受影響路徑引用清單
|
||||
|
||||
| 檔案 | 改動類別 |
|
||||
|------|---------|
|
||||
| scripts/install.sh | create_dir/download 落點 docs/→system-dev/docs/、wiki→system-dev/wiki/、VERSION、新增 cards/、scripts/ 落點 |
|
||||
| scripts/update.sh | update_file/keep_file 路徑、自我更新路徑、VERSION 讀點、**新增遷移段** |
|
||||
| template/CLAUDE.md + 根 CLAUDE.md | 鐵律/速查表/wiki 讀取表路徑;raw source 宣告維持 |
|
||||
| template/docs/SKILL.md | cards/ 落點 → system-dev/wiki/cards/;raw source 偵測語義維持 |
|
||||
| .claude/commands/wiki-init.md(+template) | cards/ 落點、工具 docs 示意、SKILL 引用;raw source 偵測維持 |
|
||||
| .claude/commands/wiki-capture.md、sdd-check.md(+template) | docs/2-architecture、docs/3-specs → system-dev/docs/ |
|
||||
| .claude/hooks/sdd-guard.sh(+template) | 7 處 docs/3-specs → system-dev/docs/3-specs |
|
||||
| .claude/hooks/session-start-recall.sh | STATUS_FILE 路徑 + 新增防呆檢查 |
|
||||
| .claude/wiki/INDEX.md、decisions-summary.md(+template) | docs/2-architecture 引用 |
|
||||
| README.md、README.en.md | 目錄樹示意、安裝後說明 |
|
||||
|
||||
---
|
||||
|
||||
## 技術限制
|
||||
|
||||
- **bash 3.2 相容**(macOS 內建):腳本改動後必須 `bash -n` 過,且多位元組字元旁變數一律 `${VAR}` 包好(1.7.0/1.8.2 崩潰教訓)。
|
||||
- **不可破壞 wiki/.git**:實機 KB 的 wiki 自帶獨立 git repo(192 張卡),遷移時用保留 .git 的搬法。
|
||||
- **必須相容 CC 原生機制**:commands/hooks/settings.json/CLAUDE.md 路徑不可違反 CC 載入慣例。
|
||||
- **遷移必須冪等**:update.sh 可被重複跑(含「以為沒更新再跑一次」)而不出錯。
|
||||
- **curl | bash 串流安全**:update.sh/install.sh 走遠端串流執行,不可在多位元組邊界出 unbound variable。
|
||||
|
||||
---
|
||||
|
||||
## 驗收標準
|
||||
|
||||
完成的定義:
|
||||
- [ ] 新裝(install.sh):根目錄只出現 `.claude/` + `CLAUDE.md`,其餘全在 `system-dev/`;`system-dev/wiki/cards/` 存在且有 .gitkeep。
|
||||
- [ ] `system-dev/VERSION` 存在且 .claude/ 下無 VERSION。
|
||||
- [ ] 舊用戶跑 update.sh:舊 `.claude/wiki/`、根工具 `docs/`、`scripts/` 自動遷入 system-dev/,wiki/.git 完好,可重複跑不出錯。
|
||||
- [ ] 未遷移用戶開 session:hook 印出防呆提示,不默默失敗。
|
||||
- [ ] 所有路徑引用無殘留死連結(grep 不到非 raw-source 語義的舊 `docs/3-specs`、`.claude/wiki` 寫死路徑)。
|
||||
- [ ] raw source 語義引用維持指向用戶原始文件(未被誤改成 system-dev/)。
|
||||
- [ ] `bash -n` 通過 install.sh 與 update.sh。
|
||||
- [ ] 實機 KB 套用後:開 session 接關正常、/wiki-init 寫入 system-dev/wiki/cards/、192 張卡與其 .git 完整。
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- memory: user-profile-lowcode(目標用戶輪廓)
|
||||
- memory: sdd-rule-applies-to-this-repo(本 repo 也守 SDD 鐵律)
|
||||
- 前置 hotfix:1.8.2(update.sh bash 3.2 崩潰修復,已 push)
|
||||
- 前置:1.8.1(補裝 Cowork SKILL.md,已 push)
|
||||
@@ -0,0 +1,87 @@
|
||||
# install-layout — Tasks
|
||||
|
||||
> 權威來源:此檔案是進度真相,不是 CLAUDE.md 或對話。
|
||||
> 規則:動手前標 [🔄],完成立刻標 [x],不批次更新。
|
||||
|
||||
---
|
||||
|
||||
## Phase 1:腳本核心(install / update + 遷移)
|
||||
|
||||
### 前置條件
|
||||
- [x] design.md 已審核(用戶批准)
|
||||
|
||||
### Tasks
|
||||
|
||||
- [x] 1.1 install.sh:docs/ create_dir+download 落點全改 system-dev/docs/
|
||||
- 驗收:✅ grep 無殘留;raw source 偵測段 `RAW_SOURCE="docs/"` 正確保留
|
||||
- [x] 1.2 install.sh:.claude/wiki/* 與 .claude/VERSION 落點改 system-dev/
|
||||
- 驗收:✅ 落點全 system-dev/;新增 system-dev/VERSION download
|
||||
- [x] 1.3 install.sh:新增 create_dir system-dev/wiki/cards + 寫 .gitkeep
|
||||
- 驗收:✅ 已加 create_dir + .gitkeep 寫入
|
||||
- [x] 1.4 install.sh:scripts 落點改 system-dev/scripts/(一開始就裝)
|
||||
- 驗收:✅ 加 SCRIPTS_URL + download install/update 到 system-dev/scripts/
|
||||
- [x] 1.5 update.sh:所有路徑改 system-dev/(wiki/docs/scripts/VERSION)
|
||||
- 驗收:✅ grep 無殘留;bash -n 過;commands/hooks 正確留 .claude/
|
||||
- [x] 1.6 update.sh:新增冪等遷移段(舊位置→system-dev/,保留 wiki/.git,白名單只搬工具 docs)
|
||||
- 驗收:✅ 沙盒測試全綠——wiki(含.git commit一致)/VERSION/SKILL/docs 搬移正確、冪等(第二次0項)、用戶自填 docs 保留
|
||||
- [x] 1.7 兩腳本 bash -n + 多位元組旁變數 ${} 包好
|
||||
- 驗收:✅ install.sh + update.sh bash -n 通過
|
||||
|
||||
---
|
||||
|
||||
## Phase 2:路徑引用同步(.md / .sh)
|
||||
|
||||
> 前置條件:Phase 1 完成
|
||||
|
||||
- [x] 2.1 CLAUDE.md(template + 根):鐵律/速查/wiki 讀取表路徑;raw source 宣告維持
|
||||
- [x] 2.2 SKILL.md(template + 根):cards/ 落點改 system-dev/wiki/cards/;raw source 偵測維持
|
||||
- [x] 2.3 wiki-init.md(.claude + template):cards/、工具 docs 示意、SKILL 引用;raw source 偵測維持
|
||||
- [x] 2.4 wiki-capture.md / sdd-check.md(.claude + template):docs/ → system-dev/docs/
|
||||
- [x] 2.5 sdd-guard.sh(.claude + template):7 處 docs/3-specs → system-dev/docs/3-specs
|
||||
- [x] 2.6 session-start-recall.sh:STATUS_FILE 路徑 + 新增防呆檢查
|
||||
- [x] 2.7 INDEX.md / decisions-summary.md(.claude + template):docs/2-architecture 引用
|
||||
- [x] 2.8 README.md / README.en.md:目錄樹示意 + 安裝後說明
|
||||
- 驗收(2.1–2.8):全 repo grep 無殘留非 raw-source 語義的舊路徑;raw source 引用未被誤改
|
||||
|
||||
---
|
||||
|
||||
## Phase 3:版本、文件、提交
|
||||
|
||||
> 前置條件:Phase 1+2 完成、bash -n 過
|
||||
|
||||
- [x] 3.1 bump template/.claude/VERSION → 1.9.0(注意:VERSION 檔本身也要隨結構搬到 system-dev/,但發佈源 template 內的相對位置同步調整)
|
||||
- [x] 3.2 CHANGELOG 記 1.9.0(結構重構 + 遷移行為)
|
||||
- [x] 3.3 commit(先不 push,等實機驗證)
|
||||
|
||||
---
|
||||
|
||||
## Phase 4:實機 KB 套用與驗證
|
||||
|
||||
> 前置條件:Phase 1–3 完成;用戶點頭才動實機
|
||||
|
||||
- [ ] 4.1 KB:.claude/wiki/(含 192 卡 + .git)搬 system-dev/wiki/,保留 .git
|
||||
- 驗收:192 張卡與 wiki/.git 完整,git log 不斷
|
||||
- [ ] 4.2 KB:.claude/VERSION、根工具 docs 搬 system-dev/;用戶自有 docs 不動
|
||||
- [ ] 4.3 KB:開 session 接關正常、/wiki-init 寫入 system-dev/wiki/cards/
|
||||
- 驗收:hook 接關輸出正常、無防呆警告(表示已遷移完成)
|
||||
|
||||
---
|
||||
|
||||
## 完成定義
|
||||
|
||||
整個 SDD 完成 = 以下全部達成:
|
||||
- [ ] 所有 tasks 標 [x]
|
||||
- [ ] design.md 驗收標準全通過(有客觀證據)
|
||||
- [ ] design.md 與實作一致
|
||||
|
||||
---
|
||||
|
||||
## 狀態說明
|
||||
|
||||
| 標記 | 意義 |
|
||||
|------|------|
|
||||
| `[ ]` | 未開始 |
|
||||
| `[🔄]` | 進行中(當前 session)|
|
||||
| `[x]` | 完成(有驗收證據)|
|
||||
| `[~]` | 暫緩(說明原因)|
|
||||
| `[!]` | 阻擋中(說明阻擋原因)|
|
||||
@@ -0,0 +1,416 @@
|
||||
---
|
||||
status: draft # active | draft | paused | closed(生命週期鐵律見 ../SDD-LIFECYCLE.md)
|
||||
superseded_by: "" # closed 且被取代時填接替的 SDD 資料夾名
|
||||
---
|
||||
|
||||
# jdd-dual-profile — Design
|
||||
|
||||
> 建立:2026-08-05 | 最後更新:2026-08-05
|
||||
> 負責人:system-dev-template CC
|
||||
> 來源:InkStoneCo 總管交辦 **W2**
|
||||
> **狀態:draft — 等 leo confirm 才升 active,未實作任何 code**
|
||||
>
|
||||
> 為什麼是 `draft` 而非 `active`:D35 ②③ 規定 CC 不得自行讓 SDD 生效;
|
||||
> 本 repo 目前 **0 份 active**(見「現況實查」§0.1),本案 confirm 後直接升 active,
|
||||
> 不需搬移任何未完成任務(無現任 active 可搬)。
|
||||
|
||||
---
|
||||
|
||||
## 一句話說明
|
||||
|
||||
把 system-dev-template 從「單一 repo 級框架」改造成 **雙 profile 框架(總管級/repo 級)**,
|
||||
並在其上裝入 **JDD PM 軌**(root.md/journeys.md/站號 sprint/角色權限封路),
|
||||
讓「憲法分流」「角色權限」「實例不改機制」三件事全部由**檔案結構與 hook 機械決定**,
|
||||
沒有任何一格靠 agent 自我判斷。
|
||||
|
||||
---
|
||||
|
||||
## 0. 現況實查(動手前先搞清楚現在長什麼樣)
|
||||
|
||||
> 本節是設計的事實基礎,也是「與規格假設不符」的清單來源。每條都是本次實測,不是回憶。
|
||||
|
||||
### 0.1 SDD 現況
|
||||
|
||||
- `docs/3-specs/` 下 5 個資料夾,**帶 frontmatter 的只有 `TEMPLATE-sdd`(status: draft)**。
|
||||
`cross-repo-signing` / `install-layout` / `wiki-architecture` / `tasks-project-projection`
|
||||
四份都只在正文寫「狀態:已採納/已結案」,**沒有 frontmatter** ⇒ 機器查得到的 `active` 數 = **0**。
|
||||
- 本 repo 的 SDD 住 `docs/3-specs/`,但它發給別人的 `sdd-guard.sh` 與 `sdd-active-check.sh`
|
||||
預設路徑是 `system-dev/docs/3-specs` ⇒ **框架 repo 的 D35 閘從來沒對自己開過火**。
|
||||
- 現有 SDD 的實際慣例是 **design.md + tasks.md 兩件式**(`TEMPLATE-sdd` 也只有這兩支),
|
||||
`requirements.md` 在本 repo **沒有先例**。本案依交辦要求補齊三件式。
|
||||
|
||||
### 0.2 安裝機制現況
|
||||
|
||||
| 事實 | 影響本設計的地方 |
|
||||
|---|---|
|
||||
| `install.sh` 逐檔 `download_if_missing "<dest>" "$REPO_URL/<path>"`,**沒有 manifest**,檔案清單硬編在腳本裡 | 加 profile ⇒ 清單要分四份(common/repo/orchestrator/模組交叉),硬編必然漂移 → **必須先做 manifest** |
|
||||
| `update.sh` 另有一份**幾乎重複**的清單(update_file/keep_file/add_if_missing/keep_with_template 四類) | 同上;manifest 的「類別」欄正好就是這四類 |
|
||||
| `REPO_URL = $TEMPLATE_SOURCE/template`,所有安裝產物的遠端路徑都掛在 `template/` 底下 | 分離 §三把 `common/`、`profiles/` 畫在 repo 根 ⇒ 會變成第二個 base URL;本設計改掛 `template/` 底下(見決策 D2) |
|
||||
| `update.sh` 的**自我更新在腳本尾端**(先跑完所有下載才更新自己) | 若這一版搬動既有檔案路徑,舊實例這一輪會整排 404;1.16.0 已被同型問題咬過(來源改動=自動更新死掉)⇒ **既有檔一律不搬**(決策 D3) |
|
||||
| `CLAUDE.md` 是整份下載 + `emit_raw_source_block` append,**沒有任何區段界標** | 「本地補充區」目前不存在邊界,漂移偵測無從談起 ⇒ 必須先立界標(設計 §2) |
|
||||
| `build_hooks_json()` 依模組(wiki/sdd)條件組裝 settings.json | profile 只是加第三個維度,**沿用同一支函式**,不另造 |
|
||||
|
||||
### 0.3 hook 現況(template 內共 7 支)
|
||||
|
||||
`pre-write-guard.sh`(空殼,`FORBIDDEN_PATTERNS` 為空=不攔任何東西)、`publish-lag-check.sh`、
|
||||
`sdd-guard.sh`、`session-start-recall.sh`、`subagent-wiki-guard.sh`、`wiki-first-search.sh`、
|
||||
`wiki-secret-scan.sh`。
|
||||
|
||||
- **`AGENT_ROLE` 在整個 repo 與 InkStoneCo 實例中 0 次出現** ⇒ 角色軸完全從零開始。
|
||||
- **`guard-cross-project.sh` 不在 template 裡**——它只存在於 InkStoneCo 實例的 `.claude/hooks/`。
|
||||
分離 §六.4 標它 `[修改]`,實際動作是「**從實例上收進框架**」,不是就地改(決策 D6)。
|
||||
- 同理,`delivery-police.sh`/`self-drive-police.sh`/`unpushed-police.sh`/`history-first-guard.sh`
|
||||
等 **11 支都是實例自行發明的**,框架不知道它們存在。
|
||||
|
||||
### 0.4 漂移基線(機械閘 #3 的今日實測值)
|
||||
|
||||
比對 InkStoneCo 實例的 `.claude/hooks/` 與本 repo `template/.claude/hooks/`:
|
||||
|
||||
| 狀態 | 數量 | 檔 |
|
||||
|---|---|---|
|
||||
| 與框架一致 | 2 | `session-start-recall.sh`、`wiki-secret-scan.sh` |
|
||||
| **已被手改(漂移)** | **4** | `pre-write-guard.sh`、`sdd-guard.sh`、`subagent-wiki-guard.sh`、`wiki-first-search.sh` |
|
||||
| 實例自行發明 | 11 | 見 §0.3 |
|
||||
|
||||
⇒ **今天沒有任何機制知道這 4 支已經漂移**。這就是分離 §八 預測②(「漂移數歸零」)的基線值 = 4。
|
||||
|
||||
### 0.5 實例專名基線(機械閘 #2 的今日實測值)
|
||||
|
||||
`template/` 底下命中 `arcrun|mira|leo21c|inkstone|uncle6|polaris`:**8 檔 20 行**。分三類:
|
||||
|
||||
| 類 | 內容 | 處置 |
|
||||
|---|---|---|
|
||||
| (a) 註解/舉例(6 行) | `sdd-guard.sh`「誠實限制(抄 arcrun)」、`publish-lag-check.sh` 的 jsDelivr 例、`logseq-markers.md` 的 TODO 例句、`issue-handle.md` 的 repo 名清單 | **本波清理**(改寫成通用敘述) |
|
||||
| (b) 政策內容混進框架(3 行) | `subagent-wiki-guard.sh`「有 Arcrun RAG MCP 就用它」、`wiki-extract.md`「下游 Arcrun ingest」 | **標逐行豁免,W3 隨 policy pack 搬走** |
|
||||
| (c) 整支是 L2 產物(13 行) | `system-dev/workflows/tasks-project-sync.{yaml,local.sh}`(本體就是 arcrun workflow) | **整組標豁免,W3 移入 policy pack** |
|
||||
|
||||
⇒ 閘 #2 **不能一上線就全紅**。必須配「逐行豁免標記 + 基線報表」,否則為了讓 CI 綠會出現
|
||||
假性清理(把 arcrun 換成「某工作流引擎」=資訊消失但問題還在)。
|
||||
|
||||
---
|
||||
|
||||
## 範圍
|
||||
|
||||
### 包含(In Scope)
|
||||
|
||||
- template 的雙 profile 化(宣告式,非搬檔):manifest、`--profile`、profile 專屬產物
|
||||
- CLAUDE.md 生成、框架區/本地補充區界標、update 漂移偵測
|
||||
- JDD 文件範本:`root.md`、`journeys.md`(含站點索引表)、站號 sprint 範本、術語表
|
||||
- 兩軸身分(scope × role)的機械判定函式庫
|
||||
- JDD §六 8 條封路規則 + 分離 §六 4 條防糾纏閘的實作
|
||||
- policy plugin 的**插槽**:載入順序文件化 + profile 憲法 must-read 注入點
|
||||
- CHANGELOG + VERSION bump + 乾淨環境雙 profile 安裝實測
|
||||
|
||||
### 不包含(Out of Scope)
|
||||
|
||||
- **arcrun-policy plugin 本體**(W3):`plugin.json`、marketplace 發行、白名單 hook 內容、
|
||||
primer/dispatch-checklist 搬遷、`.mcp.json`
|
||||
- **實例側落地**(W4):InkStoneCo 的 root.md/journeys.md 實填、routine 取任務源改站號、
|
||||
實例 11 支自製 hook 的退役與上收
|
||||
- **雲端側**(W5):LLM Wiki 總編輯管線、儀表 job、`arch_baseline`/`arch_iteration` 卡
|
||||
- **記憶階梯改序(KBDB-first)**:藍圖 §7,屬另一波
|
||||
- **既有 SDD 的 frontmatter 補齊**(§0.1 撿到的斷層):本波只回報,不順手改——
|
||||
那會動到四份別的 SDD 的生命週期狀態,屬規格層,另走 pending-changes
|
||||
|
||||
---
|
||||
|
||||
## 1. 架構總覽
|
||||
|
||||
```
|
||||
system-dev-template/ ← 框架 repo(本 repo)
|
||||
├─ scripts/install.sh --profile=repo|orchestrator ← 改造:讀 manifest
|
||||
├─ scripts/update.sh ← 改造:讀 manifest + 漂移偵測
|
||||
├─ scripts/check-no-instance-names.sh ← 新增:機械閘 #2(CI)
|
||||
├─ scripts/instance-names.txt ← 新增:黑名單設定檔
|
||||
└─ template/ ← 所有安裝產物的遠端根($REPO_URL)
|
||||
├─ manifest/
|
||||
│ ├─ common.tsv ← 新增:兩 profile 共裝
|
||||
│ ├─ repo.tsv ← 新增:repo profile 專屬
|
||||
│ └─ orchestrator.tsv ← 新增:orchestrator profile 專屬
|
||||
├─ .claude/hooks/… ← 既有 7 支【原地不動】= common 的實體
|
||||
│ ├─ lib/role-lib.sh ← 新增:兩軸判定函式庫(被 source)
|
||||
│ ├─ role-guard.sh ← 新增:J1+J2+J3
|
||||
│ ├─ jdd-format-guard.sh ← 新增:J4+J5+J8
|
||||
│ ├─ station-done-guard.sh ← 新增:J6
|
||||
│ ├─ regression-scope.sh ← 新增:J7
|
||||
│ └─ install-artifact-guard.sh ← 新增:S1
|
||||
├─ profiles/
|
||||
│ ├─ repo/
|
||||
│ │ ├─ CLAUDE.md ← repo 憲法範本(=現行 template/CLAUDE.md 演進)
|
||||
│ │ └─ (SDD 三件式、repo wiki 規範:沿用 common 既有產物,manifest 宣告即可)
|
||||
│ └─ orchestrator/
|
||||
│ ├─ CLAUDE.md ← 總管憲法範本(藍圖 v3 指針+術語表)
|
||||
│ ├─ docs/root.md.template
|
||||
│ ├─ docs/journeys.md.template
|
||||
│ ├─ docs/sprint.md.template ← 站號 sprint
|
||||
│ ├─ docs/triage-map.md.template ← 格式範本,內容留實例
|
||||
│ ├─ docs/plugin-load-order.md ← 載入順序文件(W3 插槽)
|
||||
│ └─ hooks/orchestrator-scope-guard.sh ← 新增:S4(上收 guard-cross-project)
|
||||
└─ system-dev/… ← 既有【原地不動】
|
||||
|
||||
實例安裝後:
|
||||
CLAUDE.md ← 框架區(profile 範本)+ 本地補充區(界標分隔)
|
||||
system-dev/.profile ← 單行:repo | orchestrator(scope 軸唯一來源)
|
||||
system-dev/.template-manifest ← 每個產物的 path / version / sha256(漂移偵測依據)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 設計答案①:雙 profile 的 CLAUDE.md 怎麼生成、本地補充區邊界、漂移怎麼偵測
|
||||
|
||||
### 2.1 生成:組裝而非下載
|
||||
|
||||
現行是「整份下載 `template/CLAUDE.md` + append raw source 區塊」。改為三段組裝:
|
||||
|
||||
```
|
||||
<!-- sdt:framework begin profile=<repo|orchestrator> version=1.19.0 sha256=<前12碼> -->
|
||||
(profiles/<profile>/CLAUDE.md 的完整內容,一字不改)
|
||||
<!-- sdt:framework end -->
|
||||
|
||||
<!-- sdt:local begin — 這一區是你的,update 永遠不會動它 -->
|
||||
(install 產生的 raw source 宣告;之後由使用者/CC 自由追加)
|
||||
<!-- sdt:local end -->
|
||||
```
|
||||
|
||||
- 界標用 HTML 註解:md 渲染看不見、CC 讀得到、`grep -n` 定位得到。
|
||||
- `sha256` 記的是**框架區內容本身**(不含界標行),是漂移偵測的比對基準。
|
||||
- 兩區順序固定:框架區在上(agent 先讀到憲法),本地區在下。
|
||||
|
||||
### 2.2 兩份 profile 憲法的內容分界(G4 的判準)
|
||||
|
||||
| | `profiles/repo/CLAUDE.md` | `profiles/orchestrator/CLAUDE.md` |
|
||||
|---|---|---|
|
||||
| 效忠文件 | `requirements.md`(SDD 技術軌) | `root.md` + `journeys.md`(PM 軌) |
|
||||
| 含 SDD 三件式細節 | ✅ 含(現行內容) | ❌ **不含**(G4 明文:總管版無 SDD 三件式細節) |
|
||||
| 上游指針 | ✅ 一行(指向總管 repo 的憲法位置,**不寫死專案名**,由 install 問一次或留空) | ❌ 無(它自己就是上游) |
|
||||
| JDD 術語表 | 只放「站號怎麼標在 task 上」一段 | 全表(Journey/Station/通關/點亮/對帳/完備) |
|
||||
| sprint 機制 | 「認領 loop」段(engineer 的動作) | 全流程(指定站 → 認領 → 新增必掛站 → 收尾判準) |
|
||||
| 角色 | engineer(可寫 code/tasks/requirements/design;禁改考卷) | orchestrator(可寫 root/journeys/sprint;禁寫 code、禁改 tasks) |
|
||||
|
||||
> G4 的機械驗法:`grep -c "SDD 三件式\|requirements.md" CLAUDE.md`
|
||||
> 在 orchestrator 實例上 = 0;`grep -c "上游" CLAUDE.md` 在 repo 實例上 ≥ 1。
|
||||
|
||||
### 2.3 邊界規則(寫進兩份憲法,並由 hook 兌現)
|
||||
|
||||
1. **框架區唯讀**:任何內容變更走框架 repo 提案 → bump → update 拉下來。
|
||||
2. **本地補充區隨便寫**:update 永不讀、永不寫、永不比對。
|
||||
3. 實例要覆寫框架區的某條規則 → 不准就地改,**在本地補充區寫「例外聲明 + 理由 + 日期」**。
|
||||
這樣 diff 永遠乾淨,而例外仍然留痕可審。
|
||||
|
||||
### 2.4 漂移偵測:manifest + sha256
|
||||
|
||||
`system-dev/.template-manifest`(install 產生,update 維護),TSV 一行一產物:
|
||||
|
||||
```
|
||||
<dest 路徑> <class> <安裝時 version> <安裝時 sha256>
|
||||
```
|
||||
|
||||
`class` 沿用 update.sh 既有四類語意:`overwrite`(模板/邏輯檔)/`keep`(使用者資料檔)/
|
||||
`add-if-missing`(新資料檔)/`keep-with-template`(使用者會手填的客製檔)。
|
||||
|
||||
update 對每個 `overwrite` 類產物跑三態判定:
|
||||
|
||||
| 實檔 sha vs manifest sha | 遠端 sha vs manifest sha | 判定 | 動作 |
|
||||
|---|---|---|---|
|
||||
| 相同 | 相同 | 沒變 | **no-op**(不下載、不列報表)← 兌現 EARS-1.2.2 |
|
||||
| 相同 | 不同 | 乾淨、有新版 | 覆蓋,列「已更新」 |
|
||||
| **不同** | 任意 | **漂移** | **不覆蓋**;新版另存 `<檔>.new`;列入 ⚠️ 漂移清單 |
|
||||
|
||||
漂移清單的輸出格式(白話,leo 讀得懂):
|
||||
|
||||
```
|
||||
⚠️ 下列 3 個檔被手改過,這一版沒有覆蓋它們:
|
||||
.claude/hooks/sdd-guard.sh → 新版已放在 sdd-guard.sh.new,請 diff
|
||||
你可以:① 把你的改動寫成框架提案(推薦,一次修全家)
|
||||
② 放棄本地改動:mv sdd-guard.sh.new sdd-guard.sh
|
||||
```
|
||||
|
||||
**舊實例遷移(沒有 manifest 的 1.18.x)**:update 偵測到無 manifest → 進「一次性補植」:
|
||||
以本版遠端內容為基準建 manifest,**凡當下與遠端不一致者一律先標成漂移**(保守:寧可多報不漏報),
|
||||
並把現有 `CLAUDE.md` 整份包進 `sdt:local` 區、框架區從 profile 重鋪,
|
||||
輸出「你的舊 CLAUDE.md 已完整保留在本地補充區,請自行搬移重複段落」。整段冪等,重跑不再動。
|
||||
|
||||
---
|
||||
|
||||
## 3. 設計答案②:AGENT_ROLE 兩軸身分在 hook 裡怎麼機械判定
|
||||
|
||||
### 3.1 兩個來源,零自陳
|
||||
|
||||
| 軸 | 來源 | 誰寫 | 讀不到時 |
|
||||
|---|---|---|---|
|
||||
| **scope** | `system-dev/.profile`(單行 `repo`/`orchestrator`) | install.sh(`--profile` 或偵測+人確認一次) | 視為 `repo`(多數實例;且此時 orchestrator 專屬閘不觸發,仍有 common 閘在) |
|
||||
| **role** | 環境變數 `AGENT_ROLE`(`orchestrator`/`engineer`) | ① install 依 profile 寫進 `.claude/settings.json` 的 `env` 當預設<br>② 派工端 spawn subagent 時注入<br>③ 人工 override | **依 scope 推定**:orchestrator profile → `orchestrator`;repo profile → `engineer` |
|
||||
|
||||
> 為什麼 scope 不放 `settings.json`:settings.json 是「使用者資料檔」,update 永不覆蓋,
|
||||
> 而且 CI/獨立腳本也要讀得到。`system-dev/.profile` 與 `VERSION` 同層,一致且好找。
|
||||
|
||||
### 3.2 身分矩陣(含那個不存在的格子)
|
||||
|
||||
| | `AGENT_ROLE=orchestrator` | `AGENT_ROLE=engineer` |
|
||||
|---|---|---|
|
||||
| **orchestrator profile** | PM 本尊 ✅ | 總管 repo 裡的技術 subagent ✅ |
|
||||
| **repo profile** | **❌ 不存在** → exit 2,要求修正環境 | 寫 code 的 subagent ✅ |
|
||||
|
||||
「repo profile × orchestrator」被攔的訊息要說清楚:成員 repo 沒有 PM——
|
||||
要 PM 的動作請回總管 repo 做(分離 §二「空格也是封路」)。
|
||||
|
||||
### 3.3 `lib/role-lib.sh`(common,被 source 不獨立掛)
|
||||
|
||||
```bash
|
||||
sdt_repo_root() # 由 ${BASH_SOURCE} 往上找,不假設 CLAUDE_PROJECT_DIR(雲端可跑)
|
||||
sdt_rel_path "$f" # 絕對/相對 → repo 相對路徑(抄 guard-cross-project 的 case 寫法)
|
||||
sdt_scope() # 讀 system-dev/.profile,trim;讀不到回 repo
|
||||
sdt_role() # 讀 $AGENT_ROLE;空 → 依 sdt_scope 推定
|
||||
sdt_assert_identity() # 檢查矩陣空格,命中 → 印訊息 exit 2
|
||||
sdt_file_path_from_stdin # 統一的 JSON 解析(jq → python3 → grep 三段 fallback)
|
||||
```
|
||||
|
||||
**為什麼是函式庫不是 hook**:六支新 hook 都要做同樣四件事(解析 JSON、算相對路徑、判 scope、判 role)。
|
||||
各寫一份=四處維護同一條規則,正是分離 §六.4 要避免的病。
|
||||
|
||||
### 3.4 為什麼角色 hook 屬 common,不按規格放進各自 profile
|
||||
|
||||
分離 §三把 `engineer 角色 hooks` 畫在 `profiles/repo/`、`orchestrator 角色 hooks` 畫在
|
||||
`profiles/orchestrator/`。**照做會漏一格**:總管 repo 裡也會 spawn engineer subagent
|
||||
(矩陣右上角),若 engineer 的封路 hook 只裝在 repo profile,那顆 subagent 在總管 repo 裡
|
||||
**改得動 journeys.md** ⇒ G2「考生改考卷被攔截」在最該生效的地方失效。
|
||||
|
||||
⇒ 本設計改為:**role 軸的 hook 全部屬 common(兩 profile 都裝),scope 軸的 hook 才按 profile 分**。
|
||||
唯一 scope 專屬的是 `orchestrator-scope-guard.sh`(總管禁入成員 repo 寫實作)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 設計答案③:12 條規則落成哪些 hook(改既有 vs 新增)
|
||||
|
||||
> **規則數 ≠ 檔案數**。J1/J2/J3 都是「PreToolUse Write|Edit 依 role×path 判定」,
|
||||
> 拆三支=三次解析同一包 JSON、三處維護同一張路徑表。合併為一支、規則編號保留在程式碼註解與訊息裡。
|
||||
|
||||
### 4.1 JDD §六 八條
|
||||
|
||||
| 規則 | 內容 | 落點 | 既有/新增 |
|
||||
|---|---|---|---|
|
||||
| J1 | orchestrator 寫 `src/**`、`*.py`、`*.ts`… → 攔 | `role-guard.sh` | **新增**(規格說「既有 hook 已涵蓋則跳過」——已確認 `pre-write-guard.sh` 是空殼且不認 role,**不涵蓋**) |
|
||||
| J2 | orchestrator 寫 `tasks.md`/`requirements.md`/`design.md` → 攔 | `role-guard.sh` | 新增(同上) |
|
||||
| J3 | engineer 寫 `journeys.md`/`root.md`/`*.feature`/md 內 Gherkin 區塊 → 攔(**命門**) | `role-guard.sh` | 新增 |
|
||||
| J4 | `root.md` 🔴 卡缺【要驗證+對帳日】→ 攔 | `jdd-format-guard.sh` | 新增 |
|
||||
| J5 | `tasks.md` **新增**的 task 缺站號 → 攔 | `jdd-format-guard.sh` | 新增 |
|
||||
| J6 | sprint 收尾判準:tasks 全關 → **指定站 Gherkin 全過** | `station-done-guard.sh` | **新增**(規格標 `[修改]`,但 template 內**沒有**任何 sprint 收尾 hook——`delivery-police.sh` 只存在於 InkStoneCo 實例 ⇒ 對框架而言是新增,見決策 D6) |
|
||||
| J7 | 站相關實作變動 → 查站點索引表 → 列重考清單 | `regression-scope.sh` | 新增(提醒不擋) |
|
||||
| J8 | `root.md`/`journeys.md` 出現技術名詞 → 警告/攔 | `jdd-format-guard.sh` | 新增 |
|
||||
|
||||
### 4.2 分離 §六 四條
|
||||
|
||||
| 閘 | 內容 | 落點 | 既有/新增 |
|
||||
|---|---|---|---|
|
||||
| S1 | 實例寫入安裝產物區 → 攔;`--framework-dev` 例外 | `install-artifact-guard.sh` | 新增 |
|
||||
| S2 | 框架範本混入實例專名 → CI fail | `scripts/check-no-instance-names.sh`(**非 hook**) | 新增 |
|
||||
| S3 | update 漂移偵測 | `update.sh` + `.template-manifest` | **改既有腳本** |
|
||||
| S4 | guard-cross-project 職責不重疊 | `profiles/orchestrator/hooks/orchestrator-scope-guard.sh` | **新增於框架**(實體改寫自實例那支,見 D6) |
|
||||
|
||||
### 4.3 既有檔改動清單
|
||||
|
||||
| 檔 | 改什麼 | 為什麼 |
|
||||
|---|---|---|
|
||||
| `template/.claude/hooks/session-start-recall.sh` | 依 `sdt_scope()` 分流注入:orchestrator → root/journeys 摘要 + 本 sprint **未點亮**站;repo → 現行 principles/status/mistakes | 唯一真正的「改既有 hook」;藍圖 §0「routine 起牀讀站號」的落點 |
|
||||
| `scripts/install.sh` | 加 `--profile`、自動偵測+人確認、改讀 manifest、產 `.profile`/`.template-manifest`、CLAUDE.md 三段組裝、`build_hooks_json()` 加 profile 維度與 `env.AGENT_ROLE` | E1 主體 |
|
||||
| `scripts/update.sh` | 改讀 manifest、三態判定、漂移報表、舊實例 marker 補植遷移 | S3 + EARS-1.2.2 |
|
||||
| `template/CLAUDE.md` | 演進為 `template/profiles/repo/CLAUDE.md`;**原路徑保留一份轉址說明**,避免舊 update.sh 404 | D3 向下相容 |
|
||||
| §0.5 (a) 類 6 行註解 | 改寫成通用敘述 | S2 前置清潔 |
|
||||
|
||||
**合計:新增 hook 6 支**(`role-guard`、`jdd-format-guard`、`station-done-guard`、
|
||||
`regression-scope`、`install-artifact-guard`、`orchestrator-scope-guard`)
|
||||
+ **共用函式庫 1 支**(`lib/role-lib.sh`,不獨立掛);
|
||||
**改既有 hook 1 支**(`session-start-recall.sh`);**改既有腳本 2 支**(install/update);
|
||||
**新增非 hook 腳本 1 支**(`check-no-instance-names.sh`)。
|
||||
|
||||
### 4.4 settings.json 掛載順序(install 依 profile 組裝)
|
||||
|
||||
```
|
||||
SessionStart: session-start-recall.sh(profile 分流)
|
||||
[W3 插槽:policy plugin 的 SessionStart hook 自動排在框架 hook 之後]
|
||||
PreToolUse(Write|Edit|MultiEdit):
|
||||
1. install-artifact-guard.sh ← 先擋「改機制」,最外層
|
||||
2. role-guard.sh ← 再判角色
|
||||
3. jdd-format-guard.sh ← 再驗格式
|
||||
4. orchestrator-scope-guard.sh ← 僅 orchestrator profile
|
||||
5. sdd-guard.sh(既有)
|
||||
6. pre-write-guard.sh(既有空殼)
|
||||
7. wiki-secret-scan.sh(既有)
|
||||
PreToolUse(Grep|Glob|Read|Bash): wiki-first-search.sh(既有)
|
||||
PreToolUse(Task): subagent-wiki-guard.sh(既有)
|
||||
Stop / TaskCompleted: station-done-guard.sh、regression-scope.sh
|
||||
```
|
||||
|
||||
順序原則:**範圍大的擋在前**(改機制 → 角色 → 格式),讓錯誤訊息指向最根本的那條規則。
|
||||
|
||||
---
|
||||
|
||||
## 5. W3 插槽(本波只留座位,不做 plugin)
|
||||
|
||||
分離 §五 載入順序原樣文件化到 `profiles/*/docs/plugin-load-order.md`:
|
||||
|
||||
```
|
||||
SessionStart
|
||||
1. profile 憲法(scope 軸:這個資料夾的 CLAUDE.md)
|
||||
2. framework hooks 上鏈(common + profile)
|
||||
3. 已安裝 policy plugin 注入(primer 推到眼前、白名單 hook 排入鏈尾、skill 就緒)
|
||||
4. session-start-recall(wiki status 快照,現行機制)
|
||||
```
|
||||
|
||||
框架要做的只有兩件(分離 §四明文):
|
||||
1. 文件化「政策包= Claude Code 官方 plugin」的約定與載入順序——**框架不發明平行外掛格式**;
|
||||
2. 在兩份 profile 憲法留 must-read 注入點(一段標題 + 一行說明「政策包的必讀會出現在這裡」),
|
||||
讓 plugin 的 SessionStart hook 有地方推內容。
|
||||
|
||||
⚠️ **W3 動手前必讀官方文件**(`code.claude.com/docs/en/plugins.md`、`plugins-reference.md`),
|
||||
不憑記憶寫 `plugin.json`。本 SDD **不**預先規定 plugin 的 schema。
|
||||
|
||||
---
|
||||
|
||||
## 關鍵決策
|
||||
|
||||
| # | 決策 | 選擇 | 原因 | 放棄的選項 |
|
||||
|---|---|---|---|---|
|
||||
| D1 | 安裝清單怎麼管 | **manifest TSV**(common/repo/orchestrator 各一份),install 與 update 共讀 | 現行清單硬編在兩支腳本裡已經重複;加 profile 會變四份必然漂移。manifest 讓「加一個產物」=加一行資料 | 繼續硬編(四份清單手動同步) |
|
||||
| D2 | `common/`、`profiles/` 放哪 | 放 **`template/` 底下** | 所有安裝產物的遠端根是 `$TEMPLATE_SOURCE/template`;放 repo 根會開第二個 base URL,publish-exclude 與 mirror 規則也要跟著改。分離 §三的樹是示意(它把 install.sh 也畫在根,實際在 `scripts/`) | 照規格字面放 repo 根 |
|
||||
| D3 | 既有檔要不要實體搬進 `common/` | **不搬**。既有檔原地不動,靠 manifest **宣告**它屬 common | `update.sh` 的自我更新在腳本尾端 ⇒ 舊實例跑的是舊腳本、路徑寫死,搬檔=這一輪整排 404。1.16.0 已經被「來源改動=自動更新死掉」咬過一次 | 照規格字面實體搬移(斷所有舊實例的更新) |
|
||||
| D4 | 「本地補充區」怎麼劃 | **HTML 註解界標** + 框架區 sha256 | md 渲染不可見、grep 定位得到、CC 讀得到;sha 讓漂移可機械判定 | 靠檔尾約定(無邊界=無法偵測)/另開 `CLAUDE.local.md`(agent 不保證會讀) |
|
||||
| D5 | 角色 hook 屬 common 還是各 profile | **屬 common** | 總管 repo 裡也會 spawn engineer;照規格分裝會讓那顆 subagent 改得動 journeys.md,G2 在最該生效處失效(§3.4) | 照規格分裝進各 profile |
|
||||
| D6 | `guard-cross-project` 怎麼「修改」 | **上收進框架** `orchestrator-scope-guard.sh`,實例版於 W4 退役 | 它根本不在 template 裡,是實例自己發明的。就地改=在實例改機制=違反本案要立的第一條鐵律 | 在實例上就地改(自打嘴巴) |
|
||||
| D7 | J1/J2/J3 三條規則的檔案數 | **合成一支 `role-guard.sh`** | 同一個 hook 事件、同一份身分判定、同一張路徑表;拆三支=三處維護一條規則 | 一條一支(規格字面「逐條實作」) |
|
||||
| D8 | 閘 #2(實例專名)怎麼上線 | **腳本 + 逐行豁免標記 + 基線報表**,(a) 類本波清、(b)(c) 類標豁免待 W3 | 現況 8 檔 20 行命中;一上線全紅會逼出假性清理(把 arcrun 換成「某工作流引擎」=資訊沒了問題還在) | 硬上線(CI 立刻全紅)/先全部改寫(假性清理) |
|
||||
| D9 | `--framework-dev` 怎麼實作 | **repo 根的 `.sdt-framework-dev` 檔**(框架 repo 自帶並 commit),輔以 env `SDT_FRAMEWORK_DEV=1` | Claude Code **沒有** `--framework-dev` 這個官方 flag(規格假設不成立)。用檔案=框架 repo 天生就有,零記憶負擔 | 造一個 CLI flag(做不到)/純靠環境變數(每次要記得設) |
|
||||
| D10 | 本 SDD 的 status | **draft**,confirm 後升 active | D35 ②③;本 repo 現有 0 份 active,升活性不需搬移任何任務 | 直接寫 active(搶活性) |
|
||||
|
||||
---
|
||||
|
||||
## 技術限制
|
||||
|
||||
- 相容 macOS bash 3.2(`set -u` 下空陣列展開要先判長度——install.sh 既有踩過)。
|
||||
- 不假設有 `jq`:JSON 解析走 `jq → python3 → grep` 三段 fallback(沿既有 hook 慣例)。
|
||||
- 不假設 `CLAUDE_PROJECT_DIR` 存在:路徑一律由 `${BASH_SOURCE}` 往上推(雲端可跑)。
|
||||
- hook 一律「解析失敗即放行」,寧可漏擋不誤殺;每支頂部寫誠實限制。
|
||||
- 遠端檔案路徑(`$REPO_URL/...`)對既有實例是**契約**,本波只增不移。
|
||||
|
||||
---
|
||||
|
||||
## 驗收標準
|
||||
|
||||
以 requirements.md §四 的 **G1–G7** 為唯一驗收線。收工時每題必須附**實測輸出**,
|
||||
狀態只有三種:`✅ 通(附證據)` / `◐ 半通(標明缺什麼)` / `❌ 斷`。
|
||||
|
||||
- G5 本波上限為 `◐ 半通`(插槽就位、政策包在 W3)——**不得標 ✅**。
|
||||
- 另加兩條非功能驗收:
|
||||
- 乾淨環境雙 profile 安裝各 < 10 分鐘(分離 §八 預測①,實測計時)
|
||||
- `bash scripts/update.sh` 在 InkStoneCo 實例上跑出的漂移清單 = **4 支**(§0.4 基線,
|
||||
對得上=偵測正確;對不上=偵測有偽陰/偽陽)
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- `requirements.md`(本卷)/`tasks.md`(本卷)
|
||||
- `docs/3-specs/SDD-LIFECYCLE.md`(D35 生命週期)
|
||||
- `docs/3-specs/install-layout/design.md`(安裝產物佈局的既有決策,本案沿用其「不污染用戶根目錄」原則)
|
||||
- 上游提案:`InkStoneCo/system-dev/docs/3-specs/pending-changes.md` §三 W2
|
||||
- 需求輸入:`~/Desktop/總管/{JDD-template-upgrade,分離導入規格,總管系統藍圖v3}.md`
|
||||
@@ -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 角色封路** | orchestrator/engineer 的可寫範圍用 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 執行 update,the 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/
|
||||
endpoint/schema…),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 查站點索引表並列出需重考的
|
||||
Journey/Gherkin 清單(提醒,不阻擋)。
|
||||
|
||||
### 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 → orchestrator;repo 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 SessionStart,the system shall 依 profile 注入對應的必讀
|
||||
(orchestrator:root/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 執行 update,the 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
|
||||
# ── G1(JDD §七之一)
|
||||
Scenario: PM 總管優先補接縫而非做新功能
|
||||
Given 安裝流程的所有零件均已 commit(部分未 push、部分接口未串)
|
||||
And root.md 與 journeys.md 已就位,J-1(安裝者一次通關)已定義
|
||||
When PM 總管接到指令「交付 J-1」
|
||||
Then 它派出的第一批工作是補接縫(push 缺漏、串斷點)
|
||||
And 不包含任何新功能開發
|
||||
|
||||
# ── G2(JDD §七之二)
|
||||
Scenario: 考生改考卷被攔截
|
||||
Given engineer subagent 的某站 Gherkin 未過
|
||||
When 它嘗試修改 journeys.md 中的該條 Gherkin
|
||||
Then hook 攔截,修改不生效
|
||||
|
||||
# ── G3(JDD §七之三)
|
||||
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 交付的是 Given/When 能成立的**插槽**——
|
||||
乾淨實例裝得出 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 後半)
|
||||
@@ -0,0 +1,283 @@
|
||||
# jdd-dual-profile — Tasks
|
||||
|
||||
> 權威來源:此檔案是進度真相,不是 CLAUDE.md 或對話。
|
||||
> 規則:動手前標 [🔄],完成立刻標 [x],不批次更新。
|
||||
> **每一項都標「服務哪條 Gherkin」**(G1–G7 定義見 `requirements.md` §四)。
|
||||
> 🔴 **本卷 status: draft — 等 leo confirm 才准動工。以下一項都還沒開始。**
|
||||
|
||||
---
|
||||
|
||||
## 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 一眼看得懂該做什麼)
|
||||
|
||||
- [ ] 1.8 `update.sh` 舊實例遷移:無 manifest → 一次性補植 + CLAUDE.md 界標補植
|
||||
- 服務:**G4**、G6
|
||||
- 驗收:拿一份 1.18.0 的實例副本跑兩次 update,第二次為 no-op(冪等,貼兩次輸出對照)
|
||||
- 注意:舊 CLAUDE.md 整份包進 `sdt:local` 區,一個字都不能掉
|
||||
|
||||
- [ ] 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]` | 完成(有驗收證據)|
|
||||
| `[~]` | 暫緩(說明原因)|
|
||||
| `[!]` | 阻擋中(說明阻擋原因)|
|
||||
@@ -0,0 +1,15 @@
|
||||
# Pending Changes(規格變更緩衝區)
|
||||
|
||||
> 規則來源:`SDD-LIFECYCLE.md` 第 3、4 條。
|
||||
> 規格層變更(核心設計/方向改變)**只有這一條路**:CC 把 change proposal 寫進「待裁決」——
|
||||
> 變更摘要與觸發原因+影響分析(現行 SDD 哪些任務作廢/修改/不受影響/尚未完成)——然後**停止**,
|
||||
> 等使用者明說「confirm」才依第 4 條開新 SDD;沒 confirm 就繼續依現行 SDD 工作。
|
||||
> 多個 proposal 可並存,由人一次裁決。本檔不是 SDD,不掛 status。
|
||||
|
||||
## 待裁決
|
||||
|
||||
(無)
|
||||
|
||||
## 已裁決
|
||||
|
||||
(無——裁決後從「待裁決」移到這裡留底,標 confirmed / rejected + 日期。)
|
||||
@@ -0,0 +1,175 @@
|
||||
# tasks-project-projection — Design
|
||||
|
||||
> 狀態:草稿 v2(依總管 2026-06-27 設計修正改寫;待 leo 審核)
|
||||
> 建立:2026-06-27 | 最後更新:2026-06-27
|
||||
> 負責人:leo(uncle6me-web)
|
||||
> 來源:issue #16(InkStoneCo 總管);脈絡 InkStoneCo 北極星 §5.2
|
||||
>
|
||||
> v2 變更:廢棄「`HAS_ARCRUN` 檔案指紋偵測」整條路(arcrun workflow 存遠端 KV、不需本地檔,掃檔會 false negative)。改為「裝/init 對話 + 能力查詢(cli/mcp)+ 一次性廣告 + 手動啟用入口」。兩個 🔴 blocker(安裝指紋路徑 / 專案層 `.arcrun.yaml`)連帶消失。
|
||||
|
||||
---
|
||||
|
||||
## 一句話說明
|
||||
|
||||
把 `system-dev/docs/3-specs/*/tasks.md` **單向投影**成唯讀 GitHub Project(機器/dashboard 好抓);md 永遠是唯一真相源。是否啟用=**裝/init 時 AI 問用戶一句、查環境有沒有 arcrun 能力**(cli/mcp),不靠掃本地檔。沒 arcrun/用戶不要 → 純 md、完全 no-op,並做一次性溫和廣告,之後閉嘴。
|
||||
|
||||
---
|
||||
|
||||
## 背景與問題
|
||||
|
||||
- 純 md 的 tasks.md 對人友善,但機器/dashboard 難抓進度(要 parse markdown checkbox、跨多組 SDD 聚合)。
|
||||
- 想要 GitHub Project 的看板視圖,又**不想開第二個真相源**——人手動拖 Project 卡 ⇄ md 改字會兩邊打架。
|
||||
- 既有自動化紅線:**禁定期輪詢、禁 Actions 因事件 fan-out**(避免被 GitHub flag)。任何投影方案不得違反。
|
||||
- 目標用戶 low-code、只會叫 CC 做事 → 不能要求用戶手動建 Project、手動填 id、手動跑 sync。
|
||||
|
||||
→ 解法限定為:**單向(md → Project)、md 當家、push 後本機觸發一次、optional 模組預設不逼**。
|
||||
|
||||
---
|
||||
|
||||
## 範圍
|
||||
|
||||
### 包含(In Scope)
|
||||
- 在 **template** 新增一個 optional 模組:arcrun 投影工作流(YAML 工作流骨架 + README 標「需 arcrun,`acr push` 啟用」)。
|
||||
- **裝/init 對話**:安裝或第一次 init 時 AI 問一句白話「要不要把待辦同步到 GitHub」;答好 → 查環境有沒有 arcrun(自己的 mcp 設定 / `acr` 在不在 PATH)→ 有就設定、沒有就一次性廣告。
|
||||
- **手動啟用入口**:用戶第一次答「不好」、之後想開,有路可走(叫 AI 啟用,不需重裝)。
|
||||
- 單向同步邏輯設計:md → GitHub Project,按穩定 id 增量(非全量重寫),glob 掃多組 `tasks.md`。
|
||||
- arcrun 唯一對 md 的寫入:新 task 首次同步時,把 `<!-- gh:<id> -->` 註解 append 到那一行末(不碰既有內容)。
|
||||
|
||||
### 不包含(Out of Scope)
|
||||
- **反向同步**(Project → md):永不做。Project 唯讀,避免雙真相源。
|
||||
- 定期輪詢、GitHub Actions 觸發、cron:全部禁止(守 flag 紅線)。
|
||||
- 不要同步的用戶任何行為改變:完全 no-op;除裝/init 那**一次**問句與沒裝時的**一次**廣告外,不再追問、不重複廣告。
|
||||
- arcrun 本體的安裝/工作流引擎(那是 arcrun 的事,本模組只是「給 arcrun 跑的一份 YAML 工作流」)。
|
||||
- 把投影邏輯實作成獨立輪詢 daemon 或 GitHub App。
|
||||
- **掃本地檔判斷有沒有 arcrun**(廢棄):arcrun workflow 存遠端 KV、`arcrun_push_workflow` 收字串不讀本地檔,一個專案可零 arcrun 檔卻在用 arcrun → 掃檔 false negative。判準改「能力(cli/mcp)」。
|
||||
|
||||
---
|
||||
|
||||
## 設計
|
||||
|
||||
### 架構概覽
|
||||
|
||||
```
|
||||
push 後本機觸發(單次,非輪詢)
|
||||
│
|
||||
tasks.md(唯一真相源)──┘
|
||||
*.md 多組 ──► git diff(只看改了哪幾行)
|
||||
│
|
||||
┌───────┴────────┐
|
||||
│ 投影工作流 │(Arcrun workflow 格式)
|
||||
│ classify 四動作 │
|
||||
└───────┬────────┘
|
||||
▼
|
||||
gh issue create / close / edit / archive
|
||||
▼
|
||||
GitHub Project(唯讀投影,給 dashboard 抓)
|
||||
│
|
||||
新 task → 把 <!-- gh:id --> 寫回 md 那一行(唯一回寫)
|
||||
```
|
||||
|
||||
### 啟用判準:對話 + 能力查詢(不掃檔,取代舊 `HAS_ARCRUN`)
|
||||
|
||||
> ⚠️ 廢棄舊設計。原本想抄 `HAS_WIKI`/`HAS_SDD` 的「掃本地檔指紋」模式,但**對 arcrun 不成立**:
|
||||
> - `arcrun_push_workflow` 收 `yaml_content` 字串或 `graph` 物件,**不讀本地檔**(mcp/src/tools/arcrun_workflow_crud.ts:35-146)。
|
||||
> - workflow 真身存**遠端 KV**(`{api_key}:wf:*`,webhooks-named.ts:52-104);list/run/delete 全是 API。
|
||||
> - → 一個專案可**零 arcrun 檔案**卻完全在用 arcrun。掃檔當指紋會 **false negative**。
|
||||
>
|
||||
> 判準改為**「碰不碰得到 arcrun 能力(cli/mcp)」**,落地成一段對話,不是 shell 偵測。
|
||||
|
||||
**流程(裝/init 時跑一次)**
|
||||
|
||||
```
|
||||
安裝 或 第一次 init
|
||||
│
|
||||
└─ AI 問白話一句:「您需要把本專案的待辦事項同步到 GitHub 嗎?」
|
||||
│
|
||||
├─ 答「好」→ AI 查環境有沒有 arcrun(自己的 mcp 設定有沒有 arcrun tool / `acr` 在不在 PATH)
|
||||
│ ├─ 有 → 啟動同步設定(push 投影 workflow),完成。
|
||||
│ └─ 沒有 → 一次性溫和廣告:
|
||||
│ 「抱歉,您還沒安裝 Arcrun,無法啟用。Arcrun 是免費的 AI-friendly
|
||||
│ 工作流套件——想裝直接跟 Claude 說就行。之後也可手動啟用同步。」
|
||||
│
|
||||
└─ 答「不好」→ 不做,且不再追問。
|
||||
```
|
||||
|
||||
**三個設計意圖(務必守住)**
|
||||
|
||||
1. **判準=能力不是檔案**:沒設定檔/沒 readme ≠ 沒 arcrun。問「cli/mcp 裝了沒」。
|
||||
2. **讓用戶知道有這東西**:非專家不知道「有 arcrun、有同步功能」→ 問一次=自然揭露。
|
||||
3. **一次廣告、不一直廣告**:沒裝時做**一次**溫和廣告(免費/跟 Claude 說就能裝/以後可手動啟用),之後閉嘴,別每次 install 都騷擾。
|
||||
|
||||
**手動啟用入口**:第一次答「不好」後想開 → 叫 AI 啟用(AI 重跑「查能力 → push workflow」那段),不需重裝。
|
||||
(具體入口形態——slash command vs 純對話——待實作細化;low-code 用戶只需「跟 AI 說」。)
|
||||
|
||||
**對齊北極星**:install 完即可用、單一 AI 入口、不留抽象前置步驟。用戶不碰任何 `HAS_*` 抽象檔,就是被 AI 問一句、答一句。
|
||||
|
||||
### 穩定 id 與增量同步
|
||||
|
||||
- **id 埋在 md 行內**:`- [ ] 實作 X <!-- gh:42 -->`。首次同步前無 id;create 後 Arcrun 回寫。
|
||||
- **增量判準=git diff**:push 後本機觸發拿 `git diff` 的前後版,只處理「動到的行」,不全量重掃(省 API、避免無謂 edit)。
|
||||
- **四種動作**(issue 定案,照抄):
|
||||
|
||||
| md 狀態 | 動作 |
|
||||
|---------|------|
|
||||
| 有文字、無 id | `gh issue create` → 把 `<!-- gh:id -->` 寫回該行 |
|
||||
| 有 id 且 `[ ]→[x]` | `gh issue close` |
|
||||
| 有 id 且 文字/負責人/日期改 | `gh issue edit` |
|
||||
| id 在、但整行不見 | `gh issue close`/archive |
|
||||
|
||||
### 多組 SDD 全同步
|
||||
|
||||
- glob 掃 `system-dev/docs/3-specs/*/tasks.md`,每組獨立。
|
||||
- 每組帶**子系統 label**(取 folder 名)分組,方便 Project 過濾。
|
||||
- 新開 SDD folder → 新 `tasks.md` 首次 commit 即自動成新組,**無需手動登記**(守 low-code)。
|
||||
|
||||
### 守紅線:觸發方式
|
||||
|
||||
- **本機 push 後觸發單次**(git post-push 類 hook 或 Arcrun 的 push 事件鉤子),**單一目標**。
|
||||
- 明令禁止:cron/定期輪詢/GitHub Actions on push fan-out。
|
||||
- 觸發後做完即止,不常駐、不重試輪詢。
|
||||
|
||||
### 關鍵決策
|
||||
|
||||
| 決策 | 選擇 | 原因 | 放棄的選項 |
|
||||
|------|------|------|----------|
|
||||
| 同步方向 | 單向 md→Project | md 當家,杜絕雙真相源打架 | 雙向同步(會兩邊衝突) |
|
||||
| 真相源 | tasks.md | 人/CC 都只改 md,Project 唯讀 | Project 當真相源(low-code 用戶碰不到) |
|
||||
| 觸發 | push 後本機單次 | 守 flag 紅線 | 定期輪詢/Actions(踩紅線) |
|
||||
| 增量依據 | 行內穩定 id + git diff | 省 API、不全量重寫 | 全量 diff title 比對(脆、易撞名) |
|
||||
| 啟用判準 | 裝/init 對話 + 查 cli/mcp 能力 | 能力≠檔案;arcrun 存遠端 KV,掃檔 false negative | `HAS_ARCRUN` 檔案指紋(漏判用遠端沒落檔者,**廢棄**) |
|
||||
| 沒裝時 | 一次性溫和廣告 + 之後閉嘴 | 揭露功能存在又不騷擾 | 每次 install 都廣告(騷擾)/完全靜默(用戶不知有此功能) |
|
||||
| 腳本形態 | arcrun workflow(YAML:name/description/flow/config) | 守「什麼都叫 arcrun」;`acr push` 部署 | 獨立 daemon/App(多一套要維護) |
|
||||
| md 回寫 | 只在新 task 加 `<!-- gh:id -->` | 最小侵入,leo 已接受 | 在 md 維護更多 metadata(污染 md) |
|
||||
|
||||
### 介面 / 落點(待實作細化)
|
||||
|
||||
- 工作流檔形態:arcrun YAML(`name/description/flow/config` 結構)。template 放 `workflows/<投影>.yaml`,README 標「需 arcrun,`acr push <檔>` 啟用」。(最終以 arcrun 端 SDD 定案為準。)
|
||||
- README:optional 模組區塊標「此功能需 arcrun;不要/沒裝則純 md no-op」。
|
||||
- install/update:**不靠 `HAS_*` 分支裝檔**。改由裝/init 對話驅動——AI 在用戶答「好」且查到 arcrun 能力時,`acr push` 那份 workflow;workflow YAML 本身可隨 template 一起帶(留作記錄+手動啟用素材),但帶檔 ≠ 啟用。
|
||||
- 啟用=遠端 push 了 workflow,不是本地有檔。
|
||||
|
||||
---
|
||||
|
||||
## 風險與待解
|
||||
|
||||
| 項目 | 狀態 |
|
||||
|------|------|
|
||||
| ~~arcrun 安裝指紋路徑~~ | ✅ 消失(廢棄掃檔,改能力查詢) |
|
||||
| ~~arcrun workflow 檔標準落點 blocker~~ | ✅ 降級:慣例 `workflows/*.yaml` + `acr push`,最終以 arcrun 端 SDD 為準 |
|
||||
| 「查 arcrun 能力」的具體判準(mcp tool 名/`acr` PATH 偵測法) | 🟡 待 arcrun 端 template 對接定案 |
|
||||
| push 後本機觸發的具體掛載點(git hook vs arcrun 事件鉤) | 🟡 待 arcrun 觸發能力確認 |
|
||||
| id 回寫造成 working tree 變動(觸發後 md 有新 diff) | 🟡 需設計:回寫不應再觸發一輪(避免迴圈,§迴圈防護) |
|
||||
| 手動啟用入口形態(slash command vs 純對話) | 🟡 待實作細化 |
|
||||
|
||||
> 不再有 🔴 blocker。施工順序:**leo 定調「等 arcrun 動工完再施工」**——等 arcrun 端把 template 對接 + 觸發/能力查詢定案,回來確認後再寫骨架。本 SDD 先把設計改成這版對話式、定案待審。
|
||||
|
||||
---
|
||||
|
||||
## 與既有模式的對齊檢查
|
||||
|
||||
- ⚠️ **不沿用** `HAS_WIKI`/`HAS_SDD` 的掃檔指紋模式——對 arcrun 不成立(存遠端 KV)。改「能力查詢 + 對話」,這是與既有兩模組的**刻意分歧**,原因見上。
|
||||
- ✅ optional 預設關:不要/沒裝 arcrun 完全 no-op(對齊「沒 wiki 就不裝 wiki hooks」的精神,只是判準從檔案換成能力+意願)。
|
||||
- ✅ 守 flag 紅線(issue-handle skill 既有的避免被 flag 鐵律):單向、push 後本機單次、禁輪詢/Actions。
|
||||
- ✅ low-code 友善:被 AI 問一句答一句、自動建組、id 自動回寫,用戶不碰抽象前置步驟。
|
||||
- ✅ 不騷擾:沒裝時一次廣告即止(對齊「不增加用戶負擔」)。
|
||||
- ✅ 本 SDD 為內部記錄,落 `docs/3-specs/`(gitignore,不推 GitHub)。
|
||||
@@ -0,0 +1,68 @@
|
||||
# tasks-project-projection — Tasks
|
||||
|
||||
> 權威來源:此檔案是進度真相,不是 CLAUDE.md 或對話。
|
||||
> 規則:動手前標 [🔄],完成立刻標 [x],不批次更新。
|
||||
> 來源:issue #16;design.md 同目錄。
|
||||
|
||||
---
|
||||
|
||||
## Phase 1:投影 workflow + 本地觸發端(template 側,可獨立)
|
||||
|
||||
### Tasks
|
||||
|
||||
- [x] 1.1 寫投影 workflow yaml(`template/system-dev/workflows/tasks-project-sync.yaml`)
|
||||
- 驗收:`foreach` 增量 → `switch` 動作 → 四動作(create/close/edit/archive)+ Projects v2;`acr validate --offline` 過;**每個 component 經 `acr parts` 核實存在**。
|
||||
- 注意(已踩坑):arcrun 沒有 `github` 零件,打 API 一律 `component: http_request`;credential 引用 `{{creds.github_token}}`(非 `{{secret.}}`)。
|
||||
|
||||
- [x] 1.2 寫本地觸發端(`tasks-project-sync.local.sh`)
|
||||
- 驗收:讀 tasks.md / git diff / 分類四動作 / `acr run -i` 餵增量 / 回寫 id 的骨架就位;薄殼、不自刻 parser(複雜分類交 CC)。
|
||||
- 注意:arcrun 跑遠端 CF Workers 無本地 fs/git,這三件本來就歸本地端,非 arcrun 缺口。
|
||||
|
||||
---
|
||||
|
||||
## Phase 2:裝/init 對話 + 一次性廣告 + 帶檔
|
||||
|
||||
- [x] 2.1 install.sh 加裝/init 對話指引 + 一次性廣告 + 隨 SDD 模組帶 workflow 檔
|
||||
- 驗收:`bash -n` 過;下一步段有「問一句→查 arcrun 能力→有就設定/沒有就一次廣告」;帶檔 ≠ 啟用。
|
||||
|
||||
- [x] 2.2 update.sh 隨 SDD 模組 `add_if_missing` workflow 檔 + chmod
|
||||
- 驗收:`bash -n` 過;覆蓋不會關掉誰的同步(啟用狀態存遠端)。
|
||||
|
||||
- [x] 2.3 README(中英)標 optional 模組 + bump 1.13.0 + CHANGELOG
|
||||
- 驗收:兩份 README 對稱;VERSION 兩檔同步 1.13.0;CHANGELOG 記 http_request 修正與核實紀律。
|
||||
|
||||
---
|
||||
|
||||
## Phase 3:端到端驗證(待連 arcrun 後端的人)
|
||||
|
||||
> 前置條件:Phase 1、2 完成(已完成)
|
||||
|
||||
- [!] 3.1 `acr creds push`(github_token)+ `acr push`(部署 workflow)+ `acr run`(真打通 GitHub)
|
||||
- 阻擋:本 repo 沒 `.arcrun.yaml`、沒連 arcrun 後端,跑不了端到端。**待 leo21c**(連了 arcrun 的環境)。
|
||||
- 驗收:真建一個 issue + 投影進 Project 成功;Projects v2 `addProjectV2ItemById` 的 content node id(非 issue number)實測確認;github API 回傳欄位形狀(`{{gh_create.node_id}}` 取法)確認。
|
||||
|
||||
- [!] 3.2 本地觸發掛載點 + id 回寫防迴圈定稿
|
||||
- 阻擋:依賴 3.1 的真跑結果。
|
||||
- 驗收:push 後本機觸發一次(非 cron/Actions);回寫 `<!-- gh:id -->` 的 diff 不得再觸發一輪。
|
||||
|
||||
---
|
||||
|
||||
## 完成定義
|
||||
|
||||
整個 SDD 完成 = 以下全部達成:
|
||||
- [x] Phase 1、2 所有 tasks 標 [x](template 側 code-done)
|
||||
- [x] `acr parts` 核實所有 component 存在 + `acr validate` 過(客觀證據)
|
||||
- [!] Phase 3 端到端通過(待 leo21c)→ **未完成,不宣布 done**
|
||||
- [ ] design.md 與實作一致(端到端驗後若 API 細節有出入需回頭更新 design.md)
|
||||
|
||||
---
|
||||
|
||||
## 狀態說明
|
||||
|
||||
| 標記 | 意義 |
|
||||
|------|------|
|
||||
| `[ ]` | 未開始 |
|
||||
| `[🔄]` | 進行中(當前 session)|
|
||||
| `[x]` | 完成(有驗收證據)|
|
||||
| `[~]` | 暫緩(說明原因)|
|
||||
| `[!]` | 阻擋中(說明阻擋原因)|
|
||||
@@ -0,0 +1,140 @@
|
||||
# wiki-architecture — Design
|
||||
|
||||
> 狀態:已結案(2026-06-26,KB 端 183 卡實跑壓測全綠,1,029 條三元組、端點 0 缺陷;驗收明細見 tasks.md)
|
||||
> 建立:2026-06-26 | 最後更新:2026-06-26
|
||||
> 負責人:leo(uncle6me-web)
|
||||
|
||||
---
|
||||
|
||||
## 一句話說明
|
||||
|
||||
在「用戶所有檔案一律改寫成 wiki cards」的新架構下,用 **push(CC 行動前必主動看見)vs pull(CC 按需檢索)** 為唯一判準,重新決定 wiki/ 下每個檔的存廢——只有「不看就出事的盲區」獨立 push,其餘知識(含決策、原則)全是 cards、由 INDEX 多角度索引。
|
||||
|
||||
---
|
||||
|
||||
## 背景與問題
|
||||
|
||||
舊架構(1.4.0 前)部分內容「指向原文」,wiki/ 下因此長出一組固定特殊檔(status / mistakes / decisions-summary / TAXONOMY / INDEX),當時把它們當「天經地義的結構」。
|
||||
|
||||
1.4.1 起改成**所有原文一律改寫成 cards**,但**沒有人回頭重新推導這組特殊檔在新架構下還成不成立**。結果:
|
||||
- 「原則 / 願景」(如「不污染用戶根目錄」「目標用戶 low-code」)**無處可記**——decisions-summary 裝「單筆決策」、cards 裝「概念知識」,原則落在縫裡。
|
||||
- 每次想記原則,就糾結「要不要再加一個特殊檔」——這是打補丁,不是設計。
|
||||
|
||||
**根因**:用「是不是特殊知識」當分類判準是錯的維度。正確判準是 retrieval 行為:**CC 做事時,這東西會不會被動看見?**
|
||||
|
||||
---
|
||||
|
||||
## 範圍
|
||||
|
||||
### 包含(In Scope)
|
||||
- 確立 push/pull 判準,重新決定 wiki/ 每個檔的存廢。
|
||||
- 把 decisions-summary 降級為 cards + INDEX 視圖。
|
||||
- 新增 principles 進 push 清單(hook 主動注入)。
|
||||
- INDEX 升級為「多角度視圖」的家:新增角度 = CC 改 INDEX,不必問用戶開檔。
|
||||
- 同步 wiki-init.md / SKILL.md / INDEX 範本 / session-start hook。
|
||||
|
||||
### 不包含(Out of Scope)
|
||||
- 不改 cards 本身的三層+標籤架構(issue #8 的設計不動)。
|
||||
- 不改 TAXONOMY 的字典機制。
|
||||
- 不動 install-layout 的檔案落點(那是另一份 SDD)。
|
||||
- 不強制遷移既有用戶的 decisions-summary 內容(向後相容,見下)。
|
||||
|
||||
---
|
||||
|
||||
## 設計
|
||||
|
||||
### 核心判準:push vs pull
|
||||
|
||||
> **push**:CC 行動前必須主動出現在 context(session 開始就注入)。
|
||||
> **pull**:CC 想到要查、或載入相關卡時才看見。
|
||||
|
||||
判準的邏輯支點——**mistakes 必須 push**:mistakes 防的是「CC 不自覺的盲區」。一個你不知道存在的錯,你不會主動去檢索。靠 CC 自覺去查「自己沒自覺的盲區」是自相矛盾的 → 所以 pull 模式對 mistakes 邏輯上失效,必須 push。
|
||||
|
||||
同理推 principles:「不污染用戶根目錄」這種準繩,不主動注入,CC 設計時很可能**沒想到要服從就做了**(本專案實證:CC 這幾輪反覆忘記 low-code 用戶與不污染原則,正因它們沒被 push)。**原則也是不自覺的盲區** → 必須 push。
|
||||
|
||||
### 每個檔的存廢(依判準推導)
|
||||
|
||||
| 檔案 | push / pull | 邏輯理由 | 命運 |
|
||||
|------|-------------|---------|------|
|
||||
| **status.md** | push | 不是知識,是專案「此刻時態狀態」;不看會重做已完成的事 | **留**(hook 注入) |
|
||||
| **mistakes.md** | push | 防不自覺盲區;pull 邏輯失效(見上) | **留**(hook 注入) |
|
||||
| **principles.md** | push | 原則是會被遺忘的盲區;不注入 CC 設計時不服從(實證) | **新增**(hook 注入) |
|
||||
| **decisions-summary.md** | pull | 「遇設計判斷才查」——CC 面對決策時自然會查既有決策,pull 夠用;決策本身是知識內容=card | **降級**:內容歸 cards,INDEX 提供「決策角度」視圖 |
|
||||
| **TAXONOMY.md** | (元資料) | 是 cards 的分類字典=cards 的前提,邏輯上不可能是 card | **留**(元資料,非 push 非 pull) |
|
||||
| **INDEX.md** | (入口) | 索引本身;升級為多角度視圖的家 | **留並強化** |
|
||||
| **cards/** | pull | 一切知識內容(原文摘要、AI 筆記、lesson、決策、原則內容…)都在這 | 不變 |
|
||||
|
||||
**收斂結論**:只有「不是知識(status、TAXONOMY)」和「索引本身(INDEX)」獨立;**所有知識內容都是 cards**。push 清單=會變的狀態 + 會重犯的錯 + 會忘記的原則(status / mistakes / principles)。
|
||||
|
||||
### push 的實作機制(propose,非待定)
|
||||
|
||||
從 AI 的 context 行為推導,三類 push 的注入形態不同——判準是「**這東西需要全文才能避免出事,還是一行就夠觸發 CC 去查**」:
|
||||
|
||||
| push 項 | 注入形態 | 理由(從 AI 行為推) |
|
||||
|---------|---------|---------------------|
|
||||
| **status** | **全文** | 短、且 CC 必須知道精確的「下一步是什麼」才不重做;摘要會漏掉關鍵的當前 task 編號 |
|
||||
| **principles** | **全文(一行一條)** | 原則本身就該寫成「一行一條」的精煉準繩(不污染根目錄、用戶是 low-code…)。全文注入成本低、且原則是「行動前必服從」的硬約束,不能只給標題讓 CC 自己決定要不要展開——它不會 |
|
||||
| **mistakes** | **標題清單 + 一行症狀,全文按需 pull** | mistakes 可能累積到數十條、含長 context;全文會撐爆。但「標題 + 症狀」一行足以讓 CC 認出「我正要做的事撞到某條」→ 再展開讀全文。這裡 push 的是「觸發認出」,不是「完整內容」 |
|
||||
|
||||
**關鍵**:principles 全文 push、mistakes 摘要 push,差異來自——原則是「短而硬的約束」(全文成本低、漏一條就違反),mistakes 是「長而多的教訓」(全文太貴,但摘要足以觸發檢索)。這個區分本身就是「為 AI 設計」的判斷。
|
||||
|
||||
context 預算保護:principles 應設「條數上限」(如 ≤15 條,超過代表該合併或下放成 card);mistakes 摘要每條限一行。
|
||||
|
||||
### INDEX 作為「多角度視圖」的家
|
||||
|
||||
- INDEX 不再只是「標籤視圖」,而是所有檢索角度的入口:標籤角度、決策角度、(未來)任何角度。
|
||||
- **新增一個角度 = CC 在 INDEX.md 加一節**,不必新增實體特殊檔、不必問用戶。這直接解決「AI 想累積新類別卻要問用戶開檔」的問題。
|
||||
- principles/mistakes 雖獨立 push,但在 INDEX 也該有指標(讓 pull 路徑也找得到)。
|
||||
|
||||
### 原則的歸屬(回答原始提問)
|
||||
|
||||
「不污染用戶根目錄」「目標用戶 low-code」等:
|
||||
- **內容**寫成 principles(push 檔)+ 必要時 card。
|
||||
- CC 思考「怎麼設計」時,因 principles 被 push,行動前就看見,不必主動查。
|
||||
- 累積新原則 = CC 寫進 principles + INDEX 補指標,**永不問用戶開檔**。
|
||||
|
||||
---
|
||||
|
||||
## 技術限制
|
||||
|
||||
- push 注入量受 context 預算限制:不可無腦全文注入 mistakes+principles+status(會撐爆每 session context)。需「摘要 push + 全文按需 pull」。
|
||||
- 向後相容:既有用戶的 decisions-summary.md 已有內容 → 不可刪。降級指「不再是必備特殊檔」,既有的保留為一張「決策彙總卡」或 INDEX 視圖,內容不丟。
|
||||
- bash 3.2 相容(hook 改動)。
|
||||
- 不破壞 issue #8 的 cards 三層+標籤架構。
|
||||
|
||||
---
|
||||
|
||||
## 採集規範升級:內文實體關係 + ## 實體 區塊(issue #11,183 卡實證)
|
||||
|
||||
現行三元組/gloss 做窄了。從 Logseq vault 183 卡落地暴露:三元組只示範「卡對卡」(把既有 `[[雙鏈]]` 加動詞,資訊量沒增加);gloss 只描述卡標題這一個 node,內文實體(graph node)無處放描述。
|
||||
|
||||
| 決策 | 選擇 | 理由 |
|
||||
|------|------|------|
|
||||
| 三元組抓什麼 | **內文實體間關係**(卡對卡只是其中一類)| 知識圖譜價值在內文概念關係(`原子筆記 >> 對立於 >> 傳統筆記`),不是重複雙鏈 |
|
||||
| 內文實體描述放哪 | 卡片新增 **`## 實體`** 區塊:`正規名(同義詞)— 一句描述`,**集中放、不縮排、不重複** | 內文實體也是 graph node,需描述句供下游 embedding normalize(`黃仁勳` vs `Jensen Huang`)。生產者是 AI 不會邊寫邊漏,不需縮排防漏;集中最利下游一實體一 embedding |
|
||||
| `## 關聯` 結構 | 拆兩層:**內文知識關係**(端點裸文字,對應 `## 實體` 詞條)+ **卡片關係**(卡對卡 `[[]]`)| 內文三元組端點用裸文字避免 Logseq 紅色斷鏈;靠字面一致對應實體表 |
|
||||
| 端點對齊 | **升級成「強制自檢動作」**:寫完逐條把 A/B 拿去 `## 實體` 比對,沒完全相同的正規名 → 改詞或補實體表 | comment 實證:光寫規則 Haiku 會略過(端點對不齊 14 條);寫成自檢動作後 14→0。這是 Haiku 量產的盲點,跑 1-2 張看不出、跑 12 張才暴露 |
|
||||
| 謂詞 | **明寫「用動詞、禁名詞」** | 否則 Haiku 寫出 `>> 存儲格式 >>`、`>> 操作體驗 >>` 讀不通的名詞謂詞 |
|
||||
| 實體要描述、謂詞不要 | 實體補 gloss 描述句,謂詞裸詞即可 | 實體同義詞字面差遠需描述拉近;謂詞同義詞(參考/參照)字面本就近,裸詞 embed 自動聚類 |
|
||||
|
||||
**範圍界線**:本升級只談**採集端**(卡片該寫什麼)。「哪些 token 進向量庫、怎麼去重」屬下游 ingest(另立 kbdb-ingest-plugin#1),不混進 skill。
|
||||
**兩路徑同步**:SKILL.md(Cowork)+ wiki-init.md(CC)一致。
|
||||
|
||||
---
|
||||
|
||||
## 驗收標準
|
||||
|
||||
- [ ] push/pull 判準寫進 wiki-init.md 與 SKILL.md,成為 CC/Cowork 共同規則。
|
||||
- [ ] principles 進 push:session-start hook 注入 status + mistakes重點 + principles重點,且總注入量有節制(摘要而非全文)。
|
||||
- [ ] INDEX 範本含「多角度視圖」說明 + 明示「新增角度改 INDEX 不開新檔」。
|
||||
- [ ] decisions-summary 在文件中重新定位為「pull / INDEX 視圖」,既有內容相容保留。
|
||||
- [ ] 一個原則(如「不污染用戶根目錄」)實際寫進 principles,驗證 CC 開 session 會被動看見。
|
||||
- [ ] hook bash -n 過。
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
- SDD: install-layout(檔案落點,姊妹 SDD)
|
||||
- memory: user-profile-lowcode、internal-docs-not-pushed
|
||||
- 觸發:本專案 CC 反覆遺忘 low-code 用戶與不污染原則 → 暴露「原則無 push 通道」
|
||||
@@ -0,0 +1,83 @@
|
||||
# wiki-architecture — Tasks
|
||||
|
||||
> 權威來源:此檔案是進度真相。動手前標 [🔄],完成立刻標 [x]。
|
||||
|
||||
---
|
||||
|
||||
## Phase 0:審核(前置)
|
||||
|
||||
- [x] 0.1 design.md 經用戶審核通過(push/pull 判準、push 三項形態、INDEX 多角度)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1:規則文件(wiki-init + SKILL)
|
||||
|
||||
> 前置:Phase 0
|
||||
|
||||
- [x] 1.1 wiki-init.md 寫入 push/pull 判準 + 三類 push(status全文/principles全文/mistakes摘要)
|
||||
- 驗收:CC 讀 wiki-init 能判斷一個內容該 push 還 pull
|
||||
- [x] 1.2 wiki-init.md 新增 principles 檔的建立與維護規則(一行一條、條數上限)
|
||||
- [x] 1.3 wiki-init.md decisions-summary 重定位為「pull / INDEX 決策視圖」,既有內容相容
|
||||
- [x] 1.4 SKILL.md(Cowork)同步上述規則,CC/Cowork 一致
|
||||
- 驗收:兩來源檔 push/pull 規則 byte 對齊(除路徑)
|
||||
|
||||
## Phase 2:INDEX 升級為多角度視圖
|
||||
|
||||
> 前置:Phase 1
|
||||
|
||||
- [x] 2.1 INDEX.md 範本:從「標籤視圖」升級為「多角度入口」(標籤/決策/原則…角度)
|
||||
- [x] 2.2 明示「新增角度 = 改 INDEX 一節,不開新檔、不問用戶」
|
||||
- [x] 2.3 principles/mistakes 在 INDEX 留 pull 指標
|
||||
- 驗收:INDEX 範本含多角度說明 + 新增角度的自助規則
|
||||
|
||||
## Phase 3:push 機制(session-start hook)
|
||||
|
||||
> 前置:Phase 1
|
||||
|
||||
- [x] 3.1 session-start-recall.sh 擴充:注入 status 全文 + principles 全文 + mistakes 標題清單
|
||||
- [x] 3.2 context 保護:principles 條數上限檢查、mistakes 只注入標題+一行
|
||||
- [x] 3.3 bash -n + 沙盒測試(三類都有時注入正確、量受控)
|
||||
- 驗收:開 session 三類都被動出現,總量有節制
|
||||
|
||||
## Phase 4:新增 principles 範本 + 種子原則
|
||||
|
||||
> 前置:Phase 1-3
|
||||
|
||||
- [x] 4.1 建 template/system-dev/wiki/principles.md 範本
|
||||
- [x] 4.2 install.sh download + update.sh keep_file(用戶資料,永不覆蓋)
|
||||
- [x] 4.3 種子原則寫入(dev repo 自用 wiki):不污染用戶根目錄、目標用戶 low-code、wiki 主要給 AI 看、內部文件不推
|
||||
- 驗收:開 session 這些原則被動出現在 context
|
||||
|
||||
## Phase 5:版本、文件、提交
|
||||
|
||||
- [x] 5.1 bump(中版號,新增 principles 功能)+ 兩 VERSION 同步
|
||||
- [x] 5.2 CHANGELOG
|
||||
- [x] 5.3 commit + push(已隨 1.10.0~1.11.0 推送)
|
||||
|
||||
---
|
||||
|
||||
## 完成定義
|
||||
- [x] 所有 tasks [x]
|
||||
- [x] design.md 驗收標準全過
|
||||
- [x] 實證:CC 開 session 會被動看見 principles(本 session SessionStart hook 已注入 9 條,成立)
|
||||
|
||||
---
|
||||
|
||||
## 下游驗收(2026-06-26,KB 端 183 卡實跑壓測)
|
||||
|
||||
> 採集規範升級(gloss / `## 實體` / typed-edge / 端點對齊護欄)首次真實 ingest 全量驗證,全綠:
|
||||
|
||||
| 驗收項 | 結果 |
|
||||
|--------|------|
|
||||
| 結構齊全(gloss + 實體 + 兩層各 1 份) | ✅ 183/183 |
|
||||
| 有 gloss | ✅ 183/183 |
|
||||
| 內文三元組總數 | 1,029 條 |
|
||||
| 端點對不齊 / 三段式 | ✅ 0 |
|
||||
| raw source 鐵律(pages/journals 0 異動) | ✅ |
|
||||
| 內文層無誤用 wikilink | ✅ 乾淨 |
|
||||
|
||||
- 放量分三批、驗收驅動:試跑 12 → 補硬自檢 → 0;放量 170 → 殘留 26 → 修正批 15 → 殘留 1 → 手修;全量 0 缺陷。
|
||||
- 印證 issue #11 的「端點硬自檢」護欄(Haiku 量產 14→0)在真實規模成立。
|
||||
- 連帶修了 KB 端 CLAUDE.md 6 處過時路徑(`.claude/wiki/` → `system-dev/wiki/`),即 1.9.3 hook 提示的場景。
|
||||
|
||||
**狀態:結案。** 採集規範 / push 機制 / `## 實體` 都已下游實證,無待驗證項。
|
||||
Reference in New Issue
Block a user