release: v0.2.0 develop 到 master #31

Merged
admin merged 4 commits from develop into master 2026-08-27 10:58:10 +00:00
Member

PR 描述

摘要

  • 需求描述:把 develop 上的 v0.2.0 放行到預設分支 master,共 4 個 commit。內容是配合 R15 部署後重啟閘門的狀態檔改版:deploy.sh 收尾印出的重啟狀態檔路徑帶上 CLI 代號,指引文字與設定登錄同步改成一支 CLI 一份。這一段是必要的:marketplace 與 jsc-hooks/hooks/version-guard.sh 都讀存取庫的預設分支 master(version-guard.sh 取 raw plugin.json 時刻意不指定 ref,Gitea 就回預設分支那一份),develop 併了不等於生效,要放行到 master,已安裝的五支 CLI 才抓得到這次修正。原本的缺陷是 2026-08-27 這道閘門上線當日部署時實測抓到的:全機器單一狀態檔導致並行部署互相覆蓋(實測 kiro 寫入 9 秒後被 codex 蓋掉),而且任一支 CLI 重啟就解除全部五支的閘門,其餘四支沒重啟卻不再被擋。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
tools/deploy.sh 收尾的 restart 行印出的路徑改成 $JSC_HOME/restart-required.d/$CLI,指到這一支 CLI 自己那一份,原本指的是全機器單一檔案。檔頭註解同步講明收尾是轉呼叫 restart-gate.sh require、狀態檔一支 CLI 一份,擋人邏輯與逃生門都不在這支腳本裡。require 的呼叫本身不動——路徑與格式的唯一來源在 jsc-hooks,這裡只轉呼叫。
tools/write-guides.sh 更新指引裡描述重啟狀態檔的那段文字改成 {cli} 一支一份,並寫明重啟只清自己那份、別支的閘門不受影響。指引是操作者下次更新時唯一的依據,寫錯路徑會讓人去刪一個不存在的檔案。
tools/config-spec.tsv 登錄項從 $JSC_HOME/restart-required(file)改成 $JSC_HOME/restart-required.d(目錄),說明改成一支 CLI 一份、該 CLI 那份不存在代表這支沒有待重啟的部署。/jsc-cli:doctor 的體檢清單認的是這張表。
README.md 部署產物表裡的重啟狀態檔一列同步:路徑、一支一份、四行 key=value 的欄位,並註明路徑與格式的唯一來源是 jsc-hooks/hooks/restart-gate.sh,deploy.sh 只轉呼叫它的 require。
skills/deploy/SKILL.md 第 9 步的收尾指示同步:狀態檔一支 CLI 一份,jsc-hooks 只讀那一支自己那份、只到那一支重啟為止;並補上「重啟一支只清自己那份,別支的閘門照樣站著」。重啟指示的固定措辭不變。
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 三份 manifest 版本升到 0.2.0。

設計重點

  • 升次版號是刻意的,不是修補:機器上的檔案落點算對外契約。$JSC_HOME/restart-required 改成 $JSC_HOME/restart-required.d/{cli},操作者、config-spec.tsv、更新指引三邊都看得到這個路徑,換位置就是契約變更,所以走 0.1.9 到 0.2.0,不是 patch。
  • 這一側只有路徑字串,沒有邏輯:狀態檔的路徑、範圍與格式的唯一來源是 jsc-hooks/hooks/restart-gate.sh;deploy.sh 從頭到尾只轉呼叫 require,判定與清除都不碰。所以本存取庫的變更就是五處文字與一處路徑組字,沒有第二份實作要跟著漂移。
  • require 失敗照舊要講出來:取不到 CLI 代號或寫不進去,restart-gate.sh 回 exit 2,deploy.sh 就印 note 行說明「這次沒有掛上重啟閘門」。沒掛上不能讓部署當成掛上了,這條行為不變,只是失敗原因多了一種(jsc-hooks 側新增的 CLI 代號取值與髒值防護)。
  • 附帶的加固在 jsc-hooks 側,但這裡也吃得到結果:CLI 代號直接當檔名,所以含 /、以 . 開頭、或帶 [A-Za-z0-9._-] 以外字元的值一律當成取不到(實測 JSC_CLI=../evil、a/b、.、.. 都回 exit 2,狀態目錄外沒有多出檔案);舊格式單一檔案存在時一律擋,clear 會一併刪掉,屬過渡相容,可移除時機記在 jsc-hooks 的檔頭與 README。
  • 升級後的行為差異:重啟一支 CLI 只解除那一支的閘門,其餘的照樣被擋、要各自重啟;restart-gate.sh report 現在看得出哪幾支還沒重啟。仍然只有 claude 擋得住——codex、copilot、antigravity、kiro 沒有 pre-tool hook,狀態檔照樣寫、照樣清,但中間沒有判定點,重啟要靠部署收尾的提示自己動手。

