fix/smoke-deny-assertion-per-cli #60

Merged
admin merged 1 commits from fix/smoke-deny-assertion-per-cli into develop 2026-09-01 03:50:58 +00:00
Member

摘要

  • 需求描述:接線後的冒煙測試在 antigravity 與 kiro 上各有五條判定失敗。追出來的是斷言本身認錯了擋人形態,不是 hook 失效——擋人訊息都正確印出來了,配套的訊息斷言也全部通過,壞的只有結束碼那一項比對。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
tools/wire-cli.sh smoke_rs_case 與 smoke_vg_case 把「擋下」寫死成結束碼 2,但擋下的形態由 hooks/deny.sh 依 CLI 決定。新增四個共用小函式把那張形態表鏡射過來,五個呼叫點的預期值改成字面值 deny
plugin.json 三份 manifest 的版本一起提升
.claude-plugin/plugin.json 同上
.codex-plugin/plugin.json 同上

設計重點

  • 形態的事實來源仍然只有一份。 deny.sh 的 case 決定各 CLI 怎麼擋:claude、codex、copilot 與認不得的代號走 stderr 加結束碼 2;antigravity 改印一行 stdout 的 deny JSON,kiro 只能注入警告,這兩支的結束碼都固定 0。smoke 這側只鏡射同一張表,不在五個呼叫點各長一份 CLI 分支。
  • 沒有把預期放寬成 0。 那兩支 CLI 上放行也是 0,放寬之後「該擋沒擋」與「正確擋下」完全同形,這道斷言等於作廢。判定改成結束碼與擋人標記一起比。
  • 反向也守得住。 預期放行的案例反過來要求擋人標記不得出現,所以「不該擋卻擋了」同樣抓得到。走 stderr 的三支標記為空字串,判定行為與原本完全相同,不產生回歸。
  • 斷言條數不增不減,兩個預期條數常數都不必動,lines 維持同一個數字。
  • 既有的 smoke_dn_case 與 smoke_cx_case 早就是「結束碼加輸出內容一起比」的做法,這次沿用同一套,不另立新規。

測試結果

  • sh -n tools/wire-cli.sh:通過。
  • 五支 CLI 的 wire-cli.sh smoke:claude、codex、copilot、antigravity、kiro 全部 status=ok、exit 0,lines 都是 131。修正前 antigravity 與 kiro 各 5 條失敗、回 exit 4,另外三支本來就過。lines 前後同一個數字,證明只換判定方式、沒有增減條數。
  • 反向測試:複製一份到暫存目錄,拿掉 deny.sh 裡 antigravity 分支的 deny JSON 輸出,做出「該擋卻靜靜放行」的情境(exit 0 但什麼都不印)。smoke 正確判失敗,訊息是「exit 0,預期 exit 0 且輸出含『"decision":"deny"』」。結束碼完全相同,靠擋人標記才分得出來。測完已刪除副本。
  • comment-scope.sh sweep:exit 0。
  • sync-skill-manifest.sh:exit 0,三份 manifest 同步。

前置 Push Request

  • 無
