部署收尾刷新 current 連結農場,讓升版後的技能路徑不再指著舊版 #61

Merged
admin merged 2 commits from feat/refresh-current-link-farm-on-deploy into develop 2026-09-03 04:40:24 +00:00
Member

摘要

  • 需求描述:$JSC_HOME/current 這組不帶版本的符號連結是所有跨外掛腳本呼叫的根,但沒有任何東西會更新它們,只有接線腳本會更新其中一條。升版之後連結還指著舊版,技能照字面路徑跑到舊腳本,而失敗無聲。部署收尾改成刷新整組連結。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
tools/deploy.sh 新增六個函式與收尾的刷新呼叫,install 與 update 兩種模式下把每一條連結指到這次實際安裝的版本目錄;新增 link 輸出行
skills/deploy/SKILL.md 把刷新行為與 link 行的判讀寫進流程;另修正一句因這次改動而失效的敘述
references/behaviors.md deploy 四列跟著更新,可驗證跡象能驗到連結指向正確
README.md tools/deploy.sh 那一列補上連結農場行為
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 版號 0.3.2 升到 0.3.3

設計重點

  • 為什麼是部署來做。 部署本來就知道裝了哪些 domain、裝到哪個版本,資訊最齊。接線腳本對 jsc-hooks 那一條的特例保留不動——那條有自指風險,必須從實體路徑跑,是另一個主題。
  • 基準 CLI 只有一支寫。 連結農場只有一組,不可能同時指向五個 CLI 的副本。而部署是每支 CLI 一個 sub agent 平行跑的,五支都寫會互相覆寫,最後指到哪一份是隨機的、出事重現不出來。基準取 claude、codex、copilot、kiro 之中第一支找得到的,判定方式與 CLI 偵測一致,所以五個平行行程算出同一個答案。
  • antigravity 一律不當基準。 它的來源是本地 clone,而那份 clone 明文允許是維護者的開發樹——有未提交變更時會刻意不 pull。把全機器的路徑指到一份做到一半的樹,正好就是這次要修掉的那種無聲跑錯腳本。
  • 版本目錄要有 plugin.json 才算數。 裝到一半的目錄沒有它,挑到會讓連結指向不完整的外掛,而且照樣不報錯。本身是符號連結的那一層也跳過,指過去只是多繞一層,原目標一清就跟著斷。
  • 解除安裝的判準是「連結還在、指向卻沒了」。 不是「這輪解除安裝過這個 domain」——只解除安裝其中一支 CLI 時,連結可能還指著另一支手上完好的副本,那一條必須留著。斷掉的連結不清,等於對外宣稱一支已經不在機器上的外掛還裝著。
  • 建立失敗印一行繼續,不記成失敗。 這一段跑在外掛都裝好之後,部署本身已經成功;記成失敗會連帶跳過重啟閘門與收尾,操作者拿到的是一台明明裝好卻被說成失敗的機器。缺陷仍然看得見,因為輸出多了一行 link ... fail,技能文件把它接到 degraded。
  • 目標存在但不是符號連結時不覆寫。 ln -sfn 對著實體目錄下手會把連結建進那個目錄裡,農場當場壞掉還不會報錯;改用強制刪除更糟,那是這支腳本沒建過、也可能沒有第二份的內容。判準與接線腳本的守衛一致。
  • 刷新排在重啟閘門之前。 重啟閘門的第一順位候選就在 current/jsc-hooks 底下,先刷新才不會撞上舊版路徑。

測試結果

  • 新增的輸出行是 link<TAB>{domain}<TAB>{狀態}<TAB>{連結路徑}<TAB>{指向或原因},狀態五選一:ok、removed、skip、fail、dryrun。第五欄在 ok 與 dryrun 時就是指向,呼叫端可以直接取用。
  • -n 的 dry-run 實測,基準 CLI 印出每一條連結的預定指向;非基準的 CLI 只印一行 link - skip,說明這一輪的基準是誰。
  • 四條分支都在隔離的 JSC_HOME 底下實測過,沒有真的跑部署:ok 會把刻意改成舊版的連結重指回新版,removed 清掉斷連結,skip 對實體目錄不動手,fail 訊息在取不到版本目錄時出現。
  • lint-scripts.sh、check-behaviors.sh、ste100-lint.sh 對這個存放庫都回結束碼 0。註解掃描也回 0。
  • 一句既有敘述因這次改動而失效,已一併修正:技能文件原本寫 current 底下沒有 jsc-cli,刷新之後那條連結會存在。改成講清楚它仍然靠不住——第一次建起那條連結的正是這一輪,沒部署過的機器、或上一輪刷新失敗的機器,那一條不在或還停在舊版。所以技能自己的腳本仍然走外掛基底目錄,只是理由從「那裡沒有」換成「那裡靠不住」。

