身為交出 PR 的人,我要它兩週內有人給結論,我才不會做完的東西永遠進不了版本 #95

Closed
claude-code wants to merge 1 commits from feat/pr-verdict-guard into main
Member

inkstone/ISEP#81

這一版解掉什麼

實查(2026-08-27):inkstone org 有 7 個 open PR,最久的三個躺了兩星期,
而 v0.9.0 的 46 支閘一支都沒有在管 PR。票看起來「已交付」,
東西卻沒進 main ⇒ 沒進版本 ⇒ leo 手上永遠不會出現它

兩件東西

1. hooks/pr-verdict-guard.sh(Stop,F 組)

收工那一刻清點:open、沒有人被指派、也沒有 REQUEST_CHANGES review 的 PR ⇒ 擋一次並
點名是哪幾個(含開了幾天與網址)。已經 merge 但 head 分支還留著的一起點名
——票上寫死「merge → 併完當場刪掉那條 branch」,分支還在=結論只給了一半

🔴 票上點名要避開的那條錯路(ISEP v0.6.0 divergence §B4:「s/review 佇列非空即 block」
⇒ 佇列本來就不會空 ⇒ 總管永遠停不下來)。所以擋的是遺忘,不是等待,四層都用來放掉「等待」:

情況 為什麼放掉
有人被指派 / 掛 Human 棒子在他手上。指派是 Gitea 原生欄位,不是措辭(同 baton-handback-guard 的三格表)
REQUEST_CHANGES review 「要求修改」這個結論已經給了,球在對方腳下
這一回合碰過它 見下
響過就退讓 每個 PR 各自 1 → 4 → 8 → 16,不可能鎖死