測試結果

  • jsc-meta/tools/ste100-lint.sh 掃本存取庫全綠。
  • 三份 manifest(plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json)版本一致為 0.2.0。
  • sh -n 對改動過的腳本(tools/deploy.sh、tools/write-guides.sh)全部通過。
  • grep 確認舊路徑零殘留:本存取庫沒有任何地方還指向全機器單一狀態檔。
  • tools/config-spec.tsv 欄位數一致為 8,改動那一列沒有把欄位弄丟。
  • 核心隔離實測(在 jsc-hooks 側跑,這一側的路徑對不對由它驗證):kiro 與 codex 各跑一次 require,產生兩份獨立狀態檔、不互相覆蓋;三支 CLI 各只看得到自己那一份;kiro clear 之後只剩 codex 那一份;重啟後 kiro 放行而 codex 仍被擋。最後這一列正是舊版壞掉的行為,主 agent 另外獨立複驗過一次,結果一致。
  • 舊檔相容實測:只有舊檔時三支 CLI 全擋、訊息標明是舊格式紀錄;clear 之後舊檔被刪;再判定一次放行。
  • 放行路徑實測:九支豁免技能全放行、逃生門 JSC_RESTART_GATE=off 放行、取不到技能名放行、取不到 CLI 代號放行。
  • 髒值防護實測:JSC_CLI=../evil、a/b、.、.. 四種全部 exit 2,狀態目錄外沒有多出檔案。
  • 所有子命令在 </dev/null 加 timeout 之下都不卡住。
  • jsc-hooks/tools/wire-cli.sh smoke claude 回 status=ok,重啟閘門 16 條專屬情境加通用執行共 17 行全部與預期相同。
  • 沒跑的據實說明:非 claude 四支 CLI 上這道閘門無法測試——它們沒有 pre-tool hook,沒有判定點可測,不是還沒測。
  • 這批放行本身沒有重跑腳本測試。上面這些是在 fix PR 階段跑的(cli#30,隔離與相容部分在 hooks#37),本 PR 只是把已驗過的 develop 內容搬到 master,沒有新的程式碼變更。

前置 Push Request

  • 無。三支 fix PR(hooks#37、cli#30、meta#28)都已合併進各自的 develop。
# PR 描述 ## 摘要 - 需求描述:把 `develop` 上的 v0.2.0 放行到預設分支 `master`,共 4 個 commit。內容是配合 R15 部署後重啟閘門的狀態檔改版:`deploy.sh` 收尾印出的重啟狀態檔路徑帶上 CLI 代號,指引文字與設定登錄同步改成一支 CLI 一份。這一段是必要的:marketplace 與 `jsc-hooks/hooks/version-guard.sh` 都讀存取庫的預設分支 `master`(`version-guard.sh` 取 raw `plugin.json` 時刻意不指定 ref,Gitea 就回預設分支那一份),`develop` 併了不等於生效,要放行到 `master`,已安裝的五支 CLI 才抓得到這次修正。原本的缺陷是 2026-08-27 這道閘門上線當日部署時實測抓到的:全機器單一狀態檔導致並行部署互相覆蓋(實測 kiro 寫入 9 秒後被 codex 蓋掉),而且任一支 CLI 重啟就解除全部五支的閘門,其餘四支沒重啟卻不再被擋。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/deploy.sh` | 收尾的 `restart` 行印出的路徑改成 `$JSC_HOME/restart-required.d/$CLI`,指到這一支 CLI 自己那一份,原本指的是全機器單一檔案。檔頭註解同步講明收尾是轉呼叫 `restart-gate.sh require`、狀態檔一支 CLI 一份,擋人邏輯與逃生門都不在這支腳本裡。`require` 的呼叫本身不動——路徑與格式的唯一來源在 `jsc-hooks`,這裡只轉呼叫。 | | `tools/write-guides.sh` | 更新指引裡描述重啟狀態檔的那段文字改成 `{cli}` 一支一份,並寫明重啟只清自己那份、別支的閘門不受影響。指引是操作者下次更新時唯一的依據,寫錯路徑會讓人去刪一個不存在的檔案。 | | `tools/config-spec.tsv` | 登錄項從 `$JSC_HOME/restart-required`(file)改成 `$JSC_HOME/restart-required.d`(目錄),說明改成一支 CLI 一份、該 CLI 那份不存在代表這支沒有待重啟的部署。`/jsc-cli:doctor` 的體檢清單認的是這張表。 | | `README.md` | 部署產物表裡的重啟狀態檔一列同步:路徑、一支一份、四行 key=value 的欄位,並註明路徑與格式的唯一來源是 `jsc-hooks/hooks/restart-gate.sh`,`deploy.sh` 只轉呼叫它的 `require`。 | | `skills/deploy/SKILL.md` | 第 9 步的收尾指示同步:狀態檔一支 CLI 一份,`jsc-hooks` 只讀那一支自己那份、只到那一支重啟為止;並補上「重啟一支只清自己那份,別支的閘門照樣站著」。重啟指示的固定措辭不變。 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 三份 manifest 版本升到 0.2.0。 | ## 設計重點 - **升次版號是刻意的,不是修補**:機器上的檔案落點算對外契約。`$JSC_HOME/restart-required` 改成 `$JSC_HOME/restart-required.d/{cli}`,操作者、`config-spec.tsv`、更新指引三邊都看得到這個路徑,換位置就是契約變更,所以走 0.1.9 到 0.2.0,不是 patch。 - **這一側只有路徑字串,沒有邏輯**:狀態檔的路徑、範圍與格式的唯一來源是 `jsc-hooks/hooks/restart-gate.sh`;`deploy.sh` 從頭到尾只轉呼叫 `require`,判定與清除都不碰。所以本存取庫的變更就是五處文字與一處路徑組字,沒有第二份實作要跟著漂移。 - **`require` 失敗照舊要講出來**:取不到 CLI 代號或寫不進去,`restart-gate.sh` 回 exit 2,`deploy.sh` 就印 `note` 行說明「這次沒有掛上重啟閘門」。沒掛上不能讓部署當成掛上了,這條行為不變,只是失敗原因多了一種(`jsc-hooks` 側新增的 CLI 代號取值與髒值防護)。 - **附帶的加固在 `jsc-hooks` 側,但這裡也吃得到結果**:CLI 代號直接當檔名,所以含 `/`、以 `.` 開頭、或帶 `[A-Za-z0-9._-]` 以外字元的值一律當成取不到(實測 `JSC_CLI=../evil`、`a/b`、`.`、`..` 都回 exit 2,狀態目錄外沒有多出檔案);舊格式單一檔案存在時一律擋,`clear` 會一併刪掉,屬過渡相容,可移除時機記在 `jsc-hooks` 的檔頭與 README。 - **升級後的行為差異**:重啟一支 CLI 只解除那一支的閘門,其餘的照樣被擋、要各自重啟;`restart-gate.sh report` 現在看得出哪幾支還沒重啟。仍然只有 claude 擋得住——codex、copilot、antigravity、kiro 沒有 pre-tool hook,狀態檔照樣寫、照樣清,但中間沒有判定點,重啟要靠部署收尾的提示自己動手。 ## 測試結果 - `jsc-meta/tools/ste100-lint.sh` 掃本存取庫全綠。 - 三份 manifest(`plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json`)版本一致為 0.2.0。 - `sh -n` 對改動過的腳本(`tools/deploy.sh`、`tools/write-guides.sh`)全部通過。 - `grep` 確認舊路徑零殘留:本存取庫沒有任何地方還指向全機器單一狀態檔。 - `tools/config-spec.tsv` 欄位數一致為 8,改動那一列沒有把欄位弄丟。 - 核心隔離實測(在 `jsc-hooks` 側跑,這一側的路徑對不對由它驗證):kiro 與 codex 各跑一次 `require`,產生兩份獨立狀態檔、不互相覆蓋;三支 CLI 各只看得到自己那一份;kiro `clear` 之後只剩 codex 那一份;重啟後 kiro 放行而 **codex 仍被擋**。最後這一列正是舊版壞掉的行為,主 agent 另外獨立複驗過一次,結果一致。 - 舊檔相容實測:只有舊檔時三支 CLI 全擋、訊息標明是舊格式紀錄;`clear` 之後舊檔被刪;再判定一次放行。 - 放行路徑實測:九支豁免技能全放行、逃生門 `JSC_RESTART_GATE=off` 放行、取不到技能名放行、取不到 CLI 代號放行。 - 髒值防護實測:`JSC_CLI=../evil`、`a/b`、`.`、`..` 四種全部 exit 2,狀態目錄外沒有多出檔案。 - 所有子命令在 `</dev/null` 加 `timeout` 之下都不卡住。 - `jsc-hooks/tools/wire-cli.sh smoke claude` 回 `status=ok`,重啟閘門 16 條專屬情境加通用執行共 17 行全部與預期相同。 - 沒跑的據實說明:非 claude 四支 CLI 上這道閘門無法測試——它們沒有 pre-tool hook,沒有判定點可測,不是還沒測。 - 這批放行本身沒有重跑腳本測試。上面這些是在 fix PR 階段跑的(cli#30,隔離與相容部分在 hooks#37),本 PR 只是把已驗過的 `develop` 內容搬到 `master`,沒有新的程式碼變更。 ## 前置 Push Request - 無。三支 fix PR(hooks#37、cli#30、meta#28)都已合併進各自的 `develop`。
jiantw83 added 4 commits 2026-08-27 10:56:28 +00:00
What:`tools/deploy.sh` 的 `restart` 那一行改印 `$JSC_HOME/restart-required.d/{CLI 代號}`,檔頭註解一併改寫成「轉呼叫 `restart-gate.sh require` 掛上這支 CLI 的閘門」。`tools/write-guides.sh` 產生的更新指引,狀態檔說明改成一支 CLI 一份、重啟只清自己那份、別支的閘門不受影響。`tools/config-spec.tsv` 的 `$JSC_HOME/restart-required` 那一列改成 `$JSC_HOME/restart-required.d` 目錄,說明改為「該 CLI 那份不存在代表這支沒有待重啟的部署」。

Why:`jsc-hooks` 這一輪把狀態檔改成一支 CLI 一份,路徑從單一檔案變成狀態目錄底下的一份。`deploy.sh` 印的是操作者接下來要看的檔案路徑,印錯就指向一個不存在的檔案;`write-guides.sh` 寫出的更新指引是下一輪部署的依據,留著舊路徑會讓人以為刪掉那個檔案就能解除閘門;`config-spec.tsv` 是 `/jsc-cli:doctor` 比對設定落點的依據,路徑對不上就查不到這份執行期暫態。

How:三處都只跟著改路徑與說明,掛閘門的動作本來就是轉呼叫 `jsc-hooks` 的 `restart-gate.sh require`,這裡不重寫一份判定,也不自己組狀態檔內容——路徑與格式的唯一來源留在 `restart-gate.sh`。`config-spec.tsv` 那一列的型別仍是 `global` 的執行期暫態、備份與還原都維持 `none`,欄位數不變。

Who:`jsc-cli:deploy` 的部署收尾與更新指引,對齊 `jsc-hooks` 一支 CLI 一份的重啟狀態檔。
What:`README.md`「部署留在機器上的檔案」那張表,`$JSC_HOME/restart-required` 那一列改成 `$JSC_HOME/restart-required.d/{cli}`,寫明一支 CLI 一份、內容是四行 key=value,以及路徑與格式的唯一來源在 `jsc-hooks/hooks/restart-gate.sh`。`skills/deploy/SKILL.md` 第 9 步的路徑說明同步改寫,補上「每支 CLI 只讀自己那一份」與「重啟一支只清自己那份、別支的閘門還立著」,全篇維持英文。

Why:這兩份說的是同一件事在不同讀者面前的樣貌——README 給看存取庫的人,技能文件給執行部署的模型。收尾提示裡的路徑是操作者唯一會拿到的線索,寫成舊的單一檔案就對不上機器上的實況,也會讓人以為重啟一支就把全部閘門解除了,那正是這一輪要修掉的錯誤認知。

How:只改說明,第 9 步的完成判準與那句固定的重啟指示都不動。舊表格那一列原本寫「一行一次成功部署」,其實是四行 key=value 的狀態檔,這次一併訂正。路徑與格式指回 `restart-gate.sh`,兩個存取庫不各自維護一份格式說明。

Who:`jsc-cli` 的存取庫說明與 `jsc-cli:deploy` 技能文件,對齊 `jsc-hooks` 的重啟狀態檔設計。
What:`plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 的 `version` 從 0.1.9 升到 0.2.0,三份同步,description 不動。

Why:這一輪改的是部署收尾留在機器上的檔案落點——狀態檔從單一檔案變成一支 CLI 一份的狀態目錄,`config-spec.tsv` 這份對外的設定落點清單也跟著改。那是對外可見的契約變更,不只是內部修正,所以走次版號而不是修訂號。版本不升,`version-guard.sh` 與 `jsc-cli:deploy` 都判不出本機還是舊版,機器上就不會被提示更新。

How:只改版號一個欄位。三份必須一致:`plugin.json` 給 marketplace、`.claude-plugin` 給 claude、`.codex-plugin` 給 codex,任一份落後都會讓那一路的版本比對抓錯。這一版的部署工具要搭 `jsc-hooks` 0.2.6 才有一支 CLI 一份的狀態檔,兩者一起發佈。

Who:`jsc-cli` 的三份 plugin manifest,配合這一輪重啟狀態檔路徑的修正發佈。
Reviewed-on: #30
admin approved these changes 2026-08-27 10:58:08 +00:00
admin merged commit a6ac6be5de into master 2026-08-27 10:58:10 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/cli#31