前置 Push Request

  • 無
## 摘要 - 需求描述:`$JSC_HOME/current` 這組不帶版本的符號連結是所有跨外掛腳本呼叫的根,但沒有任何東西會更新它們,只有接線腳本會更新其中一條。升版之後連結還指著舊版,技能照字面路徑跑到舊腳本,而失敗無聲。部署收尾改成刷新整組連結。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/deploy.sh` | 新增六個函式與收尾的刷新呼叫,install 與 update 兩種模式下把每一條連結指到這次實際安裝的版本目錄;新增 `link` 輸出行 | | `skills/deploy/SKILL.md` | 把刷新行為與 `link` 行的判讀寫進流程;另修正一句因這次改動而失效的敘述 | | `references/behaviors.md` | `deploy` 四列跟著更新,可驗證跡象能驗到連結指向正確 | | `README.md` | `tools/deploy.sh` 那一列補上連結農場行為 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 版號 0.3.2 升到 0.3.3 | ## 設計重點 - **為什麼是部署來做。** 部署本來就知道裝了哪些 domain、裝到哪個版本,資訊最齊。接線腳本對 `jsc-hooks` 那一條的特例保留不動——那條有自指風險,必須從實體路徑跑,是另一個主題。 - **基準 CLI 只有一支寫。** 連結農場只有一組,不可能同時指向五個 CLI 的副本。而部署是每支 CLI 一個 sub agent 平行跑的,五支都寫會互相覆寫,最後指到哪一份是隨機的、出事重現不出來。基準取 claude、codex、copilot、kiro 之中第一支找得到的,判定方式與 CLI 偵測一致,所以五個平行行程算出同一個答案。 - **antigravity 一律不當基準。** 它的來源是本地 clone,而那份 clone 明文允許是維護者的開發樹——有未提交變更時會刻意不 pull。把全機器的路徑指到一份做到一半的樹,正好就是這次要修掉的那種無聲跑錯腳本。 - **版本目錄要有 `plugin.json` 才算數。** 裝到一半的目錄沒有它,挑到會讓連結指向不完整的外掛,而且照樣不報錯。本身是符號連結的那一層也跳過,指過去只是多繞一層,原目標一清就跟著斷。 - **解除安裝的判準是「連結還在、指向卻沒了」。** 不是「這輪解除安裝過這個 domain」——只解除安裝其中一支 CLI 時,連結可能還指著另一支手上完好的副本,那一條必須留著。斷掉的連結不清,等於對外宣稱一支已經不在機器上的外掛還裝著。 - **建立失敗印一行繼續,不記成失敗。** 這一段跑在外掛都裝好之後,部署本身已經成功;記成失敗會連帶跳過重啟閘門與收尾,操作者拿到的是一台明明裝好卻被說成失敗的機器。缺陷仍然看得見,因為輸出多了一行 `link ... fail`,技能文件把它接到 `degraded`。 - **目標存在但不是符號連結時不覆寫。** `ln -sfn` 對著實體目錄下手會把連結建進那個目錄裡,農場當場壞掉還不會報錯;改用強制刪除更糟,那是這支腳本沒建過、也可能沒有第二份的內容。判準與接線腳本的守衛一致。 - **刷新排在重啟閘門之前。** 重啟閘門的第一順位候選就在 `current/jsc-hooks` 底下,先刷新才不會撞上舊版路徑。 ## 測試結果 - 新增的輸出行是 `link<TAB>{domain}<TAB>{狀態}<TAB>{連結路徑}<TAB>{指向或原因}`,狀態五選一:`ok`、`removed`、`skip`、`fail`、`dryrun`。第五欄在 `ok` 與 `dryrun` 時就是指向,呼叫端可以直接取用。 - `-n` 的 dry-run 實測,基準 CLI 印出每一條連結的預定指向;非基準的 CLI 只印一行 `link - skip`,說明這一輪的基準是誰。 - 四條分支都在隔離的 `JSC_HOME` 底下實測過,沒有真的跑部署:`ok` 會把刻意改成舊版的連結重指回新版,`removed` 清掉斷連結,`skip` 對實體目錄不動手,`fail` 訊息在取不到版本目錄時出現。 - `lint-scripts.sh`、`check-behaviors.sh`、`ste100-lint.sh` 對這個存放庫都回結束碼 0。註解掃描也回 0。 - 一句既有敘述因這次改動而失效,已一併修正:技能文件原本寫 `current` 底下沒有 `jsc-cli`,刷新之後那條連結會存在。改成講清楚它仍然靠不住——第一次建起那條連結的正是這一輪,沒部署過的機器、或上一輪刷新失敗的機器,那一條不在或還停在舊版。所以技能自己的腳本仍然走外掛基底目錄,只是理由從「那裡沒有」換成「那裡靠不住」。 ## 前置 Push Request - 無
jiantw83 added 2 commits 2026-09-03 04:39:37 +00:00
$JSC_HOME/current 是一組不帶版本的符號連結,每個外掛一條,指向快取裡帶版本號的實體目錄。技能文件裡所有跨外掛的腳本呼叫都以這一層為根,因為它不帶版本號、寫得進權限允許清單。