「碰過」不讀任何一句話:① updated_at 跟上次收工比變了(外部系統的事實:留言/推 commit/
改標籤/submit review 都會動它)② 上次收工時還不存在(不在它誕生的那一回合就開罵
③ 這一回合的 tool call 出現它的識別碼——這條是為了接住「結論寫在上」這種本票規定的合法結論。

🔴不是關鍵字黑名單(工單紅線)。差別在方向與集合:黑名單拿措辭
(措辭無限,leo 2026-08-17 已證偽:當日 8 次誤攔、0 次正確攔截);
這裡拿識別碼放行(唯一且有限,比對錯了只會少擋一次)。
本 repo 心法:只准往放行的方向做字面比對。

刻意只掛 Stop,不掛 SubagentStop:給 PR 結論是總管的權,subagent 連 main 都不准推
⇒ 掛上去只會變成對它的誤攔。

2. scripts/pr-verdict —— 三種結論各是一個動作

pr-verdict merge   <owner/repo#N>                       併 + 刪分支 + 當場複驗分支真的不見了
pr-verdict reject  <owner/repo#N> --ticket <票> -F <檔>  理由寫進**票** + 關 PR + 刪分支
pr-verdict changes <owner/repo#N> --ticket <票> -F <檔>  修改要求寫進**票** + 留 REQUEST_CHANGES
pr-verdict list                                         撈一次:誰還沒有結論

所有掉棒的形狀都長一樣——第一個動作做了,第二個沒有。綁成一個指令,
就沒有「忘了做第二件」這個狀態可以存在。merge複驗分支真的查不到了才回報成功
(下了刪除指令 ≠ 它被刪掉;保護分支/跨 fork 都會讓它失敗)。
--dry-run 把要打的每一通 API 印出來但一通都不送出

驗過的(docs/TESTING.md A14/A15)

bash hooks/tests/pr-verdict-guard.test.sh     → 52 通過 / 0 失敗

離線走 PR_VERDICT_FIXTURE不打 Gitea、不開測試 PR、不留任何測試票

在證什麼
A 不該擋 8 沒 PR/有指派/掛 Human/draft/不在 org/有 REQUEST_CHANGES/已被別的 Stop 閘擋過/fixture 壞掉
B 該擋 3 票上那三個真跡 arcrun-rag#91Arcrun#116Arcrun#104,訊息逐一點名
C 驗收 1–3 7 放著不管→擋;merge 且分支已刪→放行;merge 了分支還在→擋並點名分支
D 碰過就不點名 11 updated_at 變了 5 次都不擋;指名它 5 次都不擋;指名別的票號 → 照擋
E 退讓 23 1→4→8 三段門檻都量過;指派下去之後連 9 個回合永遠不再點名

真跡也在真實 Gitea 上唯讀重演過(不改動任何 PR):一次點名 7 個沒有結論的 PR,
含票上那三個(15/14/14 天)。指令與輸出見票上留言。

既有測試沒被弄壞:mainline-idle-guard 61/61、dispatch-format-guard 33/33、
factory-idle-guard 33/33。

給複審的人

  • scripts/check-version-consistency.sh 現在會紅:plugin.json 已是 0.10.0
    v0.10.0 的 tag 還沒打。tag 是併進 main 之後總管的動作release-tag-guard 管那道),
    分支上打不了。這與 #78#79#80 的做法一致。
  • 數字都是當場數出來的ls hooks/*.sh | wc -l = 52、
    grep -c '"command":' hooks/hooks.json = 65。
    順手改掉 plugin.json 描述欄長期寫的「27 支腳本」——實數 34
    ls -p scripts | grep -v / | wc -l)。
  • 本 PR 沒有推 main、沒有部署任何東西、沒有動任何既有 PR。
關 `inkstone/ISEP#81`。 ## 這一版解掉什麼 實查(2026-08-27):`inkstone` org 有 **7 個 open PR**,最久的三個躺了兩星期, 而 v0.9.0 的 46 支閘**一支都沒有在管 PR**。票看起來「已交付」, 東西卻沒進 main ⇒ 沒進版本 ⇒ **leo 手上永遠不會出現它**。 ## 兩件東西 ### 1. `hooks/pr-verdict-guard.sh`(Stop,F 組) 收工那一刻清點:**open、沒有人被指派、也沒有 `REQUEST_CHANGES` review 的 PR** ⇒ 擋一次並 **點名是哪幾個**(含開了幾天與網址)。已經 merge 但 **head 分支還留著**的一起點名 ——票上寫死「merge → 併完當場刪掉那條 branch」,分支還在=**結論只給了一半**。 🔴 **票上點名要避開的那條錯路**(ISEP v0.6.0 divergence §B4:「`s/review` 佇列非空即 block」 ⇒ 佇列本來就不會空 ⇒ 總管永遠停不下來)。所以**擋的是遺忘,不是等待**,四層都用來放掉「等待」: | 情況 | 為什麼放掉 | |---|---| | 有人被指派 / 掛 `Human` | 棒子在他手上。指派是 Gitea **原生欄位**,不是措辭(同 `baton-handback-guard` 的三格表) | | 有 `REQUEST_CHANGES` review | 「要求修改」這個結論已經給了,球在對方腳下 | | 這一回合碰過它 | 見下 | | 響過就退讓 | 每個 PR **各自** 1 → 4 → 8 → 16,不可能鎖死 | **「碰過」不讀任何一句話**:① `updated_at` 跟上次收工比變了(外部系統的事實:留言/推 commit/ 改標籤/submit review 都會動它)② 上次收工時還不存在(**不在它誕生的那一回合就開罵**) ③ 這一回合的 tool call 出現它的識別碼——這條是為了接住「結論寫在**票**上」這種本票規定的合法結論。 > 🔴 ③ **不是關鍵字黑名單**(工單紅線)。差別在方向與集合:黑名單拿**措辭**來**擋** > (措辭無限,leo 2026-08-17 已證偽:當日 8 次誤攔、0 次正確攔截); > 這裡拿**識別碼**來**放行**(唯一且有限,比對錯了只會**少擋一次**)。 > 本 repo 心法:只准往放行的方向做字面比對。 **刻意只掛 `Stop`,不掛 `SubagentStop`**:給 PR 結論是總管的權,subagent 連 main 都不准推 ⇒ 掛上去只會變成對它的誤攔。 ### 2. `scripts/pr-verdict` —— 三種結論各是**一個動作** ``` pr-verdict merge <owner/repo#N> 併 + 刪分支 + 當場複驗分支真的不見了 pr-verdict reject <owner/repo#N> --ticket <票> -F <檔> 理由寫進**票** + 關 PR + 刪分支 pr-verdict changes <owner/repo#N> --ticket <票> -F <檔> 修改要求寫進**票** + 留 REQUEST_CHANGES pr-verdict list 撈一次:誰還沒有結論 ``` 所有掉棒的形狀都長一樣——**第一個動作做了,第二個沒有**。綁成一個指令, 就沒有「忘了做第二件」這個狀態可以存在。`merge` 會**複驗分支真的查不到了**才回報成功 (下了刪除指令 ≠ 它被刪掉;保護分支/跨 fork 都會讓它失敗)。 `--dry-run` 把要打的每一通 API 印出來但**一通都不送出**。 ## 驗過的(`docs/TESTING.md` A14/A15) ``` bash hooks/tests/pr-verdict-guard.test.sh → 52 通過 / 0 失敗 ``` 離線走 `PR_VERDICT_FIXTURE`,**不打 Gitea、不開測試 PR、不留任何測試票**。 | 群 | 條 | 在證什麼 | |---|---|---| | A 不該擋 | 8 | 沒 PR/有指派/掛 Human/draft/不在 org/有 REQUEST_CHANGES/已被別的 Stop 閘擋過/fixture 壞掉 | | B 該擋 | 3 | **票上那三個真跡** `arcrun-rag#91`/`Arcrun#116`/`Arcrun#104`,訊息逐一點名 | | C 驗收 1–3 | 7 | 放著不管→擋;merge 且分支已刪→放行;**merge 了分支還在→擋並點名分支** | | D 碰過就不點名 | 11 | `updated_at` 變了 5 次都不擋;指名它 5 次都不擋;**指名別的票號 → 照擋** | | E 退讓 | 23 | 1→4→8 三段門檻都量過;**指派下去之後連 9 個回合永遠不再點名** | **真跡也在真實 Gitea 上唯讀重演過**(不改動任何 PR):一次點名 7 個沒有結論的 PR, 含票上那三個(15/14/14 天)。指令與輸出見票上留言。 既有測試沒被弄壞:`mainline-idle-guard` 61/61、`dispatch-format-guard` 33/33、 `factory-idle-guard` 33/33。 ## 給複審的人 - `scripts/check-version-consistency.sh` 現在會紅:`plugin.json` 已是 **0.10.0**, 但 `v0.10.0` 的 tag 還沒打。**tag 是併進 main 之後總管的動作**(`release-tag-guard` 管那道), 分支上打不了。這與 `#78`/`#79`/`#80` 的做法一致。 - 數字都是**當場數出來的**:`ls hooks/*.sh | wc -l` = 52、 `grep -c '"command":' hooks/hooks.json` = 65。 順手改掉 `plugin.json` 描述欄長期寫的「27 支腳本」——實數 **34** (`ls -p scripts | grep -v / | wc -l`)。 - **本 PR 沒有推 main、沒有部署任何東西、沒有動任何既有 PR。**
claude-code added 1 commit 2026-08-28 00:06:33 +00:00
實查(2026-08-27):inkstone org 有 7 個 open PR,最久的三個躺了兩星期
(Arcrun#104 15 天、Arcrun#116 14 天、arcrun-rag#91 14 天),
而 v0.9.0 的 46 支閘一支都沒有在管 PR。票看起來「已交付」,
東西卻沒進 main ⇒ 沒進版本 ⇒ leo 手上永遠不會出現它。

新增 hooks/pr-verdict-guard.sh(Stop,F 組)
  open、沒有人被指派、也沒有 REQUEST_CHANGES review 的 PR ⇒ 擋一次並點名
  (含開了幾天與網址);merge 了但 head 分支還留著的一起點名
  ——票上寫死「merge → 併完當場刪掉那條 branch」,分支還在=結論只給了一半。

  🔴 票上點名要避開的錯路(ISEP v0.6.0 divergence §B4):
     「佇列非空即 block」會讓總管永遠停不下來。所以擋的是遺忘,不是等待——
     ① 有人被指派/掛 Human ⇒ 不點名(棒子在他手上,是 Gitea 原生欄位不是措辭)
     ② 有 REQUEST_CHANGES review ⇒ 結論給過了,球在對方腳下
     ③ 這一回合碰過它 ⇒ 不點名
     ④ 響過就退讓:每個 PR 各自 1→4→8→16

  「碰過」不讀任何一句話:① updated_at 跟上次收工比變了(外部系統的事實)
  ② 上次收工時還不存在(剛開出來,不在誕生的回合開罵)
  ③ 這回合的 tool call 出現它的識別碼(接住「結論寫在票上」這種合法結論)。
  ③ 不是關鍵字黑名單——黑名單拿措辭來「擋」,這裡拿識別碼來「放行」,
  比對錯了只會少擋一次。leo 2026-08-17 證偽的是前者。

  刻意只掛 Stop 不掛 SubagentStop:給 PR 結論是總管的權,subagent 連 main 都不准推。

新增 scripts/pr-verdict —— merge/reject/changes 各是一個動作
  merge   併 + 刪分支 + **當場複驗分支真的不見了**(下了刪除指令 ≠ 它被刪掉)
  reject  理由寫進票 + 關 PR + 刪分支
  changes 修改要求寫進票 + 留 REQUEST_CHANGES(讓「給過結論」變成閘查得到的事實)
  list / --dry-run(按下去之前先看會打哪幾通 API,一通都不送出)

測試 hooks/tests/pr-verdict-guard.test.sh:52 條全過,離線走 fixture,
不打 Gitea、不開測試 PR、不留測試票。A 群 8 條全在證「不該擋」。
另用真實 Gitea 唯讀重演過票上那三個真跡(一次點名 7 個)。

順手:plugin.json 的「27 支腳本」是過期數字,實數 34
(ls -p scripts | grep -v / | wc -l)——同一個病,只是換一欄。

版本 0.9.0 → 0.10.0。tag 待併入 main 後由總管打(release-tag-guard 管那道)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
Author
Member

【身份】subagent/ISEP

這個 PR 由 inkstone/ISEP#97 取代,現在關閉並刪掉分支。

原因:#95 推不上去(github-contact-guard 把推 Gitea 判成推 GitHub,
證據在 inkstone/ISEP#90#issuecomment-5151),總管改走 Gitea 的 /contents/ API
另開 feat/pr-verdict-v2 送出 ⇒ #97 已併、v0.11.0 已發、inkstone/ISEP#81 已關。

刪分支前確認過內容一個位元都沒少——我改的 7 個檔逐一對 main 的 sha256:

hooks/pr-verdict-guard.sh            ✅ 相同
hooks/tests/pr-verdict-guard.test.sh ✅ 相同
scripts/pr-verdict                   ✅ 相同
hooks/hooks.json                     ✅ 相同
.claude-plugin/plugin.json           ✅ 相同
docs/TESTING.md                      ✅ 相同
docs/hooks-inventory.md              ✅ 相同

📌 這則留言本身就是 #81 那條規約在管的事:一個 open、沒人指派、沒有結論的 PR
就是它要抓的目標——而它抓到的第一個會是我自己開的這個。留著不處理,
等於剛出貨的那支閘上線第一天就有一筆該響的沒響。

【身份】subagent/ISEP **這個 PR 由 `inkstone/ISEP#97` 取代,現在關閉並刪掉分支。** 原因:`#95` 推不上去(`github-contact-guard` 把推 Gitea 判成推 GitHub, 證據在 `inkstone/ISEP#90#issuecomment-5151`),總管改走 Gitea 的 `/contents/` API 另開 `feat/pr-verdict-v2` 送出 ⇒ `#97` 已併、`v0.11.0` 已發、`inkstone/ISEP#81` 已關。 **刪分支前確認過內容一個位元都沒少**——我改的 7 個檔逐一對 `main` 的 sha256: ``` hooks/pr-verdict-guard.sh ✅ 相同 hooks/tests/pr-verdict-guard.test.sh ✅ 相同 scripts/pr-verdict ✅ 相同 hooks/hooks.json ✅ 相同 .claude-plugin/plugin.json ✅ 相同 docs/TESTING.md ✅ 相同 docs/hooks-inventory.md ✅ 相同 ``` 📌 **這則留言本身就是 `#81` 那條規約在管的事**:一個 open、沒人指派、沒有結論的 PR 就是它要抓的目標——**而它抓到的第一個會是我自己開的這個**。留著不處理, 等於剛出貨的那支閘上線第一天就有一筆該響的沒響。
claude-code closed this pull request 2026-08-28 00:36:39 +00:00

Pull request closed

Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: inkstone/ISEP#95