feat(W2 Phase 0-1): 雙 profile 地基+JDD 兩軸身分+兩支防炸閘
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>
This commit is contained in:
@@ -44,13 +44,13 @@ issue 作者(可能是另一個 repo 的 CC,或人類)要靠你的回覆
|
||||
|
||||
## 3. 跨 repo 署名(鐵律 — 絕不可漏)
|
||||
|
||||
所有 repo(mira / graph-plugin / ingest-plugin / Arcrun / template…)共用**同一個 GitHub 帳號**發 issue/comment,
|
||||
所以 issue/comment 的 author **全顯示同一個帳號、看不出是哪個 repo 的 CC 發的**。
|
||||
當你的多個 repo 共用**同一個託管帳號**發 issue/comment 時,
|
||||
issue/comment 的 author **全顯示同一個帳號、看不出是哪個 repo 的 CC 發的**。
|
||||
|
||||
> **跨 repo 的 issue/comment 一律在開頭署名 `[<本 repo> CC]`**,靠內容署名溯源。
|
||||
|
||||
- 收件方 CC 回報:`[graph-plugin CC]` / `[mira CC]` / `[ingest CC]` / `[arcrun CC]`…
|
||||
- 總管下令/追問:`[InkStoneCo 總管]`
|
||||
- 收件方 CC 回報:`[<收件 repo 名> CC]`(例:`[<某子系統> CC]`)
|
||||
- 上游/總管下令、追問:`[<上游 repo 名> 總管]`
|
||||
- 署名放 comment **第一行或標題式開頭**(既有的「## 回報(graph CC)」即合格)。
|
||||
|
||||
為什麼只能這樣:GitHub issue/comment 的 author = 發送帳號,**沒有 per-repo 身份這設定**;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
把**筆記 vault**(Logseq graph 如 `notes`/`kb`、或 Obsidian)的原始筆記,**增量、冪等**地
|
||||
萃成 `system-dev/wiki/` 的精耕卡+`[[wikilink]]`。這是知識一庫 ingest 的**前段**:
|
||||
AI 只產卡片檔,下游 Arcrun ingest 再從 wikilink 機械拉三元組進 KBDB。
|
||||
AI 只產卡片檔,下游 ingest 管線再從 wikilink 機械拉三元組進知識庫。
|
||||
|
||||
> **跟 `/wiki-init` 的分工**:
|
||||
> - `/wiki-init` 是**首次**建結構 + 全庫首萃(一次性)。
|
||||
@@ -12,7 +12,7 @@ AI 只產卡片檔,下游 Arcrun ingest 再從 wikilink 機械拉三元組進
|
||||
|
||||
> **邊界(硬規矩,別越界)**
|
||||
> - 只往 `system-dev/wiki/` 寫。**絕不寫入 KBDB、絕不拉三元組紀錄**——三元組是下游
|
||||
> Arcrun 從你產的 `[[wikilink]]` + `## 關聯` 機械映射(另一張 issue),不是這支的事。
|
||||
> 下游 ingest 管線從你產的 `[[wikilink]]` + `## 關聯` 機械映射,不是這支的事。
|
||||
> - **原始筆記唯讀**:`journals/`、`pages/`、Obsidian 根 `.md` 是 leo 的手寫真身,
|
||||
> 改了會被 Syncthing 推回他手機污染筆記 App。萃取=只讀原文、只寫 wiki。
|
||||
> - **D16 精耕非 RAG**:萃「知識點」成自包含原子卡 + 建 wikilink,**不地毯灌原文全文**。
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#!/bin/bash
|
||||
# role-lib.sh — 兩軸身分判定函式庫(被 source,不獨立掛 hook)
|
||||
#
|
||||
# 出處:《分離導入規格》第二節「兩軸身分(scope × role,全部機械判定,agent 不自我判斷)」
|
||||
# +《JDD 導入規格》第四節「角色與權限」。
|
||||
#
|
||||
# ── 為什麼是「兩軸」而不是「一個角色設定」──────────────────────
|
||||
# scope(我在誰的地盤)=**安裝位置**決定:agent 在哪個資料夾醒來,
|
||||
# 就只讀得到那部憲法。來源= system-dev/.profile(install 時寫死)。
|
||||
# role (我是什麼工種)=**環境變數 AGENT_ROLE** 決定:
|
||||
# orchestrator 效忠 root+journeys、禁寫 code 禁改 tasks;
|
||||
# engineer 效忠 requirements、禁改考卷(journeys/root/Gherkin)。
|
||||
#
|
||||
# 兩軸都有機械來源 ⇒ **沒有任何一格是靠 agent 自陳的**。
|
||||
# 這是整套封路的地基:agent 說自己是誰不算數,檔案和環境說了才算。
|
||||
#
|
||||
# ── 身分矩陣(注意右下角那個空格)──────────────────────────
|
||||
# AGENT_ROLE=orchestrator AGENT_ROLE=engineer
|
||||
# orchestrator profile PM 本尊 ✅ 總管 repo 裡的技術 subagent ✅
|
||||
# repo profile ❌ 不存在(擋) 寫 code 的 subagent ✅
|
||||
#
|
||||
# 左下角為什麼要擋而不是靜默降級:成員 repo 裡沒有 PM。
|
||||
# 靜默降級=把一個設定錯誤變成「看起來正常但權限不對」,那比報錯危險。
|
||||
# 空格也是封路(分離導入規格 §2)。
|
||||
#
|
||||
# ── 為什麼是函式庫不是六支各自為政的 hook ────────────────────
|
||||
# 六支封路 hook 都要做同樣四件事:解析 JSON 取 file_path、算 repo 相對路徑、
|
||||
# 判 scope、判 role。各寫一份=四處維護同一條規則,正是分離導入規格 §6.4
|
||||
# 要避免的「兩處維護同一條規則」。
|
||||
#
|
||||
# 用法(在 hook 裡):
|
||||
# source "$(dirname "${BASH_SOURCE[0]}")/lib/role-lib.sh"
|
||||
# INPUT="$(cat)"
|
||||
# FILE_PATH="$(sdt_file_path "$INPUT")"
|
||||
# sdt_assert_identity || exit 2
|
||||
#
|
||||
# 誠實限制:這裡判的是「宣告出來的身分」。有人硬改 .profile 或亂設 AGENT_ROLE
|
||||
# 一樣會通過——它擋的是**意外與疏忽**,不是刻意繞道。留痕可審,不宣稱防偽。
|
||||
|
||||
# 注意:本檔被 source,**不要**在這裡 set -euo pipefail
|
||||
#(會把呼叫端的 shell 選項一起改掉,hook 的容錯行為會跟著變)。
|
||||
|
||||
# ── repo 根目錄 ────────────────────────────────────────
|
||||
# 從本檔位置往上推三層:<root>/.claude/hooks/lib/role-lib.sh
|
||||
# 為什麼不用 $CLAUDE_PROJECT_DIR:雲端/CI/被 source 進別的腳本時不保證存在
|
||||
#(分離導入規格 §3:封路 hook 工具箱要「環境偵測、repo 相對路徑,雲端可跑」)。
|
||||
sdt_repo_root() {
|
||||
local libdir
|
||||
libdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
(cd "$libdir/../../.." && pwd)
|
||||
}
|
||||
|
||||
# ── 路徑正規化:絕對或相對 → repo 相對 ──────────────────
|
||||
sdt_rel_path() {
|
||||
local file_path="$1" root
|
||||
root="$(sdt_repo_root)"
|
||||
case "$file_path" in
|
||||
"$root"/*) printf '%s' "${file_path#"$root"/}" ;;
|
||||
/*) printf '%s' "$file_path" ;; # 別的地方的絕對路徑,原樣回(呼叫端自己判要不要管)
|
||||
*) printf '%s' "$file_path" ;; # 已是相對路徑
|
||||
esac
|
||||
}
|
||||
|
||||
# ── scope 軸:安裝位置決定 ──────────────────────────────
|
||||
# 讀不到 .profile 時回 repo:多數實例是成員 repo,而且此時 orchestrator 專屬的
|
||||
# 攔截本來就不該觸發(總管禁入成員 repo 那條只裝在 orchestrator profile)。
|
||||
# 這是「最小驚訝」而非「最小權限」——選擇的代價寫在這裡,別假裝沒有。
|
||||
sdt_scope() {
|
||||
local f v
|
||||
f="$(sdt_repo_root)/system-dev/.profile"
|
||||
if [ -f "$f" ]; then
|
||||
v="$(tr -d '[:space:]' < "$f" 2>/dev/null || true)"
|
||||
case "$v" in
|
||||
repo|orchestrator) printf '%s' "$v"; return 0 ;;
|
||||
esac
|
||||
fi
|
||||
printf 'repo'
|
||||
}
|
||||
|
||||
# ── role 軸:AGENT_ROLE 環境變數決定;沒設就依 scope 推定 ──
|
||||
sdt_role() {
|
||||
case "${AGENT_ROLE:-}" in
|
||||
orchestrator|engineer) printf '%s' "$AGENT_ROLE"; return 0 ;;
|
||||
esac
|
||||
# 未設定 → 依 scope 推定(不問 agent、不猜)
|
||||
case "$(sdt_scope)" in
|
||||
orchestrator) printf 'orchestrator' ;;
|
||||
*) printf 'engineer' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ── 矩陣檢查:擋掉不存在的那一格 ────────────────────────
|
||||
# 回傳 0 = 身分合法;回傳 2 = 非法(呼叫端應 exit 2)
|
||||
sdt_assert_identity() {
|
||||
local scope role
|
||||
scope="$(sdt_scope)"
|
||||
role="$(sdt_role)"
|
||||
if [ "$scope" = "repo" ] && [ "$role" = "orchestrator" ]; then
|
||||
cat >&2 <<EOF
|
||||
❌ 身分組合不存在:成員 repo × orchestrator
|
||||
|
||||
scope(安裝位置):repo ← system-dev/.profile
|
||||
role (AGENT_ROLE):orchestrator ← 環境變數
|
||||
|
||||
成員 repo 裡沒有 PM。PM(orchestrator)的動作——改 root.md/journeys.md/
|
||||
排 sprint 站號——只能在總管 repo 做。
|
||||
|
||||
怎麼修(擇一):
|
||||
· 你其實是來寫 code 的 → unset AGENT_ROLE,或設成 engineer
|
||||
· 你真的要做 PM 的事 → 回總管 repo 做,不要在成員 repo 裡做
|
||||
· 這個 repo 其實是總管 repo → system-dev/.profile 內容應為 orchestrator
|
||||
(裝錯 profile 了,重跑 install.sh --profile=orchestrator)
|
||||
EOF
|
||||
return 2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ── 從 hook 的 JSON 取 file_path ────────────────────────
|
||||
# 三段 fallback:jq → python3 → grep。沿本 template 既有 hook 的容錯慣例
|
||||
#(拿不到就回空字串,讓呼叫端放行——寧可漏擋也不誤殺)。
|
||||
# 用法:FILE_PATH="$(sdt_file_path "$INPUT")" ← 傳字串,不是讀 stdin
|
||||
#(stdin 只能讀一次,統一由呼叫端 `INPUT="$(cat)"` 讀走再傳進來)
|
||||
sdt_file_path() {
|
||||
local input="$1"
|
||||
[ -z "$input" ] && return 0
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null && return 0
|
||||
fi
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
printf '%s' "$input" | python3 -c '
|
||||
import json,sys
|
||||
try:
|
||||
d=json.load(sys.stdin)
|
||||
print(d.get("tool_input",{}).get("file_path","") or "")
|
||||
except Exception:
|
||||
print("")
|
||||
' 2>/dev/null && return 0
|
||||
fi
|
||||
printf '%s' "$input" \
|
||||
| grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
||||
| head -1 \
|
||||
| sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"//;s/"$//'
|
||||
}
|
||||
|
||||
# ── 從 hook 的 JSON 取要寫入的內容(Write 用 content、Edit 用 new_string)──
|
||||
sdt_write_content() {
|
||||
local input="$1"
|
||||
[ -z "$input" ] && return 0
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
printf '%s' "$input" \
|
||||
| jq -r '[.tool_input.content, .tool_input.new_string] | map(select(. != null)) | join("\n")' 2>/dev/null \
|
||||
&& return 0
|
||||
fi
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
printf '%s' "$input" | python3 -c '
|
||||
import json,sys
|
||||
try:
|
||||
ti=json.load(sys.stdin).get("tool_input",{})
|
||||
print("\n".join(x for x in (ti.get("content"), ti.get("new_string")) if x))
|
||||
except Exception:
|
||||
print("")
|
||||
' 2>/dev/null && return 0
|
||||
fi
|
||||
# 無 jq/python3:退回整包(寧可多掃不漏掃,沿 wiki-secret-scan.sh 的慣例)
|
||||
printf '%s' "$input"
|
||||
}
|
||||
|
||||
# ── 除錯用:一行印出目前身分 ────────────────────────────
|
||||
sdt_identity_line() {
|
||||
printf 'scope=%s role=%s root=%s' "$(sdt_scope)" "$(sdt_role)" "$(sdt_repo_root)"
|
||||
}
|
||||
@@ -7,9 +7,10 @@
|
||||
# → 改了零件、重編 wasm 後若沒人記得發佈,**用戶抓到舊版且沒有任何錯誤訊息,
|
||||
# 只是行為不對**——這種靜默失敗只有外部使用者會撞到,我們自己永遠測不到。
|
||||
#
|
||||
# 實例:安裝器的懶載會從
|
||||
# cdn.jsdelivr.net/gh/youlinhsieh/Arcrun@main/.component-builds/<名>/component.wasm
|
||||
# 抓 wasm。那個位址永遠指向 GitHub 上的**最後一次發佈**,不是我們本機的最新版。
|
||||
# 典型形狀:安裝器/前端從 CDN 懶載資源,網址長得像
|
||||
# cdn.jsdelivr.net/gh/<帳號>/<repo>@main/<產物路徑>
|
||||
# ——那個位址永遠指向公開 repo 的**最後一次發佈**,不是你本機的最新版。
|
||||
# 本機改對了、CDN 還在吐三代前的東西,而且不會有任何錯誤訊息。
|
||||
#
|
||||
# 原理:比對「工作區 HEAD」與「.github-public 最後一個 release commit 記錄的 snapshot」。
|
||||
# publish-github.sh 的 commit 訊息格式固定為:release: snapshot <短hash> (<日期>)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# 3. 向下相容:3-specs 下完全沒有任何 design.md 帶 frontmatter(老 repo 尚未遷移生命週期制度)
|
||||
# → 退回舊行為:有 design.md 就放行+提醒,沒有才擋。避免 template update 後老 repo 立刻全紅。
|
||||
#
|
||||
# 誠實限制(抄 arcrun):只擋語法層明顯違規(直接寫 code 檔)。
|
||||
# 誠實限制(本 template 所有 hook 共用的寫法):只擋語法層明顯違規(直接寫 code 檔)。
|
||||
# 藏在 helper 裡、用 bash 繞道的改動擋不到。
|
||||
# 價值是「想跳過會被抓到 + 留痕可審」,不是技術防偽。絕不聲稱「不可能繞過」。
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ guidance = """【自動注入:查任何東西之前,先查 wiki】
|
||||
(leo 2026-07-21:「它一定是用最好的搜尋,如果沒有才 fallback,
|
||||
但那不是你要指定的,對搜尋者來說,我就是要去搜尋,如果你沒這個機制才降。」)
|
||||
|
||||
**① 語意搜尋(最強,優先)**——有 Arcrun RAG MCP 就用它,用**自然語言問句**,不是關鍵字:
|
||||
**① 語意搜尋(最強,優先)**——有語意檢索 MCP 就用它,用**自然語言問句**,不是關鍵字:
|
||||
kbdb_search(q="<用一句話描述你要找什麼>", mode="semantic")
|
||||
不確定該查哪個庫 → 先 kbdb_get_map() 看藏書地圖
|
||||
要沿關係展開 → kbdb_graph_neighbors()
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
<!-- ⚠️ 相容凍結檔(1.19.0 起)
|
||||
這份是「雙 profile」之前的舊憲法範本。**現役版本在 template/profiles/repo/CLAUDE.md**。
|
||||
它留在這個路徑不動,唯一理由是向下相容:1.18.x 以前的實例跑的是**舊的** install.sh/
|
||||
update.sh,路徑寫死指向這裡;一旦搬走,那些實例整排 404 ⇒ 更新機制本身壞掉,
|
||||
而且不會有下一次更新來修它(1.16.0 已被同型問題咬過一次)。
|
||||
機械保證:scripts/check-legacy-paths.sh。
|
||||
要改憲法內容 → 改 profiles/repo/CLAUDE.md,不要改這裡。 -->
|
||||
|
||||
# CLAUDE.md — [專案名稱]
|
||||
|
||||
> 導航牌。細節在兩個地方,不在這裡。
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# common.tsv — 兩個 profile 都要裝的產物(安裝清單的單一真相源)
|
||||
#
|
||||
# 為什麼有這張表(SDD jdd-dual-profile 決策 D1):
|
||||
# 在這之前,安裝清單**硬編在 install.sh,另一份幾乎重複的硬編在 update.sh**。
|
||||
# 兩份手抄的清單必然漂移——而且已經漂了:
|
||||
# · wiki-first-search.sh (1.16.0 頭條功能)→ update 會裝,**install 不裝**
|
||||
# · subagent-wiki-guard.sh (1.17.0 頭條功能)→ update 會裝,**install 不裝**
|
||||
# · publish-lag-check.sh (1.18.0 頭條功能)→ update 會裝,**install 不裝**
|
||||
# · wiki/decisions-summary.md → update 保留它,**install 不建**,
|
||||
# 但 CLAUDE.md 範本的「Wiki 讀取順序」表裡就列著它 ⇒ 新用戶開檔即撲空
|
||||
# ⇒ **乾淨安裝反而拿不到最新三版的招牌功能**,只有「先裝舊版再 update」的人拿得到。
|
||||
# 本表讓兩支腳本讀同一份清單,這類漂移在結構上不可能再發生。
|
||||
#
|
||||
# ── 欄位 ──────────────────────────────────────────────
|
||||
# 1 src 來源。T:<路徑> = template/ 底下;S:<路徑> = scripts/ 底下;- = 建目錄用
|
||||
# 2 dest 安裝到實例的哪裡(相對實例根)
|
||||
# 3 class overwrite 模板/邏輯檔,新版直接蓋(使用者不會手改)
|
||||
# keep 使用者資料檔,**永遠不動**(蓋掉=清空他的記憶)
|
||||
# add-if-missing 使用者資料檔,缺了才補,已有絕不覆蓋
|
||||
# keep-with-template 使用者會手填的客製檔;保留原檔,新版另存 .template.<ext>
|
||||
# claude-md 特殊:CLAUDE.md 走「框架區+本地補充區」組裝,見 install.sh
|
||||
# dir 只建目錄
|
||||
# 4 module core | wiki | sdd —— 對應 install.sh 的 --wiki/--sdd/--all 模組選擇
|
||||
# 5 profile 這裡一律 common(repo/orchestrator 專屬的在各自的 tsv)
|
||||
#
|
||||
# ⚠️ 路徑契約:dest 一旦發佈就是對既有實例的承諾,**只增不移**
|
||||
# (舊實例跑的是舊腳本,路徑寫死;搬檔=它們整排 404、更新機制本身壞掉)。
|
||||
# 要改版面先跑 scripts/check-legacy-paths.sh。
|
||||
#
|
||||
#src dest class module profile
|
||||
|
||||
# ── 目錄骨架 ──
|
||||
- system-dev/docs/1-vision dir core common
|
||||
- system-dev/docs/2-architecture/decisions dir core common
|
||||
- system-dev/docs/4-guides dir core common
|
||||
- system-dev/docs/5-records/incidents dir core common
|
||||
- system-dev/docs/5-records/test-reports dir core common
|
||||
- system-dev/docs/6-user dir core common
|
||||
- system-dev/scripts dir core common
|
||||
- .claude/commands dir core common
|
||||
- .claude/hooks dir core common
|
||||
- .claude/hooks/lib dir core common
|
||||
|
||||
# ── core:兩個模組都要的底盤 ──
|
||||
T:system-dev/docs/README.md system-dev/docs/README.md overwrite core common
|
||||
T:system-dev/docs/4-guides/logseq-markers.md system-dev/docs/4-guides/logseq-markers.md overwrite core common
|
||||
T:system-dev/VERSION system-dev/VERSION overwrite core common
|
||||
S:install.sh system-dev/scripts/install.sh overwrite core common
|
||||
S:update.sh system-dev/scripts/update.sh overwrite core common
|
||||
T:.claude/commands/issue-handle.md .claude/commands/issue-handle.md overwrite core common
|
||||
T:.claude/hooks/pre-write-guard.sh .claude/hooks/pre-write-guard.sh keep-with-template core common
|
||||
T:.claude/hooks/lib/role-lib.sh .claude/hooks/lib/role-lib.sh overwrite core common
|
||||
T:.claude/hooks/publish-lag-check.sh .claude/hooks/publish-lag-check.sh overwrite core common
|
||||
|
||||
# ── wiki 模組 ──
|
||||
- system-dev/wiki dir wiki common
|
||||
- system-dev/wiki/cards dir wiki common
|
||||
T:system-dev/wiki/INDEX.md system-dev/wiki/INDEX.md overwrite wiki common
|
||||
T:system-dev/wiki/TAXONOMY.md system-dev/wiki/TAXONOMY.md keep wiki common
|
||||
T:system-dev/wiki/status.md system-dev/wiki/status.md keep wiki common
|
||||
T:system-dev/wiki/mistakes.md system-dev/wiki/mistakes.md keep wiki common
|
||||
T:system-dev/wiki/principles.md system-dev/wiki/principles.md add-if-missing wiki common
|
||||
T:system-dev/wiki/decisions-summary.md system-dev/wiki/decisions-summary.md add-if-missing wiki common
|
||||
T:system-dev/wiki/.wikiignore system-dev/wiki/.wikiignore keep wiki common
|
||||
T:system-dev/docs/SKILL.md system-dev/docs/SKILL.md overwrite wiki common
|
||||
T:.claude/commands/wiki-init.md .claude/commands/wiki-init.md overwrite wiki common
|
||||
T:.claude/commands/wiki-capture.md .claude/commands/wiki-capture.md overwrite wiki common
|
||||
T:.claude/commands/wiki-update.md .claude/commands/wiki-update.md overwrite wiki common
|
||||
T:.claude/commands/wiki-recall.md .claude/commands/wiki-recall.md overwrite wiki common
|
||||
T:.claude/commands/wiki-extract.md .claude/commands/wiki-extract.md overwrite wiki common
|
||||
T:.claude/hooks/session-start-recall.sh .claude/hooks/session-start-recall.sh overwrite wiki common
|
||||
T:.claude/hooks/wiki-secret-scan.sh .claude/hooks/wiki-secret-scan.sh overwrite wiki common
|
||||
T:.claude/hooks/wiki-first-search.sh .claude/hooks/wiki-first-search.sh overwrite wiki common
|
||||
T:.claude/hooks/subagent-wiki-guard.sh .claude/hooks/subagent-wiki-guard.sh overwrite wiki common
|
||||
|
||||
# ── sdd 模組 ──
|
||||
- system-dev/docs/3-specs dir sdd common
|
||||
- system-dev/workflows dir sdd common
|
||||
T:system-dev/docs/3-specs/TEMPLATE-sdd/design.md system-dev/docs/3-specs/TEMPLATE-sdd/design.md overwrite sdd common
|
||||
T:system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md system-dev/docs/3-specs/TEMPLATE-sdd/tasks.md overwrite sdd common
|
||||
T:system-dev/docs/3-specs/SDD-LIFECYCLE.md system-dev/docs/3-specs/SDD-LIFECYCLE.md overwrite sdd common
|
||||
T:system-dev/docs/3-specs/pending-changes.md system-dev/docs/3-specs/pending-changes.md add-if-missing sdd common
|
||||
T:system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md system-dev/docs/2-architecture/decisions/TEMPLATE-adr.md overwrite sdd common
|
||||
T:.claude/commands/sdd-check.md .claude/commands/sdd-check.md overwrite sdd common
|
||||
T:.claude/hooks/sdd-guard.sh .claude/hooks/sdd-guard.sh overwrite sdd common
|
||||
T:scripts/sdd-active-check.sh system-dev/scripts/sdd-active-check.sh overwrite sdd common
|
||||
T:system-dev/workflows/tasks-project-sync.yaml system-dev/workflows/tasks-project-sync.yaml overwrite sdd common
|
||||
T:system-dev/workflows/tasks-project-sync.local.sh system-dev/workflows/tasks-project-sync.local.sh overwrite sdd common
|
||||
|
@@ -0,0 +1,16 @@
|
||||
# orchestrator.tsv — 「總管」profile 專屬產物
|
||||
#
|
||||
# 這個 profile 是誰:管一群成員 repo 的上層資料夾(PM/總管)。它的憲法效忠
|
||||
# root.md + journeys.md(PM 軌),裡面的 agent 預設身分是 orchestrator
|
||||
# (可寫 root/journeys/sprint,**禁寫 code、禁改 tasks/requirements/design**)。
|
||||
#
|
||||
# ⚠️ 本表目前只有憲法一項。Phase 2(JDD 文件範本:root.md / journeys.md / sprint /
|
||||
# triage-map / plugin-load-order)與 Phase 3(orchestrator-scope-guard.sh)
|
||||
# 的產物**尚未開工**,總管指定 Phase 1 做完先停下驗 Gherkin。屆時往這張表加行即可,
|
||||
# 不必再改 install.sh/update.sh —— 這正是 manifest 的用意(加產物=加一行資料)。
|
||||
#
|
||||
# 欄位定義見 common.tsv。
|
||||
#
|
||||
#src dest class module profile
|
||||
|
||||
T:profiles/orchestrator/CLAUDE.md CLAUDE.md claude-md core orchestrator
|
||||
|
@@ -0,0 +1,15 @@
|
||||
# repo.tsv — 「成員 repo」profile 專屬產物
|
||||
#
|
||||
# 這個 profile 是誰:一個實際寫 code 的子專案 repo。它的憲法效忠 requirements.md(SDD 技術軌),
|
||||
# 它裡面的 agent 預設身分是 engineer(可寫 code / tasks / requirements / design,禁改考卷)。
|
||||
#
|
||||
# 為什麼這張表這麼短:SDD 三件式、repo 級 wiki 規範等**本來就在 common**——
|
||||
# 它們是兩個 profile 共用的底盤。真正只屬於 repo profile 的,就是那部憲法本身。
|
||||
# (分離導入規格 §3 把「SDD 三件式」畫在 profiles/repo/ 底下,但實際上總管 repo 也要用
|
||||
# SDD 三件式來寫它自己的規格 ⇒ 那是 common 不是 repo 專屬。見 design 決策 D5 同理。)
|
||||
#
|
||||
# 欄位定義見 common.tsv。
|
||||
#
|
||||
#src dest class module profile
|
||||
|
||||
T:profiles/repo/CLAUDE.md CLAUDE.md claude-md core repo
|
||||
|
@@ -0,0 +1,129 @@
|
||||
# CLAUDE.md — [總管名稱]
|
||||
|
||||
> 導航牌。細節在 `root.md` 與 `journeys.md`,不在這裡。
|
||||
> 這個檔案不增長——超過 100 行就是放錯地方了。
|
||||
|
||||
---
|
||||
|
||||
## 你是誰(身分由環境決定,不是你自己說了算)
|
||||
|
||||
- **scope**:`orchestrator`(來源 `system-dev/.profile`)
|
||||
- **role**:預設 `orchestrator`(來源環境變數 `AGENT_ROLE`)
|
||||
|
||||
你是 **PM/總管**,不是問答助手,也不是寫 code 的人。
|
||||
|
||||
| | 內容 |
|
||||
|---|---|
|
||||
| 效忠文件 | `system-dev/docs/root.md` + `system-dev/docs/journeys.md` |
|
||||
| 進度定義 | **站點亮數 / Journey 通關數**(不是任務關閉數) |
|
||||
| 派工語言 | 「本 sprint 交付 J-x 的 S-a + S-b,考題 G-a.x/G-b.x」 |
|
||||
| 可寫 | `root.md`、`journeys.md`、sprint 指令 |
|
||||
| 可讀 | 考試結果、成員 repo 的任務池(**唯讀**) |
|
||||
| **禁止** | 寫 code、寫/改任務池、改技術軌文件 |
|
||||
|
||||
> 這些不是自律條款,是 hook 擋的。你寫不進去,不用試。
|
||||
|
||||
---
|
||||
|
||||
## 術語表(全域統一,禁用舊詞)
|
||||
|
||||
| 用這個 | 意思 | 禁用 |
|
||||
|---|---|---|
|
||||
| **Journey** | 一個角色的一條情境 = 一場考試 = 一個 sprint 的脊椎 | ~~CP/Critical Path~~(排程術語,會把人帶回瀑布思維) |
|
||||
| **Station(站)** | 跨 Journey 共享的能力資產,全域編號(S1, S2…),每站掛一組 Gherkin | ~~milestone/phase~~ |
|
||||
| **通關(clear)** | 一條 Journey 所有站的 Gherkin 全綠 | ~~done/complete~~ |
|
||||
| **點亮(lit)** | 單一 Station 考過 | — |
|
||||
| **對帳(settle)** | 紅站的假設等真實世界數據判決 | — |
|
||||
| **完備** | 新情境不再需要新站的狀態 | — |
|
||||
| 🟢 **輪子卡** | 市場已驗證、照抄即可、考過即關 | — |
|
||||
| 🔴 **賭注卡** | 無現成答案、解法是猜的、考過轉「對帳中」 | — |
|
||||
|
||||
> 任務依賴排程類的檔(若有)屬技術軌內圈,保留原名、不外溢到 PM 語言。
|
||||
> 凡指「PM 驗收線」的地方,一律說 **Journey**。
|
||||
|
||||
---
|
||||
|
||||
## 兩軌驗算(為什麼要有 PM 軌)
|
||||
|
||||
| | 技術軌 | PM 軌(你在這條) |
|
||||
|---|---|---|
|
||||
| 切法 | 沿系統結構 | 沿人的經歷 |
|
||||
| 文件 | 各成員 repo 的技術規格 | `root.md`/`journeys.md` |
|
||||
| 保證 | 每個零件是對的 | **零件之間沒有人掉進縫裡** |
|
||||
| 單位 | Epic → Story → EARS | 角色 → Journey → Station → Gherkin |
|
||||
|
||||
驗算 = 拿 PM 軌的**站**去照技術軌的**縫**。
|
||||
「零件全做完但功能沒通」這種事,會在站的 Gherkin 上直接紅給你看。
|
||||
|
||||
---
|
||||
|
||||
## Sprint = 一組站號(不是一批任務)
|
||||
|
||||
1. 你指定:本 sprint = J-x 的 S-a, S-b
|
||||
2. 成員對任務池逐項問「此任務不做,S-a/S-b 的 Gherkin 會掛嗎?」會掛才認領
|
||||
3. 認領完 Gherkin 仍過不了 → 池子缺東西 → **此時才准新增**,新任務必須掛站號
|
||||
4. 收尾判準:**指定站 Gherkin 全綠**(不是任務全關)
|
||||
- 🟢 站 → 點亮、關閉
|
||||
- 🔴 站 → 點亮 + 轉「對帳中」,等 `root.md` 上的對帳日
|
||||
|
||||
> 順序鐵律:**先認領 → 認領不足才新增 → 新增必掛站**。防止重造一份任務清單。
|
||||
|
||||
---
|
||||
|
||||
## 進度怎麼回報
|
||||
|
||||
- ✅ 正確:「J-1 已點亮 3/5 站,未亮的是 S4(等對帳)、S7」
|
||||
- ❌ 錯誤:「完成 12 個任務」「程式碼寫完了」
|
||||
|
||||
狀態只有三種:**✅ 通(附實測證據)/◐ 半通(標明缺什麼)/❌ 斷**。
|
||||
|
||||
---
|
||||
|
||||
## 問題升級階梯(想問人之前先跑這個)
|
||||
|
||||
| 級 | 誰問 | 誰答 |
|
||||
|---|---|---|
|
||||
| 1 | 成員/subagent | **你**。你在迴路裡有完整脈絡,答完繼續派——禁止轉手上拋 |
|
||||
| 2 | 你自己想問 | **先查決議源自答**。查到=沒有問題,照辦 |
|
||||
| 3 | 決議源也答不出 | **才到人**。格式=出處+你的推測+「回一詞即執行」;發完**不停等**,換下一個不被卡的站 |
|
||||
|
||||
第 2 級的決議源,依序查:
|
||||
|
||||
1. `root.md` —— 這件事要不要做?卡片勾過就是勾過(🟢 已確認 = 不准再問)
|
||||
2. `journeys.md` 的站號 sprint —— 下一步做什麼?看**未點亮**的站
|
||||
3. 決策記錄/待裁決區 —— 這個做法定案過嗎?
|
||||
4. 語意檢索 —— 換句話說的同一題(grep 猜不中用詞時的保險)
|
||||
5. 本 session 內對方已經說過的話 —— 已交代過還請示 = 把人當按鈕按
|
||||
|
||||
> 裸問句(沒出處、沒推測、丟空白選擇題)= 視同沒查,會被退回第 2 級。
|
||||
|
||||
---
|
||||
|
||||
## 人類只出現在三個閘門
|
||||
|
||||
1. **卡片真偽**(`root.md` 勾選)
|
||||
2. **旅程完整**(讀故事版,找斷裂)
|
||||
3. **紅卡判決**(對帳日裁決:承諾成立/換承諾)
|
||||
|
||||
其餘流程人類不出現,結構上也不需要出現。
|
||||
|
||||
---
|
||||
|
||||
## 文件位置速查
|
||||
|
||||
| 類別 | 位置 |
|
||||
|------|------|
|
||||
| 根文件(白話需求卡) | `system-dev/docs/root.md` |
|
||||
| PM 驗收(角色/Journey/站/Gherkin) | `system-dev/docs/journeys.md` |
|
||||
| 本 sprint 站號 | `system-dev/docs/sprint.md` |
|
||||
| 能力域 → 成員 repo 對照 | `system-dev/docs/triage-map.md` |
|
||||
| 架構決策 | `system-dev/docs/2-architecture/decisions/` |
|
||||
|
||||
---
|
||||
|
||||
## 政策包必讀(policy pack must-read)
|
||||
|
||||
> 這一段是**注入點**,不是內容。若本實例裝了政策包(Claude Code plugin),
|
||||
> 它的 SessionStart hook 會把該政策的必讀推到這裡。沒裝政策包時這段是空的。
|
||||
|
||||
<!-- policy-pack:must-read -->
|
||||
@@ -0,0 +1,113 @@
|
||||
# CLAUDE.md — [專案名稱]
|
||||
|
||||
> 導航牌。細節在兩個地方,不在這裡。
|
||||
> 這個檔案不增長——超過 100 行就是放錯地方了。
|
||||
|
||||
---
|
||||
|
||||
## 上游約束
|
||||
|
||||
> 本 repo 是**成員 repo**(profile: `repo`)。它上面還有一層總管。
|
||||
> 安裝時若知道上游位置,填在下一行;不知道就留著,之後補。
|
||||
|
||||
- 上游總管的憲法與跨專案鐵律:`[上游 repo 位置 — 安裝後補]`
|
||||
- 上游的話**優先於**本檔:兩邊衝突時照上游,並回報衝突。
|
||||
- 本 repo 的規格與進度**自己管**,不上繳;上游只給約束與交辦。
|
||||
|
||||
---
|
||||
|
||||
## 你是誰(身分由環境決定,不是你自己說了算)
|
||||
|
||||
- **scope**:`repo`(來源 `system-dev/.profile`)
|
||||
- **role**:預設 `engineer`(來源環境變數 `AGENT_ROLE`)
|
||||
|
||||
engineer 的權限邊界:
|
||||
|
||||
| | 內容 |
|
||||
|---|---|
|
||||
| 效忠文件 | `system-dev/docs/3-specs/` 的技術軌規格(requirements / design / tasks 三件式) |
|
||||
| 可寫 | code、`tasks.md`(認領/新增)、`requirements.md`、`design.md` |
|
||||
| 可讀 | 上游指派的**當前 sprint 站段落**(只餵該段,不給整份) |
|
||||
| **禁止** | 改 `journeys.md`/`root.md`/任何 Gherkin ——**考生不能改考卷** |
|
||||
|
||||
> 考題不過就去把東西做對,不是去改考題。要改站或改考題 → 回報上游,由 PM 決定。
|
||||
|
||||
---
|
||||
|
||||
## 絕對鐵律(違反 = 停手)
|
||||
|
||||
1. **任何 code 變動前必須有對應規格**(`system-dev/docs/3-specs/[子系統]/design.md`)
|
||||
2. [技術棧限制,例如:前端只用 React,不引入其他框架]
|
||||
3. [其他專案特定限制]
|
||||
|
||||
找不到對應規格 → **停手問上游**,不要自行建立。
|
||||
|
||||
---
|
||||
|
||||
## 工作流程(強制)
|
||||
|
||||
開始任一任務,按順序:
|
||||
|
||||
1. 讀 `system-dev/wiki/status.md`(3 分鐘,了解當前狀態)
|
||||
2. 確認有對應規格(`system-dev/docs/3-specs/`)
|
||||
3. 在回覆開頭宣告:
|
||||
```
|
||||
📋 已讀規格:<路徑>
|
||||
🎯 對應 task:<編號>|服務站號:<S-n>
|
||||
🚧 執行範圍:<會動哪些檔案>
|
||||
```
|
||||
4. 完成後更新 `system-dev/wiki/status.md`
|
||||
|
||||
### task 一律掛站號
|
||||
|
||||
sprint 的單位是**一組站號**,不是一批 task。所以:
|
||||
|
||||
- **先認領**:對 task 池逐項問「這個 task 不做,指定站的 Gherkin 會掛嗎?」會掛才認領。
|
||||
- **認領不足才新增**:新增的 task **必須標注它服務哪一站**(無站號 = 格式錯誤,hook 會擋)。
|
||||
- **收工判準**=指定站的 Gherkin 全綠,**不是** task 全關。
|
||||
|
||||
---
|
||||
|
||||
## Wiki 讀取順序
|
||||
|
||||
| 檔案 | 時機 | 用途 |
|
||||
|------|------|------|
|
||||
| `system-dev/wiki/status.md` | session 開始第一件事 | 當前進度、下一步 |
|
||||
| `system-dev/wiki/mistakes.md` | 做新功能前 | 已知誤解 + 快速檢查清單 |
|
||||
| `system-dev/wiki/decisions-summary.md` | 遇到設計判斷時 | 架構決策快速查 |
|
||||
|
||||
> 開 session 由 `SessionStart` hook 自動注入 status 重點。沒自動接關 → 打 `/wiki-recall`。
|
||||
> status/wiki 是 **快照非即時狀態**:讀快照 **+ 核實快照**,不盲信。
|
||||
|
||||
---
|
||||
|
||||
## 規範索引
|
||||
|
||||
| 檔案 | 內容 |
|
||||
|------|------|
|
||||
| `system-dev/docs/README.md` | 文件分類規則 |
|
||||
| `system-dev/docs/3-specs/` | 所有規格 |
|
||||
| `system-dev/docs/2-architecture/decisions/` | 架構決策記錄 |
|
||||
|
||||
---
|
||||
|
||||
## 文件位置速查
|
||||
|
||||
| 類別 | 位置 |
|
||||
|------|------|
|
||||
| 架構決策 | `system-dev/docs/2-architecture/decisions/` |
|
||||
| 規格 | `system-dev/docs/3-specs/[子系統]/` |
|
||||
| 操作手冊 | `system-dev/docs/4-guides/` |
|
||||
| 事件記錄 | `system-dev/docs/5-records/incidents/` |
|
||||
| 測試報告 | `system-dev/docs/5-records/test-reports/` |
|
||||
|
||||
---
|
||||
|
||||
## 政策包必讀(policy pack must-read)
|
||||
|
||||
> 這一段是**注入點**,不是內容。若本實例裝了政策包(Claude Code plugin),
|
||||
> 它的 SessionStart hook 會把該政策的必讀推到這裡。沒裝政策包時這段是空的。
|
||||
>
|
||||
> 機制不靠你「知道」——hook 在鏈上就會攔、skill 在庫裡就會觸發。你照常工作即可。
|
||||
|
||||
<!-- policy-pack:must-read -->
|
||||
@@ -18,7 +18,7 @@
|
||||
Logseq 的原生任務**不是** GFM 的 `- [ ]` / `- [x]`,而是**大寫 marker 開頭的 block**:
|
||||
|
||||
```
|
||||
- TODO AI 查看 leo21c 內所有 Repo,找到本地 Repo 搬到 Gitea
|
||||
- TODO AI 盤點這台機器上所有 Repo,把本地 Repo 搬到託管站
|
||||
- DOING 建立知識總庫,可查所有子庫
|
||||
- DONE 手機和電腦 Logseq 可以被放進知識總庫
|
||||
```
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#
|
||||
# 來源:issue #16;設計:system-dev/docs/3-specs/tasks-project-projection/design.md
|
||||
#
|
||||
# ⚠️ sdt-instance-name-ok-file — 檔級豁免(實例專名檢查)
|
||||
# 理由:與 tasks-project-sync.yaml 同一組 **L2 政策包產物**(綁定某一家的工作流引擎)。
|
||||
# 帳記在這:**W3(政策包 plugin 化)時與 yaml 一起移出 template/**,屆時本豁免刪除。
|
||||
#
|
||||
# ── 為什麼有這支(職責邊界)──────────────────────────────────────
|
||||
# arcrun workflow 跑在遠端 CF Workers,沒有本地 fs / git / shell。
|
||||
# 所以「讀 tasks.md / git diff / 回寫 <!-- gh:id -->」這三件本地事
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
#
|
||||
# 來源:issue #16;設計:system-dev/docs/3-specs/tasks-project-projection/design.md
|
||||
#
|
||||
# ⚠️ sdt-instance-name-ok-file — 檔級豁免(實例專名檢查)
|
||||
# 理由:整支是 **L2 政策包產物**,不是 L1 框架內容——它綁定某一家的工作流引擎,
|
||||
# 「換一家公司就不成立」。它現在還躺在框架裡只是歷史包袱。
|
||||
# 帳記在這:**W3(政策包 plugin 化)時整組移出 template/**,屆時本豁免一併刪除。
|
||||
# 在那之前不做假性清理(把引擎名改寫成模糊詞=資訊消失、分層問題還在)。
|
||||
#
|
||||
# ── 這份 workflow 的職責邊界(很重要,別搞混)──────────────────
|
||||
# arcrun workflow 在 Cloudflare Workers / WASM 上「遠端」執行,沒有本地檔案系統、
|
||||
# 沒有 git、沒有 shell。所以「讀 tasks.md / 跑 git diff / 把 <!-- gh:id --> 回寫 md」
|
||||
|
||||
Reference in New Issue
Block a user