## 摘要 - 需求描述:接線後的冒煙測試在 antigravity 與 kiro 上各有五條判定失敗。追出來的是斷言本身認錯了擋人形態,不是 hook 失效——擋人訊息都正確印出來了,配套的訊息斷言也全部通過,壞的只有結束碼那一項比對。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/wire-cli.sh` | `smoke_rs_case` 與 `smoke_vg_case` 把「擋下」寫死成結束碼 2,但擋下的形態由 `hooks/deny.sh` 依 CLI 決定。新增四個共用小函式把那張形態表鏡射過來,五個呼叫點的預期值改成字面值 `deny` | | `plugin.json` | 三份 manifest 的版本一起提升 | | `.claude-plugin/plugin.json` | 同上 | | `.codex-plugin/plugin.json` | 同上 | ## 設計重點 - **形態的事實來源仍然只有一份。** `deny.sh` 的 `case` 決定各 CLI 怎麼擋:claude、codex、copilot 與認不得的代號走 stderr 加結束碼 2;antigravity 改印一行 stdout 的 deny JSON,kiro 只能注入警告,這兩支的結束碼都固定 0。smoke 這側只鏡射同一張表,不在五個呼叫點各長一份 CLI 分支。 - **沒有把預期放寬成 0。** 那兩支 CLI 上放行也是 0,放寬之後「該擋沒擋」與「正確擋下」完全同形,這道斷言等於作廢。判定改成結束碼與擋人標記一起比。 - **反向也守得住。** 預期放行的案例反過來要求擋人標記不得出現,所以「不該擋卻擋了」同樣抓得到。走 stderr 的三支標記為空字串,判定行為與原本完全相同,不產生回歸。 - **斷言條數不增不減**,兩個預期條數常數都不必動,`lines` 維持同一個數字。 - 既有的 `smoke_dn_case` 與 `smoke_cx_case` 早就是「結束碼加輸出內容一起比」的做法,這次沿用同一套,不另立新規。 ## 測試結果 - `sh -n tools/wire-cli.sh`:通過。 - 五支 CLI 的 `wire-cli.sh smoke`:claude、codex、copilot、antigravity、kiro 全部 `status=ok`、exit 0,`lines` 都是 131。修正前 antigravity 與 kiro 各 5 條失敗、回 exit 4,另外三支本來就過。`lines` 前後同一個數字,證明只換判定方式、沒有增減條數。 - **反向測試**:複製一份到暫存目錄,拿掉 `deny.sh` 裡 antigravity 分支的 deny JSON 輸出,做出「該擋卻靜靜放行」的情境(exit 0 但什麼都不印)。smoke 正確判失敗,訊息是「exit 0,預期 exit 0 且輸出含『"decision":"deny"』」。結束碼完全相同,靠擋人標記才分得出來。測完已刪除副本。 - `comment-scope.sh sweep`:exit 0。 - `sync-skill-manifest.sh`:exit 0,三份 manifest 同步。 ## 前置 Push Request - 無
jiantw83 added 1 commit 2026-09-01 03:50:31 +00:00
What:
- wire-cli.sh 的 smoke 區段新增四個共用小函式:smoke_deny_rc 給結束碼、smoke_deny_mark 給擋人標記、smoke_deny_ok 做判定、smoke_deny_desc 產生失敗訊息。
- smoke_rs_case 與 smoke_vg_case 的判定改走 smoke_deny_ok,五個呼叫點的預期值由結束碼 2 改成字面值 deny。
- 三份 manifest 的版本一起提升,由 sync-skill-manifest.sh 同步。

Why:
- 兩個函式把「擋下」寫死成結束碼 2,但擋下的形態是由 deny.sh 依 CLI 決定的。claude、codex、copilot 與認不得的代號走 stderr 加結束碼 2;antigravity 改印一行 stdout 的 deny JSON,kiro 只能注入警告,這兩支的結束碼都固定 0。
- 結果是這兩支的 smoke 各有五條判定失敗,回報成執行期錯誤。但擋人訊息其實都正確印出來了,配套的訊息斷言也全部通過,壞的只有結束碼那一項比對——是斷言認錯形態,不是 hook 失效。
- 不能改成一律放寬到 0。那兩支上放行也是 0,放寬之後「該擋沒擋」與「正確擋下」完全同形,這道斷言等於作廢。

How:
- 形態表在 smoke 這側鏡射一份,事實來源仍是 deny.sh 的 case。表只有一份,改一支不會忘了另一支。
- 判定同時比結束碼與擋人標記;預期放行的案例反過來要求標記不得出現,所以「該擋沒擋」與「不該擋卻擋了」兩個方向都守得住。
- 走 stderr 的三支標記為空字串,判定行為與原本完全相同,不產生回歸。
- 斷言條數不增不減,兩個預期條數常數都不必動。
- 反向測試確認斷言仍然有效:拿掉 deny.sh 裡 antigravity 的 deny JSON 輸出,做出該擋卻靜靜放行的情境,smoke 正確判失敗。結束碼相同,靠擋人標記才分得出來。

Who:
接線後的冒煙測試在 antigravity 與 kiro 上判定失敗,追出來的是斷言本身的缺陷。
admin merged commit 417fe1a413 into develop 2026-09-01 03:50:58 +00:00
admin deleted branch fix/smoke-deny-assertion-per-cli 2026-09-01 03:50:58 +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#60