diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 44a13b2..24cdf6d 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-hooks", - "version": "0.3.4", + "version": "0.3.5", "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查、註解範圍守門、繁中編碼守門、部署後強制重啟、寫入與提交閘門", "skills": "./skills", "author": { diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 20b68ee..90a90b0 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "hooks": "./hooks/codex-hooks.json", "name": "jsc-hooks", - "version": "0.3.4", + "version": "0.3.5", "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查、註解範圍守門、繁中編碼守門、部署後強制重啟、寫入與提交閘門", "skills": "./skills", "jsc": { diff --git a/plugin.json b/plugin.json index cebe865..d5b67ff 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-hooks", - "version": "0.3.4", + "version": "0.3.5", "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄、SDLC 模型鎖、版本前置檢查、註解範圍守門、繁中編碼守門、部署後強制重啟、寫入與提交閘門", "skills": "./skills/", "jsc": { diff --git a/tools/wire-cli.sh b/tools/wire-cli.sh index 0fd2dde..14544cb 100755 --- a/tools/wire-cli.sh +++ b/tools/wire-cli.sh @@ -1506,16 +1506,57 @@ if [ "$action" = smoke ]; then # 舊格式的單一狀態檔照樣擋得下來。用暫時目錄是為了不動到使用者真正的 # $JSC_HOME/restart-required.d/——冒煙測試不該把別人的閘門拆掉。 # 一律 &1); _rc=$? smoke_n_rs=$((smoke_n_rs + 1)) - if [ "$_rc" -eq "$3" ]; then + if smoke_deny_ok "$3" "$_rc" "$_out"; then printf '[jsc] restart-gate.sh(%s):exit %s,與預期相同。\n' "$1" "$_rc" >> "$smoke_out" else smoke_fails=$((smoke_fails + 1)) printf '[jsc] restart-gate.sh(%s):exit %s,預期 %s,重啟閘門判定壞了:%s\n' \ - "$1" "$_rc" "$3" "$(printf '%s' "$_out" | tr '\n' ' ' | cut -c1-200)" >> "$smoke_out" + "$1" "$_rc" "$(smoke_deny_desc "$3")" \ + "$(printf '%s' "$_out" | tr '\n' ' ' | cut -c1-200)" >> "$smoke_out" fi } # 狀態檔在不在也要比:一支 CLI 一份的重點就在「該留的留、該刪的刪」,只看結束碼看不出來。 @@ -1540,7 +1581,7 @@ if [ "$action" = smoke ]; then JSC_HOME="$rs_home" JSC_CLI="$cli" \ sh "$HOOKS/restart-gate.sh" require update hooks cli /dev/null smoke_rs_file "require 寫出當前 CLI 那一份" "$rs_dir/$cli" exist - smoke_rs_case "當前 CLI 那份存在,技能 jsc-sdlc:implement" jsc-sdlc:implement 2 + smoke_rs_case "當前 CLI 那份存在,技能 jsc-sdlc:implement" jsc-sdlc:implement deny smoke_rs_case "當前 CLI 那份存在,豁免技能 jsc-cli:deploy" jsc-cli:deploy 0 smoke_rs_case "當前 CLI 那份存在,豁免技能 jsc-gitea:wiki" jsc-gitea:wiki 0 smoke_rs_case "當前 CLI 那份存在,豁免技能 jsc-log:worklog" jsc-log:worklog 0 @@ -1557,7 +1598,7 @@ if [ "$action" = smoke ]; then # 舊格式的單一狀態檔(過渡相容):沒有 per-CLI 資訊,所以一律擋,clear 一併刪掉。 printf 'at=%s\nmode=update\ndomains=hooks\ncli=%s\n' "$(now_iso)" "$rs_other" \ > "$rs_home/restart-required" 2>/dev/null - smoke_rs_case "舊格式單一狀態檔存在" jsc-sdlc:implement 2 + smoke_rs_case "舊格式單一狀態檔存在" jsc-sdlc:implement deny JSC_HOME="$rs_home" JSC_CLI="$cli" JSC_SESSION_ID=smoke-restart-legacy \ sh "$HOOKS/session-timer.sh" restart /dev/null smoke_rs_file "清除一併刪掉舊格式狀態檔" "$rs_home/restart-required" absent @@ -1658,7 +1699,7 @@ if [ "$action" = smoke ]; then # GITEA_HOST 一律清空:放行的案例會繼續往下走到遠端比對,站台推導得出來就會真的連網, # 冒煙不該依賴網路,也不該讓遠端落後把預期放行的案例判成擋下。 # 一律 &1); _rc=$? smoke_n_vg=$((smoke_n_vg + 1)) - if [ "$_rc" -eq "$3" ]; then + if smoke_deny_ok "$3" "$_rc" "$vg_out"; then printf '[jsc] version-guard.sh(%s):exit %s,與預期相同。\n' "$1" "$_rc" >> "$smoke_out" else smoke_fails=$((smoke_fails + 1)) printf '[jsc] version-guard.sh(%s):exit %s,預期 %s,相依版本判定壞了:%s\n' \ - "$1" "$_rc" "$3" "$(printf '%s' "$vg_out" | tr '\n' ' ' | cut -c1-200)" >> "$smoke_out" + "$1" "$_rc" "$(smoke_deny_desc "$3")" \ + "$(printf '%s' "$vg_out" | tr '\n' ' ' | cut -c1-200)" >> "$smoke_out" fi } # 訊息內容也要比:擋下來卻沒指名是哪一個相依落後,使用者看不出要更新哪一個 plugin, @@ -1710,7 +1752,7 @@ if [ "$action" = smoke ]; then # 一、相依確定落後:擋下,而且訊息要指名是哪一項、需要哪一版、目前哪一版。 printf '{"name": "jsc-sdlc", "version": "0.1.0", "jsc": {"requires": {"jsc-cli": ">=9.9.9"}}}\n' \ > "$vg_manifest" - smoke_vg_case "相依落後" jsc-sdlc:implement 2 + smoke_vg_case "相依落後" jsc-sdlc:implement deny smoke_vg_msg "相依落後時訊息指名那一項" "jsc-cli 需要 >=9.9.9,目前 0.1.0" # 二、相依相等或超前都放行:只擋落後,本機超前是開發技能組時的常態,擋了維護者自己動不了。 @@ -1724,7 +1766,7 @@ if [ "$action" = smoke ]; then # 三、豁免技能:這一條最要緊,它證明閘門不會把更新與修復的唯一路徑鎖死。同一個 jsc-cli # plugin 底下,非豁免的技能在相依落後時被擋、豁免的那一支照樣放行,差別只在豁免清單。 smoke_vg_case "豁免技能 jsc-cli:deploy,相依落後照樣放行" jsc-cli:deploy 0 - smoke_vg_case "同 plugin 的非豁免技能 jsc-cli:doctor" jsc-cli:doctor 2 + smoke_vg_case "同 plugin 的非豁免技能 jsc-cli:doctor" jsc-cli:doctor deny # 四、fail-open 四條:沒有證據不等於落後。五支 CLI 只有 claude 讀得到本機載入版本, # 這四條任何一條改成擋人,另外四支就會被整批鎖死。 @@ -1746,7 +1788,7 @@ if [ "$action" = smoke ]; then # 前面那一項則是滿足的:漏掉最後一筆就會變成放行,當場被這一條抓出來。 printf '{\n "name": "jsc-sdlc",\n "version": "0.1.0",\n "jsc": {\n "requires": {\n "jsc-hooks": ">=0.0.1",\n "jsc-cli": ">=9.9.9"\n }\n }\n}\n' \ > "$vg_manifest" - smoke_vg_case "多行縮排 manifest,落後的相依擺在最後一個鍵" jsc-sdlc:implement 2 + smoke_vg_case "多行縮排 manifest,落後的相依擺在最後一個鍵" jsc-sdlc:implement deny smoke_vg_msg "最後一個鍵的落後項也列進訊息" "jsc-cli 需要 >=9.9.9,目前 0.1.0" rm -rf "$vg_home" else