Files
system-dev-template/scripts/check-legacy-paths.sh
T
Leo 6a49f25aef 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>
2026-08-05 23:56:48 +08:00

96 lines
3.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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