共用函式庫補上 stdin JSON 的載入期預設值,四條收尾路徑不再吐未設定訊息 #84

Merged
admin merged 2 commits from fix/stdin-json-default-in-shared-lib into develop 2026-09-03 05:35:22 +00:00
Member

摘要

  • 需求描述:有幾條路徑在收尾時往標準錯誤吐一行「參數未設定」。掃描結果其實是對的,但那行訊息讓人以為掃描失敗——註解範圍掃描的流程規定「安靜地回 0 才算通過」,這一行正好讓「安靜」這個判準失效。根因在共用函式庫的載入期,補一個預設值就解決。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
hooks/lib.sh 在任何讀取 stdin JSON 的函式之前,補上該變數的載入期預設值。一行程式碼加十行說明為什麼要有
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 版號 0.4.3 升到 0.4.4

設計重點

  • 根因在收尾的 trap,不在掃描本身。 hook_trace 裝的 EXIT trap 在腳本結束時經由 emit_event 呼叫 session_id,而它第一件事就是讀 stdin JSON 那個變數。腳本在讀取標準輸入之前就離開時,那個變數還沒人設過,開了 set -u 的腳本收尾就報錯。
  • 錯誤訊息的檔名會誤導,值得記一筆。 dash 回報行號用被 source 檔的行號、檔名卻用呼叫端的名字,所以訊息看起來像呼叫端的第 30 行出錯,實際上在共用函式庫裡。照著訊息去找會找錯地方。這一點是用一支六行的探針腳本確認的——set -u 之後 source 函式庫再直接叫那個函式,它回報同樣的行號配探針自己的檔名。
  • 修在共用處,不在各腳本各補一次。 讀那個變數的是共用函式,補在共用處才涵蓋每一條離開路徑,也涵蓋往後新增的腳本。
  • 用帶預設的展開,不用直接指派空字串。 呼叫端已經帶值進來時原樣保留,讀取標準輸入之後的取值行為完全不變。
  • 這個缺陷不只一處。 凡是「有 set -u、裝了 hook_trace、又在讀取標準輸入之前離開」的路徑都會中。實測四條:註解範圍掃描的整區模式與規則提示模式、語言檢查的規則提示模式、寫入閘門的未知模式。修前都吐,修後都安靜。

測試結果

  • 掃描安靜且結束碼 0:整區掃描在乾淨的存放庫上回結束碼 0,標準錯誤零位元組。工作區無變更、有變更但註解合規兩種情境各驗一次,都是零位元組。
  • 陽性對照仍有作用:暫存區新開一個 git 存放庫,提交乾淨檔案後改成帶議題編號的註解,掃描正確回結束碼 2 並印出命中的兩條規則與證據行。證明修完之後掃描沒有被弄啞。
  • 事件記錄沒有跟著消失:用隔離的環境驗,沒有污染正式事件流。餵標準輸入 JSON 跑計時器,事件裡的工作階段欄位取的是標準輸入帶進來的值,不是預設值;整區掃描自己的事件也還在記,最後一筆的狀態與結束碼都正確。
  • 修前修後四條路徑的對照都跑過,逐條列在提交訊息裡。
  • lint-scripts.sh、check-behaviors.sh、ste100-lint.sh 對這個存放庫都回結束碼 0。

前置 Push Request

  • 無
