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
+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