feat(install): 安裝完成等於驗過能用

install 寫完轉接檔後,把叫用鏈真的走一遍:轉接檔 → PATH 上的 tea-sdlc → 流程正本。

最脆弱的是中間那一環。套件裝在某個 Node 版本底下,換個版本就找不到了,而轉接檔本身
看起來完全正常——沒有這道驗證,使用者要到第一次打 /sdlc-plan 才發現,那時他已經離開
安裝的心智狀態很久了。所以不是查檔案在不在,而是真的到 PATH 上把 tea-sdlc 找出來執行
一次,再把取回的正本跟套件裡的那一份逐字比對:找不到、叫不動、或叫到的是另一份安裝,
三種都驗得出來。轉接檔則逐一回磁碟讀,比對存在且內容含正確的叫用行。

驗證不碰網路,也與 Gitea 登入、時間追蹤無關,所以無條件執行。

驗不過回 ok:false,但已經寫好的轉接檔一份都不刪。回滾在升級情境下是淨損失:原本有一組
能用的舊轉接檔,覆蓋後驗證失敗再刪掉,使用者就從「有點舊但能用」變成什麼都沒有;何況
最可能的病灶是「PATH 上找不到 tea-sdlc」,那不是轉接檔的問題。

為此 lib 多一個 Failure:有一種失敗是事情做完了、檔案也寫出去了,只是驗不過,那時最該
交出去的正是「已經寫了哪些、哪一段不通」。envelope 形狀不變,只是 {ok:false, error}
旁邊多一個 data,只讀 error.code 的呼叫端照常運作。

--dry-run 不寫入,也就沒有東西可驗,verify 標成 skipped。

Closes #59

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jeffery
2026-09-17 18:25:32 +08:00
co-authored by Claude Opus 5
parent c2ca7fbf07
commit 73b9cd9f75
8 changed files with 653 additions and 15 deletions
+12
View File
@@ -146,6 +146,18 @@ test('README 裡的 tea-sdlc 指令逐字拿去跑都認得,不會是寫給人
}
});
test('README 交代了安裝會自動驗證,以及驗不過時轉接檔不會被回滾', () => {
// 「驗不過但檔案還在」如果沒寫出來,使用者看到 ok:false 的第一個念頭會是自己去清乾淨重裝,
// 那正好是這個設計要避免的事
const text = readme();
const section = text.slice(text.indexOf('### 安裝完成等於驗過能用'), text.indexOf('## 更新 / 移除'));
assert.ok(section.length > 0, 'README 沒有交代安裝後的驗證');
assert.match(section, /ok:false/);
assert.match(section, /不.{0,4}回滾|一份都不刪/);
assert.match(section, /dry-run/);
});
test('模組邊界表指得到實際存在的檔案', () => {
const text = agents();