問題是沒有任何東西會更新這些連結,只有 wire-cli.sh 會更新 jsc-hooks 那一條。其餘幾條是人手動建的,建好之後就停在當時的版本。實際後果是部署完四個 domain 之後,快取裡是新版,連結卻還指著舊版:助理巡檢照文件的字面路徑跑,跑到的是舊腳本,而其中一個舊版底下根本沒有它要呼叫的檔案。失敗無聲,只有心跳停止,沒人盯就不會有人發現。

部署改成收尾時刷新整組連結。挑部署來做,是因為它本來就知道裝了哪些 domain、裝到哪個版本,資訊最齊。

四個設計決定:

基準 CLI 取 claude、codex、copilot、kiro 之中第一支找得到的,整輪只有那一支寫連結。連結農場只有一組,不可能同時指向五個 CLI 的副本;而五支 CLI 是平行跑的,五支都寫會互相覆寫,最後指到哪一份是隨機的、出事重現不出來。antigravity 一律不當基準,它的來源是本地 clone,而那份 clone 明文允許是維護者的開發樹,把全機器路徑指到做到一半的樹正好是這次要修的那種毛病。

版本目錄取版本排序最大、且真的有 plugin.json、且本身不是符號連結的那一層。要求 plugin.json 是因為裝到一半的目錄沒有它,挑到會讓連結指向不完整的外掛而且照樣不報錯。

解除安裝的判準是「連結還在、指向卻沒了」,不是「這輪解除安裝過這個 domain」。只解除安裝其中一支 CLI 時,連結可能還指著另一支手上完好的副本,那一條必須留著。

連結建立失敗印一行繼續,不記進失敗清單。這一段跑在外掛都裝好之後,部署本身已經成功;記成失敗會連帶跳過重啟閘門,操作者拿到的是一台明明裝好卻被說成失敗的機器。缺陷仍然看得見,因為輸出多了一行。

目標存在但不是符號連結時一律不覆寫,印 skip 要人工處理。ln -sfn 對著實體目錄下手會把連結建進那個目錄裡,農場當場壞掉還不會報錯。

新增 link 行讓呼叫端讀得到每一條連結指到哪裡,狀態五選一。技能文件與行為契約跟著更新,另修正一句因這次改動而失效的敘述:原本寫 current 底下沒有 jsc-cli,刷新之後那條連結會存在,改成講清楚它仍然靠不住,因為第一次建起它的正是這一輪。
連結農場的刷新要靠版號才傳得到機器端。

三份 manifest 由 sync-skill-manifest.sh 同步,只動版本欄位。
admin merged commit 45187f5173 into develop 2026-09-03 04:40:24 +00:00
admin deleted branch feat/refresh-current-link-farm-on-deploy 2026-09-03 04:40:24 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/cli#61