6a49f25aef
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>
96 lines
3.9 KiB
Bash
Executable File
96 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
||
# check-legacy-paths.sh — 相容閘:已發佈的安裝/更新腳本會抓的每個遠端路徑,都必須還在
|
||
#
|
||
# 這支存在的理由(SDD jdd-dual-profile 發現⑦ + 決策 D3):
|
||
# install.sh / update.sh 是**逐檔 curl**:檔案清單與遠端路徑**寫死在腳本裡**。
|
||
# 而 update.sh 的「自我更新」在腳本**尾端**——舊實例這一輪跑的是**舊腳本**。
|
||
# ⇒ 只要框架把某個既有檔搬走/改名,舊實例的那一輪就是**整排 404**,
|
||
# 而且它們不會自動好:更新機制本身壞了,就沒有下一次更新來修它。
|
||
#
|
||
# 前科:1.16.0「update/install 來源改指 Gitea」——來源一改,
|
||
# 舊實例的自動更新當場死掉(CHANGELOG 1.16.0 有記)。同一種病。
|
||
#
|
||
# 所以鐵律是:**遠端路徑對既有實例是契約,只增不移。**
|
||
# 要搬版面 → 先在原路徑留相容檔(轉址說明/原內容),確認本閘綠了才准動。
|
||
#
|
||
# 作法:
|
||
# 從「已發佈版本」的 install.sh / update.sh 裡抽出所有 $REPO_URL/... $TEMPLATE_URL/...
|
||
# $SCRIPTS_URL/... 引用,映射回本 repo 的實體路徑,逐一確認檔案存在。
|
||
#
|
||
# 誠實限制:
|
||
# · 只驗「路徑還在不在」,不驗內容還對不對(舊腳本抓到新內容仍可能語意不相容)。
|
||
# · 基準是 git 裡的已發佈版本(預設 HEAD);再更老的版本若引用過更多路徑,
|
||
# 本閘看不到——要驗更早的版本,用 BASE=<commit> 指定。
|
||
#
|
||
# 用法:
|
||
# bash scripts/check-legacy-paths.sh # 以 HEAD 為已發佈基準
|
||
# BASE=dc4fe67 bash scripts/check-legacy-paths.sh
|
||
set -euo pipefail
|
||
|
||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
cd "$REPO_ROOT"
|
||
|
||
BASE="${BASE:-HEAD}"
|
||
|
||
# ── 取出基準版本的兩支腳本 ────────────────────────────
|
||
TMP="$(mktemp -d)"
|
||
trap 'rm -rf "$TMP"' EXIT
|
||
|
||
for s in install.sh update.sh; do
|
||
if ! git show "$BASE:scripts/$s" > "$TMP/$s" 2>/dev/null; then
|
||
echo "⚠️ 基準 $BASE 沒有 scripts/$s,略過" >&2
|
||
: > "$TMP/$s"
|
||
fi
|
||
done
|
||
|
||
# ── 抽出遠端引用 → 映射成本地實體路徑 ──────────────────
|
||
# $REPO_URL/x → template/x
|
||
# $TEMPLATE_URL/x → template/x
|
||
# $SCRIPTS_URL/x → scripts/x
|
||
extract_paths() {
|
||
grep -oE '\$\{?(REPO_URL|TEMPLATE_URL|SCRIPTS_URL)\}?/[A-Za-z0-9._/-]+' "$1" 2>/dev/null \
|
||
| sed -e 's|\${*REPO_URL}*/|template/|' \
|
||
-e 's|\${*TEMPLATE_URL}*/|template/|' \
|
||
-e 's|\${*SCRIPTS_URL}*/|scripts/|' \
|
||
|| true
|
||
}
|
||
|
||
ALL="$( { extract_paths "$TMP/install.sh"; extract_paths "$TMP/update.sh"; } | sort -u )"
|
||
|
||
if [ -z "$ALL" ]; then
|
||
echo "⚠️ 在 $BASE 的腳本裡找不到任何遠端引用——抽取規則可能過時,本閘等同關閉" >&2
|
||
exit 1
|
||
fi
|
||
|
||
TOTAL=0
|
||
MISSING=0
|
||
MISSING_LIST=""
|
||
|
||
while IFS= read -r p; do
|
||
[ -z "$p" ] && continue
|
||
TOTAL=$((TOTAL + 1))
|
||
if [ ! -e "$p" ]; then
|
||
MISSING=$((MISSING + 1))
|
||
MISSING_LIST="${MISSING_LIST} ✗ ${p}"$'\n'
|
||
fi
|
||
done <<< "$ALL"
|
||
|
||
if [ "$MISSING" -gt 0 ]; then
|
||
cat >&2 <<EOF
|
||
════════════════════════════════════════════════
|
||
❌ 相容閘:已發佈腳本會抓的路徑不見了($MISSING / $TOTAL)
|
||
════════════════════════════════════════════════
|
||
$MISSING_LIST
|
||
後果(不是理論,是 1.16.0 真的發生過):
|
||
舊實例跑 update 時對上面每個路徑 curl 404 → 更新失敗 →
|
||
**更新機制本身壞掉,之後也不會有下一次更新來修它**。
|
||
|
||
正解:搬版面時在原路徑留相容檔(轉址說明或原內容),
|
||
本閘綠了才准繼續。遠端路徑是契約,只增不移。
|
||
EOF
|
||
exit 1
|
||
fi
|
||
|
||
echo "✅ 相容閘:已發佈腳本(基準 $BASE)引用的 $TOTAL 個路徑全部還在"
|
||
exit 0
|