## 摘要 - 需求描述:有幾條路徑在收尾時往標準錯誤吐一行「參數未設定」。掃描結果其實是對的,但那行訊息讓人以為掃描失敗——註解範圍掃描的流程規定「安靜地回 0 才算通過」,這一行正好讓「安靜」這個判準失效。根因在共用函式庫的載入期,補一個預設值就解決。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `hooks/lib.sh` | 在任何讀取 stdin JSON 的函式之前,補上該變數的載入期預設值。一行程式碼加十行說明為什麼要有 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 版號 0.4.3 升到 0.4.4 | ## 設計重點 - **根因在收尾的 trap,不在掃描本身。** `hook_trace` 裝的 EXIT trap 在腳本結束時經由 `emit_event` 呼叫 `session_id`,而它第一件事就是讀 stdin JSON 那個變數。腳本在讀取標準輸入之前就離開時,那個變數還沒人設過,開了 `set -u` 的腳本收尾就報錯。 - **錯誤訊息的檔名會誤導,值得記一筆。** dash 回報行號用被 source 檔的行號、檔名卻用呼叫端的名字,所以訊息看起來像呼叫端的第 30 行出錯,實際上在共用函式庫裡。照著訊息去找會找錯地方。這一點是用一支六行的探針腳本確認的——`set -u` 之後 source 函式庫再直接叫那個函式,它回報同樣的行號配探針自己的檔名。 - **修在共用處,不在各腳本各補一次。** 讀那個變數的是共用函式,補在共用處才涵蓋每一條離開路徑,也涵蓋往後新增的腳本。 - **用帶預設的展開,不用直接指派空字串。** 呼叫端已經帶值進來時原樣保留,讀取標準輸入之後的取值行為完全不變。 - **這個缺陷不只一處。** 凡是「有 `set -u`、裝了 `hook_trace`、又在讀取標準輸入之前離開」的路徑都會中。實測四條:註解範圍掃描的整區模式與規則提示模式、語言檢查的規則提示模式、寫入閘門的未知模式。修前都吐,修後都安靜。 ## 測試結果 - **掃描安靜且結束碼 0**:整區掃描在乾淨的存放庫上回結束碼 0,標準錯誤零位元組。工作區無變更、有變更但註解合規兩種情境各驗一次,都是零位元組。 - **陽性對照仍有作用**:暫存區新開一個 git 存放庫,提交乾淨檔案後改成帶議題編號的註解,掃描正確回結束碼 2 並印出命中的兩條規則與證據行。證明修完之後掃描沒有被弄啞。 - **事件記錄沒有跟著消失**:用隔離的環境驗,沒有污染正式事件流。餵標準輸入 JSON 跑計時器,事件裡的工作階段欄位取的是標準輸入帶進來的值,不是預設值;整區掃描自己的事件也還在記,最後一筆的狀態與結束碼都正確。 - 修前修後四條路徑的對照都跑過,逐條列在提交訊息裡。 - `lint-scripts.sh`、`check-behaviors.sh`、`ste100-lint.sh` 對這個存放庫都回結束碼 0。 ## 前置 Push Request - 無
jiantw83 added 2 commits 2026-09-03 05:34:02 +00:00
有幾條路徑在收尾時會往標準錯誤吐一行「參數未設定」,掃描結果其實是對的,但那行訊息讓人以為掃描失敗。註解範圍掃描的流程規定「安靜地回 0 才算通過」,這一行正好讓「安靜」這個判準失效。

根因在共用函式庫:hook_trace 裝的 EXIT trap 會在腳本結束時經由 emit_event 呼叫 session_id,而它第一件事就是讀 stdin JSON 那個變數。腳本在讀取標準輸入之前就離開時,那個變數還沒人設過,開了 set -u 的腳本收尾就報錯。

訊息裡的檔名有誤導性:dash 回報行號用被 source 檔的行號、檔名卻用呼叫端的名字,所以看起來像是呼叫端的第 30 行出錯,實際上在函式庫裡。用一支探針腳本確認過行號的來源。

修法是在共用函式庫載入期給那個變數一個預設值,寫在任何讀取它的函式之前。修在共用處而不是各腳本各補一次:讀它的是共用函式,補在共用處才涵蓋每一條離開路徑,也涵蓋往後新增的腳本。用帶預設的展開而不是直接指派空字串,呼叫端已經帶值進來時原樣保留。

這個缺陷不只一處。凡是「有 set -u、裝了 hook_trace、又在讀取標準輸入之前離開」的路徑都會中,實測四條路徑修前都吐、修後都安靜。

驗證三項:掃描回 0 且標準錯誤零位元組;陽性對照仍正確回 2 並印出命中,證明掃描還有作用;事件記錄仍然正常,且事件裡的工作階段欄位取自標準輸入而不是預設值。事件驗證用隔離的環境做,沒有污染正式事件流。
共用函式庫的收尾修正要靠版號才傳得到機器端。

三份 manifest 由 sync-skill-manifest.sh 同步,只動版本欄位。
admin merged commit 8e37ab3191 into develop 2026-09-03 05:35:22 +00:00
admin deleted branch fix/stdin-json-default-in-shared-lib 2026-09-03 05:35:22 +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/hooks#84