閘教的那條出路要真的走得通(inkstone/ISEP#112)
comment-carries-task-guard 擋下留言時教人跑 `scripts/ticket subtask …`,
而那一行跑不動。兩個獨立的原因,各自都足以害死它:
① 相對路徑對「貼上去那個人的 cwd」解析。總管的 cwd 是 InkStoneCo/,
那裡的 scripts/ticket 是停在 08-27 之前的舊複本(grep -c subtask → 0),
照著貼只印出它「四個動詞」的說明然後 exit 0。
② 用法是手抄的第二份,而它已經漂了:寫了 --assign 卻沒有 --next,
正本會因為「指派了人卻沒寫 --next」直接擋下(exit 2,在打 API 之前)。
修法是拿掉可以漂的那一格,不是把兩份對齊一次:
- 路徑 scripts/ticket 的 self_path()(__file__ 的絕對路徑)
⇒ 印指令的人與跑指令的人是同一個檔案
- 用法 USAGE / usage_text() 一份,閘去 `ticket usage subtask --example` 現要
- 內文模板 body_template() 由 REQUIRED_SECTIONS 現生,跟檢查同源
新增動詞 `ticket usage <verb> [--example] [--parent] [--draft]`。
閘的訊息改成整塊可貼可跑:腳本絕對路徑、母票已填、內文草稿附在同一塊裡,
只剩標題/目標/驗收條件三格是機器不可能知道的。
正本叫不動時 fail-open 的只有「訊息內容」(只指路,不補一份手抄用法),
擋不擋不受影響。
測試 scripts/test-comment-carries-task-guard.sh 22 → 29 條。
新增的 ⑮–㉑ 驗的是「出路走不走得通」,不是「有沒有擋」——
⑱ 把閘 stderr 裡那塊指令原樣抽出來、只填三格、真的執行一次,
離開碼必須是 1(走到網路才停);是 2 就代表這個病復發。
六個變異全部驗過會紅(相對路徑/閘自己抄用法/--assign 沒配 --next/
模板寫死少一段/fallback 補回手抄用法)。
版本:待總管定版(plugin update 比的是版本號不是內容)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SP7DiGMfSkWjZ15CHMbPFE
This commit is contained in:
@@ -154,3 +154,48 @@ leo 當場:「**這些為什麼不寫到票裡?**」
|
||||
📌 KBDB 缺這一段: 2026-08-31 用 `kbdb_search(mode='semantic')` 查
|
||||
「SDD 生命週期/單一活性/取消 Active SDD」**0 命中**(最接近的是 2026-08-09
|
||||
一張講 SDD × Gitea 整合摩擦的卡,那是裁決之前)。⇒ 這條開發史還沒進 KBDB。
|
||||
|
||||
## ⚠️ MISTAKE: 閘擋對了,但它印出來的那條出路**跑不動**
|
||||
|
||||
票: `inkstone/ISEP#112`
|
||||
日期: 2026-08-31
|
||||
|
||||
症狀: `comment-carries-task-guard.sh` 擋下留言時教你跑
|
||||
`scripts/ticket subtask …`。照著貼,會印出一段「四個動詞」的說明然後
|
||||
什麼都沒發生。被擋的人當下正在做別的事,最可能的反應是**找個理由繞過去**。
|
||||
|
||||
實查: 兩個**各自獨立**的原因,任何一個單獨存在都足以害死它——
|
||||
① **相對路徑**。閘印的是 `scripts/ticket`,而相對路徑是對
|
||||
**貼上去那個人的 cwd** 解析的。總管的 cwd 是 `InkStoneCo/`,
|
||||
那裡的 `scripts/ticket` 是正本停在 2026-08-27 之前的舊複本:
|
||||
`grep -c subtask InkStoneCo/scripts/ticket` → **0**(正本是 10)。
|
||||
⇒ 「`subtask` 這個子命令不存在」這個結論**在那個 cwd 底下是真的**。
|
||||
② **用法各寫一份**。閘手抄了一段用法,`cmd_subtask` 的 `die()` 又寫了一段。
|
||||
兩份已經漂了:閘那份寫 `--assign <誰做>` 卻**沒有 `--next`**,
|
||||
而正本會因為「指派了人卻沒寫 --next」直接擋下(實測 exit 2)。
|
||||
⇒ **就算路徑對了,那一行照樣跑不完。**
|
||||
|
||||
原因: 閘的訊息與它教的那支工具是**兩份各自維護的字**。
|
||||
`hooks/lib/beacon_report.py` ② 早就會在 SessionStart 報「專案裡有舊複本」,
|
||||
**但報告不會改掉閘印出來的那一行**——知道有這個坑,跟那一行會不會踩到它,
|
||||
是兩件事。
|
||||
|
||||
正確做法:
|
||||
- **路徑**:印出來要人複製的指令,一律用正本自己的 `__file__` 絕對路徑
|
||||
(`scripts/ticket` 的 `self_path()`)。印指令的人與跑指令的人是同一個檔案,
|
||||
沒有第二種可能。
|
||||
⚠️ 分界線是「**這行字會被誰複製、在哪台機器上跑?**」——
|
||||
要**貼進 Gitea 留言**的指令反而要維持相對寫法(留言會被別台機器讀到)。
|
||||
- **用法**:只留一份(`scripts/ticket` 的 `USAGE`/`usage_text()`),
|
||||
閘去 `ticket usage subtask --example` 現要,不自己抄。
|
||||
- **模板**:子票內文草稿由 `REQUIRED_SECTIONS` 現生(`body_template()`),
|
||||
跟檢查同源 ⇒ 不可能生出「照著貼卻過不了自己那道閘」的票。
|
||||
|
||||
🔴 **驗法要驗到「它跑不跑得動」,不是「它有沒有擋」。**
|
||||
`scripts/test-comment-carries-task-guard.sh` ⑱ 把閘 stderr 裡那塊指令
|
||||
**原樣抽出來、只填三格、真的執行一次**:離開碼 1(走到網路才停)=過,
|
||||
2(被某道閘擋下)=這個病復發。⑲ 是它的鑑別力對照組。
|
||||
|
||||
📌 推廣:**一支閘的價值是「擋下來 + 給一條走得通的路」。**
|
||||
出路走不通時它不是幫你,是擋你——而被擋的人不會停下來修閘,
|
||||
他會去找繞過去的方法。所以「出路能不能跑」要跟「判準準不準」一樣被測。
|
||||
|
||||
Reference in New Issue
Block a user