SDD 生命週期鐵律遷移:單一活性制度上線(portal-auth=active,其餘 paused/draft)

- 鋪檔(自 system-dev-template v1.15.0):SDD-LIFECYCLE.md+pending-changes.md
  +sdd-guard.sh(覆蓋舊版,加單一活性檢查)+sdd-check.md+sdd-active-check.sh
- settings.json PreToolUse(Write|Edit|MultiEdit)掛上 sdd-guard.sh
- 全部 SDD design.md 掛 frontmatter:portal-auth=active(現行 portal 線,
  #61 demo 四件套剛 merge);artifact-sharing=draft(零任務動工);
  其餘 16 份=paused(皆有未完成任務,無明顯死件,不硬 close)
- CLAUDE.md 加「SDD 生命週期鐵律」段(指向 SDD-LIFECYCLE.md+濃縮五條)
  +SDD 速查表改以 frontmatter status: active 為現行判準
- 驗證:sdd-active-check exit 0(恰 1 份 active);guard pipe-test code 檔
  exit 0 帶現行 SDD 提示;反向測試(造 2 份 active)guard exit 2/check exit 1 全擋

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
uncle6me-web
2026-07-17 17:03:16 +08:00
parent db0a39fdbd
commit 7bd7b4b26a
27 changed files with 327 additions and 15 deletions
+20
View File
@@ -4,6 +4,26 @@
--- ---
## 生命週期(單一活性鐵律,全文見 `system-dev/docs/3-specs/SDD-LIFECYCLE.md`
五條鐵律摘要:
1. **單一活性**:任何時刻整個 repo 只允許一份 `status: active` 的 SDD;所有開發任務對應它的 tasks,找不到對應任務 → 停下來問,不准直接做。
2. **禁止自行建立 SDD**:澄清問題→回答不動文件;任務層變更→更新現行 SDD 的 tasks(標日期與原因);規格層變更→走第 3 條。
3. **規格變更只有一條路**change proposal 寫進 `system-dev/docs/3-specs/pending-changes.md`(摘要+觸發原因+影響分析),然後**停止**等使用者「confirm」。
4. **開新 SDD 的唯一時機**:使用者 confirm 後——先把舊 SDD 未完成任務逐條搬入新 SDD(做完前不准寫 code)→ 舊的標 `closed` + `superseded_by` 移入 `archive/` → 新 SDD changelog 記繼承 → 列搬移/作廢清單請最終確認。
5. **每次 session 開始**先讀 active SDD 與 pending-changes.md,回報三個數字:
```
📐 現行規格:〈SDD 名稱〉
📋 未完成任務:N
⚖️ 待裁決 proposalM
```
若出現**兩份 active=規則已被違反,當場糾正**(收斂到一份,其餘 paused/closed)。
---
## 執行流程 ## 執行流程
### 第一步:理解任務 ### 第一步:理解任務
+82 -14
View File
@@ -1,10 +1,16 @@
#!/bin/bash #!/bin/bash
# PreToolUse hook — 動 code 前檢查有沒有對應 SDD # PreToolUse hook — 動 code 前檢查 SDD 單一活性 SDD 鐵律(issue #6
# wishlist §2:把 /sdd-check 從「命令要人打」升級成「hook 自動攔」。 # wishlist §2:把 /sdd-check 從「命令要人打」升級成「hook 自動攔」。
# 生命週期規則全文:system-dev/docs/3-specs/SDD-LIFECYCLE.md
# #
# 掛在 settings.json 的 PreToolUsematcher: Write|Edit)。 # 掛在 settings.json 的 PreToolUsematcher: Write|Edit)。
# stdin 收到 JSON{ tool_name, tool_input: { file_path, ... } } # stdin 收到 JSON{ tool_name, tool_input: { file_path, ... } }
# 行為:動到 code 檔(.ts/.go/...)但 system-dev/docs/3-specs/ 下沒有任何 SDD → 警告(exit 2 擋)。 # 行為:
# 1. status: active 的 SDD > 1 份 → 單一活性鐵律已被違反,**不論寫什麼檔**一律擋(exit 2),
# 先收斂到一份再說。
# 2. 動 code 檔(.ts/.go/...)→ 需要「恰好 1 份」active SDD;0 份 → 擋。
# 3. 向下相容:3-specs 下完全沒有任何 design.md 帶 frontmatter(老 repo 尚未遷移生命週期制度)
# → 退回舊行為:有 design.md 就放行+提醒,沒有才擋。避免 template update 後老 repo 立刻全紅。
# #
# 誠實限制(抄 arcrun):只擋語法層明顯違規(直接寫 code 檔)。 # 誠實限制(抄 arcrun):只擋語法層明顯違規(直接寫 code 檔)。
# 藏在 helper 裡、用 bash 繞道的改動擋不到。 # 藏在 helper 裡、用 bash 繞道的改動擋不到。
@@ -24,6 +30,42 @@ fi
# 拿不到路徑 → 不擋(容錯,寧可放過也不誤殺) # 拿不到路徑 → 不擋(容錯,寧可放過也不誤殺)
[ -z "$FILE_PATH" ] && exit 0 [ -z "$FILE_PATH" ] && exit 0
SPECS_DIR="system-dev/docs/3-specs"
# ── 統計 active / frontmatter ──────────────────────
# 排除 archive/(已封存)與 TEMPLATE(範本自帶 status: draft frontmatter,不算數——
# 否則 update 一鋪新版 TEMPLATE-sdd,老 repo 就被誤判「已遷移」而全紅,向下相容破功)。
# frontmatter 判定=design.md 前 10 行有 ^status: 行(機器可查,見 SDD-LIFECYCLE.md)。
ACTIVE_COUNT=0
FM_COUNT=0
ACTIVE_LIST=""
if [ -d "$SPECS_DIR" ]; then
while IFS= read -r f; do
[ -n "$f" ] || continue
HEAD10=$(head -10 "$f" 2>/dev/null || true)
if printf '%s\n' "$HEAD10" | grep -q '^status:[[:space:]]*'; then
FM_COUNT=$((FM_COUNT + 1))
if printf '%s\n' "$HEAD10" | grep -q '^status:[[:space:]]*active'; then
ACTIVE_COUNT=$((ACTIVE_COUNT + 1))
ACTIVE_LIST="${ACTIVE_LIST}${f}
"
fi
fi
done < <(find "$SPECS_DIR" -name 'design.md' -not -path '*TEMPLATE*' -not -path '*/archive/*' 2>/dev/null)
fi
# ── 鐵律 1:單一活性被違反(active > 1)→ 不論寫什麼檔一律擋 ──
if [ "$ACTIVE_COUNT" -gt 1 ]; then
cat >&2 <<EOF
🚫 SDD 單一活性鐵律違反:偵測到 ${ACTIVE_COUNT} 份 status: active 的 SDD(任何時刻整個 repo 最多一份):
${ACTIVE_LIST}
請先收斂到一份:其餘改 status: paused / closedclosed 且被取代者填 superseded_by 並移入 3-specs/archive/)。
規則全文見 system-dev/docs/3-specs/SDD-LIFECYCLE.md。收斂前擋下所有寫檔。
(本 hook 攔 Write/Edit;修 frontmatter 可用 bash 直改,或由人裁決哪份是現行。)
EOF
exit 2
fi
# 只管 code 檔。docs/markdown/設定檔等放行。 # 只管 code 檔。docs/markdown/設定檔等放行。
case "$FILE_PATH" in case "$FILE_PATH" in
*.ts|*.tsx|*.js|*.jsx|*.go|*.py|*.rs|*.java|*.rb|*.php|*.c|*.cpp|*.h|*.hpp|*.swift|*.kt) ;; *.ts|*.tsx|*.js|*.jsx|*.go|*.py|*.rs|*.java|*.rb|*.php|*.c|*.cpp|*.h|*.hpp|*.swift|*.kt) ;;
@@ -36,28 +78,54 @@ case "$FILE_PATH" in
*_test.*|*.test.*|*.spec.*|*/tests/*|*/test/*) exit 0 ;; *_test.*|*.test.*|*.spec.*|*/tests/*|*/test/*) exit 0 ;;
esac esac
# system-dev/docs/3-specs/ 下完全沒有 design.md → 攔 # ── 向下相容:整個 3-specs 沒有任何帶 frontmatter 的 design.md ──
SDD_COUNT=0 # =老 repo 還沒遷移生命週期制度 → 退回舊行為(有 design.md 就放行+提醒),
if [ -d "system-dev/docs/3-specs" ]; then # 避免 template update 一裝新 hook,老 repo 所有 code 寫入立刻全紅。
SDD_COUNT=$(find system-dev/docs/3-specs -name 'design.md' -not -path '*TEMPLATE*' 2>/dev/null | wc -l | tr -d ' ') if [ "$FM_COUNT" -eq 0 ]; then
fi SDD_COUNT=0
if [ -d "$SPECS_DIR" ]; then
SDD_COUNT=$(find "$SPECS_DIR" -name 'design.md' -not -path '*TEMPLATE*' -not -path '*/archive/*' 2>/dev/null | wc -l | tr -d ' ')
fi
if [ "$SDD_COUNT" -eq 0 ]; then if [ "$SDD_COUNT" -eq 0 ]; then
cat >&2 <<EOF cat >&2 <<EOF
🚫 SDD 協議攔截:要動 code 檔 ($FILE_PATH),但 system-dev/docs/3-specs/ 下找不到任何 SDD。 🚫 SDD 協議攔截:要動 code 檔 ($FILE_PATH),但 ${SPECS_DIR}/ 下找不到任何 SDD。
絕對鐵律:任何 code 變動前必須有對應 SDDdesign.md 絕對鐵律:任何 code 變動前必須有對應 SDDdesign.md,且遵守單一活性生命週期
system-dev/docs/3-specs/SDD-LIFECYCLE.md)。
請先: 請先:
1. 確認這個改動屬於哪個子系統 1. 確認這個改動屬於哪個子系統
2. 在 system-dev/docs/3-specs/[子系統]/ 建立 design.md(可用 /sdd-check 協助) 2. 在 ${SPECS_DIR}/[子系統]/ 建立 design.md(可用 /sdd-check 協助)frontmatter 標 status: active
3. 在回覆開頭宣告已讀 SDD + 對應 task 3. 在回覆開頭宣告已讀 SDD + 對應 task
小修改(修 bug、改文字)若確定豁免,請明確說明範圍後由人放行。
EOF
exit 2
fi
# 舊行為放行 + 提醒遷移(stderr 警告,不擋)
echo "📋 提醒:${SPECS_DIR}/ 有 SDD 但尚未掛生命週期 frontmatter(老結構)。動手前確認已讀對應 design.md;建議依 SDD-LIFECYCLE.md 補 status 標記(現行那份標 active)。" >&2
exit 0
fi
# ── 新行為:寫 code 檔需「恰好 1 份」active SDD ──
if [ "$ACTIVE_COUNT" -eq 0 ]; then
cat >&2 <<EOF
🚫 SDD 協議攔截:要動 code 檔 ($FILE_PATH),但 ${SPECS_DIR}/ 下沒有任何 status: active 的 SDD。
單一活性鐵律:所有開發任務唯一對應源=那份 active SDD(規則見 system-dev/docs/3-specs/SDD-LIFECYCLE.md)。
請先(擇一,都是人的決定,CC 不得自行建 SDD):
1. 把現行規格的 design.md frontmatter 標成 status: active(一份、只能一份)
2. 或依 SDD-LIFECYCLE.md 第 3、4 條:proposal 進 pending-changes.md → 使用者 confirm → 開新 SDD 標 active
然後在回覆開頭宣告已讀 active SDD + 對應 task。
小修改(修 bug、改文字)若確定豁免,請明確說明範圍後由人放行。 小修改(修 bug、改文字)若確定豁免,請明確說明範圍後由人放行。
EOF EOF
exit 2 exit 2
fi fi
# 有 SDD:放行,留痕提醒要宣告(stderr 警告,不擋) # 恰好 1 份 active:放行,留痕提醒要宣告(stderr 警告,不擋)
echo "📋 提醒:system-dev/docs/3-specs/ 下有 SDD。動手前請確認已讀對應 design.md 並在回覆宣告。" >&2 printf '📋 提醒:現行 active SDD\n%s動手前請確認已讀它的 design.md、對應到 tasks,並在回覆宣告。\n' "$ACTIVE_LIST" >&2
exit 0 exit 0
+5
View File
@@ -25,6 +25,11 @@
"type": "command", "type": "command",
"command": "bash .claude/hooks/wiki-secret-scan.sh", "command": "bash .claude/hooks/wiki-secret-scan.sh",
"timeout": 5 "timeout": 5
},
{
"type": "command",
"command": "bash .claude/hooks/sdd-guard.sh",
"timeout": 5
} }
] ]
}, },
+17 -1
View File
@@ -29,6 +29,19 @@
--- ---
## SDD 生命週期鐵律(2026-07-17 leo 拍板,全文見 `system-dev/docs/3-specs/SDD-LIFECYCLE.md`
> 現行規格以 design.md frontmatter `status: active` 為準(機器可查),
> hook `.claude/hooks/sdd-guard.sh` `system-dev/scripts/sdd-active-check.sh` 強制。
1. **單一活性**:任何時刻整個 repo 最多一份 `status: active` 的 SDD;所有開發任務必須對應這份 SDD 的 tasks,找不到對應 → 停下來問。
2. **CC 禁止自行建立 SDD**:任何情況下不得主動建新 SDD(既有 hook 規則 4.3 同源)。
3. **規格層變更只有一條路**:寫 change proposal 進 `system-dev/docs/3-specs/pending-changes.md`(變更摘要+影響分析)然後**停止**,等使用者明說「confirm」;沒 confirm 就照現行 SDD 繼續。任務層小改直接更新現行 tasks 並標日期原因。
4. **開新 SDDconfirm 後)**:先把舊 SDD 未完成且仍有效的任務**逐條搬入**新 SDD——搬完前不准寫任何程式碼;舊 SDD 改 `closed``superseded_by` 並移入 `3-specs/archive/`;向使用者列「已搬移/已作廢」清單請最終確認。
5. **每次 session 開始**:先讀現行 active SDD 與 pending-changes.md,回報三個數字——「現行規格〈名稱〉+未完成任務 N+待裁決 proposal M」——再開工。
---
## 工作流程(強制) ## 工作流程(強制)
開始任一任務,按順序: 開始任一任務,按順序:
@@ -78,9 +91,12 @@
## SDD 位置速查 ## SDD 位置速查
> **現行(activeSDD 唯一判準=frontmatter `status: active`**2026-07-17 起),查法:`bash system-dev/scripts/sdd-active-check.sh`。下表僅路徑索引,「進行中」標記以 frontmatter 為準。
| 子系統 | 路徑 | | 子系統 | 路徑 |
|-------|------| |-------|------|
| **進行中** Credential Primitives WASM | `docs/3-specs/arcrun/credential-primitives-wasm/` | | **現行 active** RAG Portal 多人授權 | `system-dev/docs/3-specs/portal-auth/` |
| Credential Primitives WASMpaused | `docs/3-specs/arcrun/credential-primitives-wasm/` |
| arcrun 總進度 | `docs/3-specs/arcrun/arcrun.md` | | arcrun 總進度 | `docs/3-specs/arcrun/arcrun.md` |
| Auth Recipe 系統 | `docs/3-specs/arcrun/auth-recipe.md` | | Auth Recipe 系統 | `docs/3-specs/arcrun/auth-recipe.md` |
| Landing Page | `docs/3-specs/arcrun/landing-page.md` | | Landing Page | `docs/3-specs/arcrun/landing-page.md` |
+39
View File
@@ -0,0 +1,39 @@
# SDD 生命週期鐵律(不可違反)
> 來源:leo 2026-07-17 拍板。
> 適用:`system-dev/docs/3-specs/` 下的「規格 SDD」(requirements/design/tasks 三件式資料夾)。
> **不適用**:派工表/sprint 檔、journeys/ 卷宗、TEMPLATE-sdd、README、pending-changes.md——它們不是 SDD,不掛 status。
## 狀態標記(機器可查)
每個 SDD 資料夾的 `design.md` 最上方掛 YAML frontmatter
```yaml
---
status: active # active | draft | paused | closed
superseded_by: "" # closed 且被取代時填接替的 SDD 資料夾名
---
```
- `active`:現行規格,全 repo 開發任務唯一對應源。**任何時刻整個 repo 最多一份。**
- `draft`:起草中,尚未採納。
- `paused`:動過工、暫停中;恢復=升回 active(先收掉現任 active)或被新 SDD 繼承。
- `closed`:已完成或被取代;被取代者填 `superseded_by` 並移入 `3-specs/archive/`
## 五條鐵律
1. **單一活性**:任何時刻只允許一份 `status: active`。所有開發任務必須對應這份 SDD 的 tasks。找不到對應任務 → 停下來問,不准直接做。
2. **禁止自行建立 SDD**:CC 在任何情況下不得主動建新 SDD。收到使用者意見先分類:澄清問題→回答即可不動文件;任務層變更(不影響核心設計)→更新現行 SDD 的 tasks 區段並標日期與原因;規格層變更(核心設計/方向改變)→走第 3 條,不准直接改 spec。
3. **規格變更只有一條路**:產出 change proposal 寫入 `system-dev/docs/3-specs/pending-changes.md`(變更摘要與觸發原因+影響分析:現行 SDD 哪些任務作廢/修改/不受影響/尚未完成),然後**停止**,等使用者明說「confirm」。沒 confirm 就繼續依現行 SDD 工作。多個 proposal 可並存緩衝區、由人一次裁決——CC 的速度導向影響分析,不是規格增生。
4. **開新 SDD 的唯一時機**:使用者 confirm 一份規格層 proposal 時,依序:
a. 舊 SDD 未完成且仍有效的任務**逐條搬入**新 SDD 的 tasks——**這步做完前不准寫任何程式碼**(強迫顯式盤點,遺漏會在 d 的清單被看到,而不是三天後才發現)。
b. 舊 SDD frontmatter 改 `status: closed, superseded_by: <新SDD>`,資料夾移入 `3-specs/archive/`
c. 新 SDD 的 changelog 首行記錄:繼承自哪份、為何取代。
d. 向使用者列出「已搬移任務清單」與「已作廢任務清單」請求最終確認。
5. **每次 session 開始**:先讀現行 active SDD 與 pending-changes.md,回報三個數字——「現行規格〈名稱〉+未完成任務 N+待裁決 proposal M」——再開始工作。若回報出現兩份 active=規則已被違反,當場糾正。
## 硬約束(不信任單點自律,用結構保證不變量)
- `.claude/hooks/sdd-guard.sh`PreToolUse Write|Edit):active 數 >1 → 任何寫檔一律擋;寫 code 檔需恰好 1 份 active。
- `scripts/sdd-active-check.sh`:獨立檢查,pre-commit / CI 可掛,違反 exit 1。
- 誠實限制:hook 只擋語法層明顯違規,繞道可行但留痕可審;不聲稱不可繞過。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design Document: arcrun MVP # Design Document: arcrun MVP
## Overview ## Overview
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design Document: u6u Platform Evolution # Design Document: u6u Platform Evolution
## Overview ## Overview
@@ -1,3 +1,8 @@
---
status: draft
superseded_by: ""
---
# Artifact Sharing — Design # Artifact Sharing — Design
> 狀態:草稿(待 review > 狀態:草稿(待 review
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Auth Recipe System — SDD # Auth Recipe System — SDD
> 文件類型:SDDSoftware Design Document > 文件類型:SDDSoftware Design Document
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design Document: Credential Primitives TS → WASM 改寫 # Design Document: Credential Primitives TS → WASM 改寫
## Overview ## Overview
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Frontend Redesign — Design # Frontend Redesign — Design
> 讀此檔前請先讀 `requirements.md``design-source/index.html` > 讀此檔前請先讀 `requirements.md``design-source/index.html`
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design: KBDB Base —— 原子化萬用表(self-hosted 資料底座 + 官方核心) # Design: KBDB Base —— 原子化萬用表(self-hosted 資料底座 + 官方核心)
> 2026-06-07 richblack 拍板。來源:壓測報告(`test_arcrun/docs/壓測報告.md`)暴露 self-hosted 無資料層 → > 2026-06-07 richblack 拍板。來源:壓測報告(`test_arcrun/docs/壓測報告.md`)暴露 self-hosted 無資料層 →
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# arcrun.dev Landing Page — SDD # arcrun.dev Landing Page — SDD
> **目標**:給工程師一個門面,可以取得 API Key、管理 Key、探索 APISwagger),同時藉此獲得會員 Email。 > **目標**:給工程師一個門面,可以取得 API Key、管理 Key、探索 APISwagger),同時藉此獲得會員 Email。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design Document: arcrun SDK Libraries + Website # Design Document: arcrun SDK Libraries + Website
## Overview ## Overview
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# search-console — arcrun 自帶搜尋/控制台頁(Gitea Arcrun#3 授權新建) # search-console — arcrun 自帶搜尋/控制台頁(Gitea Arcrun#3 授權新建)
> 授權:Gitea `Leo/Arcrun#3`leo 2026-07-02 拍板「本 issue 即 leo 授權」)。 > 授權:Gitea `Leo/Arcrun#3`leo 2026-07-02 拍板「本 issue 即 leo 授權」)。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design: Component Gatekeeping(零件投稿真把關) # Design: Component Gatekeeping(零件投稿真把關)
> 2026-05-29。實作 requirements.md 的 R1-R6。 > 2026-05-29。實作 requirements.md 的 R1-R6。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# SDD: arcrun Component Registry 正典化(Component Registry Canon # SDD: arcrun Component Registry 正典化(Component Registry Canon
> 2026-05-07 建立。狗糧發現的根本問題:registry 活著但 index 空的,AI 找不到零件就會繞回 Python。 > 2026-05-07 建立。狗糧發現的根本問題:registry 活著但 index 空的,AI 找不到零件就會繞回 Python。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design: 資料外流警示(Data Exfiltration Warning # Design: 資料外流警示(Data Exfiltration Warning
> 2026-05-30。實作 requirements.md。**本 design 需 richblack review 後才動 code。** > 2026-05-30。實作 requirements.md。**本 design 需 richblack review 後才動 code。**
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design: LI (LLM Interface) for arcrun # Design: LI (LLM Interface) for arcrun
> v0.1 — 2026-05-16 > v0.1 — 2026-05-16
@@ -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 日期。)
@@ -1,3 +1,8 @@
---
status: active
superseded_by: ""
---
# portal-auth — DesignRAG Portal 多人授權) # portal-auth — DesignRAG Portal 多人授權)
> 狀態:**定案**2026-07-14 總管審過+leo 裁 D-4=A/D-8=adminPR #49 > 狀態:**定案**2026-07-14 總管審過+leo 裁 D-4=A/D-8=adminPR #49
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# SDD: arcrun Recipe System(容器 + Recipe 模式) # SDD: arcrun Recipe System(容器 + Recipe 模式)
> 2026-05-07 建立。吃狗糧寫 wiki 合成 workflow 時撞牆發現的平台缺口。 > 2026-05-07 建立。吃狗糧寫 wiki 合成 workflow 時撞牆發現的平台缺口。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# SDD: Resumable Workflowwebhook callback 喚醒) # SDD: Resumable Workflowwebhook callback 喚醒)
> 2026-05-07 建立。狗糧寫 wiki 合成 workflow 時,Mira daemon 對長草稿(>2KB)切非同步模式回 `{pending, task_id, poll_url}`cypher-executor 沒處理就直接傳下游。 > 2026-05-07 建立。狗糧寫 wiki 合成 workflow 時,Mira daemon 對長草稿(>2KB)切非同步模式回 `{pending, task_id, poll_url}`cypher-executor 沒處理就直接傳下游。
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# thin-shell-alignment — Design # thin-shell-alignment — Design
> **狀態**:草案,待確認。對應 `requirements.md` > **狀態**:草案,待確認。對應 `requirements.md`
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# Design: 用戶 CC harnessacr install-harness # Design: 用戶 CC harnessacr install-harness
> 2026-06-03。richblack 已授權建此 SDD(白名單已加)。**待 review design 後動 code。** > 2026-06-03。richblack 已授權建此 SDD(白名單已加)。**待 review design 後動 code。**
@@ -1,3 +1,8 @@
---
status: paused
superseded_by: ""
---
# workflow-discovery — Design # workflow-discovery — Design
> **狀態**:草案,待確認。對應 `requirements.md` > **狀態**:草案,待確認。對應 `requirements.md`
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# sdd-active-check.sh — 單一活性 SDD 獨立硬約束(SDD 生命週期鐵律,issue #6
# 規則全文:system-dev/docs/3-specs/SDD-LIFECYCLE.md
#
# 用法:bash sdd-active-check.sh [specs目錄]
# 參數 1(可選)=specs 目錄,預設 system-dev/docs/3-specs
#
# 行為:統計 status: active 的 design.mddesign.md 前 10 行有 ^status: active
# 排除 archive/ 與 TEMPLATE)——
# >1 份 → stderr 列出清單,exit 1(違反單一活性)
# ≤1 份 → exit 0
#
# pre-commit 掛法(.git/hooks/pre-commit,記得 chmod +x):
# #!/bin/sh
# bash system-dev/scripts/sdd-active-check.sh || exit 1
# CI 也是同一行,違反即紅。
#
# 誠實限制:與 sdd-guard.sh 同精神——只做語法層機械檢查,繞道可行但留痕可審,
# 不聲稱不可繞過。價值是「不變量被違反時一定有機器出聲」。
set -euo pipefail
SPECS_DIR="${1:-system-dev/docs/3-specs}"
# 沒有 specs 目錄(沒裝 SDD 模組)→ 無事可查,放行
[ -d "$SPECS_DIR" ] || exit 0
ACTIVE_COUNT=0
ACTIVE_LIST=""
while IFS= read -r f; do
[ -n "$f" ] || continue
if head -10 "$f" 2>/dev/null | grep -q '^status:[[:space:]]*active'; then
ACTIVE_COUNT=$((ACTIVE_COUNT + 1))
ACTIVE_LIST="${ACTIVE_LIST}${f}
"
fi
done < <(find "$SPECS_DIR" -name 'design.md' -not -path '*TEMPLATE*' -not -path '*/archive/*' 2>/dev/null)
if [ "$ACTIVE_COUNT" -gt 1 ]; then
cat >&2 <<EOF
🚫 SDD 單一活性鐵律違反:${SPECS_DIR}/ 下有 ${ACTIVE_COUNT} 份 status: active 的 SDD(任何時刻最多一份):
${ACTIVE_LIST}
請收斂到一份:其餘改 status: paused / closedclosed 且被取代者填 superseded_by 並移入 archive/)。
規則見 system-dev/docs/3-specs/SDD-LIFECYCLE.md。
EOF
exit 1
fi
exit 0