一次交貨 = 一份跨 repo 版本清單(inkstone/ISEP#84)
+ 每次結案都留下估多久/花多久/差多少(inkstone/ISEP#85) #84:scripts/release-manifest freeze 前每一格都真的去 Gitea 抓過(抓不到不給凍結);凍結後不准再加東西; rollback 一定吐出整份清單的每一格,--only 指名單一 repo 會被擋下 ——那正是票上那個病:剩下的還停在新版 ⇒ 一組從來沒測過的組合。 清單與 INDEX.md 寫在專案根的 releases/(不是 plugin 目錄,plugin update 會清掉)。 #85:scripts/milestone-account + hooks/milestone-account-guard.sh 三個數字自己算(取自 Gitea 的 created_at/due_on/closed_at,不用手填); 差超過 ±25%(超時或提早都算)就要從七個固定代號裡挑一個,挑不出來不准結案; 代號要有 Gitea 時間軸撐得住——訊號不成立的代號直接拒收(不採信自述)。 閘擋的是「直接 curl PATCH state=closed 但還沒記帳」,正門走 milestone-account close。 盤點數字在本樹實數(ls hooks/*.sh|grep -c '"command":'): hooks 53→54 支、註冊 68→69 條、scripts 39 支(描述欄舊的 38 把三個目錄也數進去了)。 順手修掉 docs/hooks-inventory.md「一句話結論」被貼兩次、且標頭 52/內文 53 互相矛盾。 測試(全部離線,不打 Gitea、不留測試票/不關真的 milestone): scripts/test-release-manifest.sh 21/21 scripts/test-milestone-account.sh 23/23 hooks/tests/milestone-account-guard.test.sh 22/22 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
This commit is contained in:
@@ -165,6 +165,68 @@ bash hooks/tests/prod-write-guard.test.sh hooks/prod-write-guard.sh
|
||||
- 「卡點二」2 條任一紅 ⇒ 「談論它」又被當成「執行它」(同款第八次),
|
||||
或是剝了內文之後連真的部署都放行了
|
||||
|
||||
### A16 — 一次交貨 = 一份清單(跨 repo 版本組合):21 條
|
||||
```
|
||||
bash scripts/test-release-manifest.sh
|
||||
```
|
||||
**該看到**:`通過 21 條,失敗 0 條`。全程離線(`RELEASE_MANIFEST_FIXTURE`),
|
||||
**不打 Gitea、不建任何真的 release**;清單寫在 `mktemp` 的目錄,不碰 repo 裡的 `releases/`。
|
||||
|
||||
**它在守什麼**(`inkstone/ISEP#84`):一次交貨常常同時動到好幾個 repo,
|
||||
而「這一版 = 哪幾個 repo 的哪幾版」**沒有任何地方記著** ⇒ 退版只退了其中一個,
|
||||
剩下的還停在新版 ⇒ **變成一組從來沒測過的組合**。
|
||||
|
||||
**失敗**:
|
||||
- ⑨⑩ 紅 ⇒ 驗收 1 沒過:**版本號寫上去就算數**,沒有真的去 Gitea 抓過
|
||||
(「寫上去」跟「存在」是兩件事,而清單的用處完全建立在後者)
|
||||
- ⑱ 紅 ⇒ 驗收 3 沒過:**只退其中一個 repo 沒有被擋下來**,那正是票上那個病
|
||||
- ⑯⑰⑲ 任一紅 ⇒ 驗收 2 沒過:退版沒有吐出整份清單的每一格
|
||||
(包含「已經在目標版本、不必動」那幾格——列出來才證明沒有一格被漏掉)
|
||||
- ⑫ 紅 ⇒ 凍結過的清單還能再加東西,「凍結」兩個字就沒有意義了
|
||||
- ⑳㉑ 紅 ⇒ 驗收 4 沒過:leo 打開 `INDEX.md` 看不出「我現在手上是哪一版」
|
||||
|
||||
### A17 — 每次結案都留下估多久/花多久/差多少:23 條
|
||||
```
|
||||
bash scripts/test-milestone-account.sh
|
||||
```
|
||||
**該看到**:`通過 23 條,失敗 0 條`。全程離線(`MILESTONE_ACCOUNT_FIXTURE` =一份假的
|
||||
Gitea 回應表),時鐘用 `MILESTONE_ACCOUNT_NOW` 定住,帳本寫在 `mktemp` 目錄,
|
||||
**不打 Gitea、不關任何真的 milestone**。
|
||||
|
||||
**它在守什麼**(`inkstone/ISEP#85`,leo 2026-08-27 說那天「**拖時間**」):
|
||||
拖了多久、比預計多拖多少、為什麼拖——**沒有任何數字**。偵測器早就有了
|
||||
(`mainline-idle-guard.sh`/`factory-idle-guard.sh`),**但沒有人把它算成帳**。
|
||||
|
||||
**失敗**:
|
||||
- ①②③④ 任一紅 ⇒ 驗收 1 沒過:三個數字不是自己算出來的
|
||||
- ⑤⑥ 紅 ⇒ 驗收 2 沒過:差超過 ±25% 卻能不挑代號就結案
|
||||
- ⑧ 紅 ⇒ 代號不再是封閉集合。**能統計的前提是分類有限**,這一格垮了統計就垮了
|
||||
- ⑨ 紅 ⇒ **挑一個時間軸撐不住的代號也能過**,等於「採信我自己說的」,
|
||||
而票上寫死證據一律從 Gitea 的時間軸取
|
||||
- ⑦ 紅 ⇒ **誤攔**:只差 -6% 也逼人挑代號。這比漏擋嚴重——每次結案都被念,
|
||||
人就學會繞過去
|
||||
- ⑭⑮⑯⑰ 任一紅 ⇒ 驗收 3 沒過:累積之後看不出哪一種原因最常發生
|
||||
- ⑱⑲ 紅 ⇒ 驗收 4 沒過:拿已經逾期的里程碑進去算不出數字
|
||||
|
||||
### A18 — 結案要記帳的那道閘:22 條
|
||||
```
|
||||
bash hooks/tests/milestone-account-guard.test.sh
|
||||
```
|
||||
**該看到**:`通過 22 條,失敗 0 條`。離線(帳本走 `MILESTONE_ACCOUNT_LEDGER`),
|
||||
純結構判斷、沒有語意判官,所以每次結果都一樣。
|
||||
|
||||
**失敗**:
|
||||
- **A 群任何一條紅 ⇒ 誤攔,這比漏擋嚴重。** ⑥⑦⑧⑪ 特別重要:
|
||||
`echo` 一段指令、`cat` 這支閘自己、commit 訊息裡提到、把指令寫進文件的 heredoc 內文
|
||||
——**四種都只是「談論它」,不是「執行它」**。這四格是本 repo 撞過很多次的同一個病
|
||||
(`strip_heredoc.py` 的檔頭記著兩次真跡)
|
||||
- ⑨⑩ 紅 ⇒ 走正門 `scripts/milestone-account close` 反而被自己的閘擋下,
|
||||
那道閘就等於封死了唯一的出路
|
||||
- ⑭⑮⑯⑰⑱ 任一紅 ⇒ 漏擋:換個寫法(`python urllib`、前面串一個無害指令、
|
||||
`--request` 長寫法、換一個 repo)就繞過去了
|
||||
- ⑲ 紅 ⇒ 訊息沒有點名目標,人看完不知道要對哪一個里程碑動手
|
||||
- ⑳㉑ 紅 ⇒ 「記過帳就放行」這個出路是假的,或者一記帳就把所有里程碑全開了
|
||||
|
||||
### A5 — 開票前的搜尋是跨 repo 的
|
||||
```
|
||||
python3 scripts/ticket where 標籤 模組化
|
||||
@@ -362,6 +424,9 @@ B2(信標那行)/B3(setup 輸出)/B4(閘的訊息)三個畫面
|
||||
| **A15 pr-verdict --dry-run** | 總管 | ✅(2026-08-28) |
|
||||
| **A14 回覆自己說出拖了多久** | 總管 | ✅ 20/20(2026-08-28,inkstone/ISEP#63) |
|
||||
| **A15 發通知不等於部署** | 總管 | ✅ 37/37(2026-08-28,inkstone/ISEP#63) |
|
||||
| **A16 跨 repo 版本清單** | 總管 | ✅ 21/21(2026-08-28,inkstone/ISEP#84) |
|
||||
| **A17 估多久/花多久/差多少** | 總管 | ✅ 23/23(2026-08-28,inkstone/ISEP#85) |
|
||||
| **A18 結案要記帳的閘** | 總管 | ✅ 22/22(2026-08-28,inkstone/ISEP#85) |
|
||||
| A5 搜尋跨 repo | 總管 | ✅ |
|
||||
| A6 標籤對齊+冪等 | 總管 | ✅ 14 repo,第二次 0/0 |
|
||||
| **A9 人閘警察管路** | 總管 | ✅ 14/14(2026-08-26) |
|
||||
|
||||
+12
-3
@@ -1,4 +1,4 @@
|
||||
# 52 支閘,白話盤點表
|
||||
# 54 支閘,白話盤點表
|
||||
|
||||
> 回應 `inkstone/InkStoneCo#40`:「如果加入了,我應該可以白話文看到 hooks 的內容?」
|
||||
> 這份表就是那個「白話文」——不用點開任何 `.sh` 檔,一行看懂一支閘在管什麼。
|
||||
@@ -7,8 +7,7 @@
|
||||
|
||||
## 一句話結論
|
||||
|
||||
`hooks/` 底下有 **53 個 `.sh` 檔**,`hooks.json` 實際掛上 **68 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
`hooks/` 底下有 **53 個 `.sh` 檔**,`hooks.json` 實際掛上 **68 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
`hooks/` 底下有 **54 個 `.sh` 檔**,`hooks.json` 實際掛上 **69 條註冊**(同一支閘常被多種情境同時掛上);
|
||||
其中 **3 支檔案存在但沒被掛上**(2 支是待人填的空範本、1 支是刻意留著沒開的止血帶,見下面「未生效」表)。
|
||||
下面按「你會在什麼時候撞到它」分組,一支一行。
|
||||
|
||||
@@ -46,6 +45,15 @@
|
||||
> 順手改掉一個過期的數字:描述欄長期寫「27 支腳本」,實數是 **34**
|
||||
> (`ls -p scripts | grep -v / | wc -l`)——**同一個病,只是換一欄。**
|
||||
|
||||
> 📌 **`inkstone/ISEP#85`(2026-08-28)進來一支**:`milestone-account-guard.sh`(A 組,PreToolUse/Bash)。
|
||||
> 53→**54** 支、68→**69** 條,兩個數字都是加完之後**在自己的樹上當場數出來的**
|
||||
> (指令同上),**不是拿上一版加一**——`system-dev/wiki/mistakes.md` 記著這條:
|
||||
> 那個數字是 leo 的驗收介面,多報就是假綠。
|
||||
> 順手修掉一個真的漂移:上一版「一句話結論」那一句**被貼了兩次**(同一行連續出現兩遍),
|
||||
> 而標頭寫 52、內文寫 53——**同一頁裡三個數字互相矛盾**,正是本頁自己警告過的那種病。
|
||||
> 另外描述欄的「38 支腳本」是把 `kbdb-live-exam/`/`lib/`/`patches/` 三個**目錄**也數進去了;
|
||||
> 用本頁寫死的那道指令(只數檔案)實數是 **39**。
|
||||
|
||||
---
|
||||
|
||||
## 怎麼讀這張表
|
||||
@@ -74,6 +82,7 @@
|
||||
| `release-tag-guard.sh` | AI 想打版本 tag,但 `plugin.json` 裡寫的版本號跟 tag 對不上就擋下——避免「這裡說 0.2.0、那裡說 0.1.0」各說各話。 | 🛑 擋 |
|
||||
| `ticket-api-bypass-guard.sh` | AI 想繞過 `scripts/ticket` 工具、直接打 API 新增 Gitea 東西(開新票/milestone/label/PR,會漏掉「新增前先搜過」這道檢查)就擋下——不管是隱式 POST(urllib 傳 data= 沒寫 method)還是小寫 `requests.post(...)`。 | 🛑 擋 |
|
||||
| `milestone-due-guard.sh` | AI 想開一個新的里程碑(milestone)卻沒填期限就擋下,**填 `9999-01-01` 一樣擋**——那是「沒有期限」穿了一件期限的衣服,盤點時每一格看起來都有值,其實一格都沒有。只管「建里程碑」這個動作,查詢/改別的欄位都放行。 | 🛑 擋 |
|
||||
| `milestone-account-guard.sh` | AI 想直接打 API 把某個里程碑改成「已關閉」,卻**還沒留下「估多久/花多久/差多少/為什麼差」**就擋下。跟上一列是同一條線的兩端:那支管**開**里程碑要有真的期限,這支管**關**的時候要留下帳。走正門 `scripts/milestone-account close` 就會自己算(數字取自 Gitea 的 `created_at`/`due_on`/`closed_at`,不用手填),差超過 ±25% 才要你從**七個固定代號**裡挑一個,而且那個代號要有 Gitea 時間軸撐得住——**不採信自述**。純讀取/建里程碑/改期限/只是談論它/走正門,全部放行;真要手動關就在指令裡加 `milestone-account-ok`(留痕)。 | 🛑 擋 |
|
||||
| `reply-identity-guard.sh` | 直接打 Gitea API 貼留言到票上時,內文第一行沒有 `【身份】`(`總管`/`subagent`/`leo`)就擋下——票上多條線並行時,看不出哪一則是誰寫的。純讀取、走 `scripts/ticket` 正門、指令裡加 `reply-identity-ok` 都放行。 | 🛑 擋 |
|
||||
| `comment-carries-task-guard.sh` | AI 要在票裡留一則「等某某上線才驗得了」這種**還沒做完的事**,卻沒有把它開成一張子票時,擋一次。留言沒人會回頭讀,票的 open/closed 撈一次就看得到。 | 🛑 擋(同一輪只擋一次) |
|
||||
| `search-is-not-proof-guard.sh` | AI 用知識庫的**搜尋**找到一筆東西,然後把那筆東西的原始編號直接貼進票裡或派工單裡,當成「某個功能壞了」的證據——而它從沒用正規的檢索路徑去查過那筆——擋一次。你關心的是:不會再有人拿錯的方法量出一個錯的結論,然後退回一張其實已經做完的票。 | 🛑 擋(同一輪只擋一次) |
|
||||
|
||||
Reference in New Issue
Block a user