棒子不會掉:子票相依+tag+指派三格,全部用 Gitea 原生欄位
leo 2026-08-27:「子票相依是 gitea 原有機制,改 tag 和指定也是,這些全部都要」 08-26 掉的那一次(arcrun-rag#136 comment 4267「等雲端那半出貨才驗得了」躺了 14 小時)三格全缺:沒有子票、tag 沒動、沒有指派給任何人。根因不是誰忘了, 是那件事沒有落在任何一個「撈一次就看得到」的欄位上。 實測(Gitea 1.26.4):子票還開著時關母票 → HTTP 412 "cannot close this issue or pull request because it still has open dependencies" ⇒ 相依是平台保證的硬擋,不是提醒。跨 repo 也成立(201)。 - scripts/ticket 新增三個動詞:subtask(長子票+掛相依)/ handback(指派+改 tag+寫下一步,一個動作)/mine(撈一次看棒子在誰手上) - hooks/comment-carries-task-guard.sh:留言帶未完成的未來式卻沒開子票 → 擋一次 - hooks/baton-handback-guard.sh:一條線收工,三格缺哪一格當場說出來(提醒不擋) - docs/governance §16:三個維度/粒度(傾向多開票)/既有票只從今天起適用/ 與 s/* 的關係/實測輸出 - 測試 20+10 全綠,用 fixture 跑不打網路、不在票池留測試票 📌 踩到並記進閘的檔頭:hook 裡比對中文一律用 python3 的 re,不要用 grep 的字元類 (等[^。]{0,20}出貨 在真實 hook 呼叫路徑下對「等雲端那半出貨」不匹配,閘靜默失效) 票:inkstone/ISEP#30(comment 4334/4335/4346/4347) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -702,3 +702,142 @@ Gitea 的 milestone 只管得到同一個 repo,所以六個群在 `inkstone/IS
|
||||
**機械閘**=`hooks/milestone-due-guard.sh`(PreToolUse `Bash`):
|
||||
建 milestone 沒有 `due_on`、或 `due_on` 帶 `9999` → 擋。
|
||||
四向實測:無 due_on 擋/9999 擋/真期限放行/只是讀 milestone 放行。
|
||||
|
||||
---
|
||||
|
||||
## 16. 棒子不會掉:三個 Gitea 原生欄位,全部都要(leo 2026-08-27 立)
|
||||
|
||||
> leo 原話:「**不對,子票相依是 gitea 原有機制,改 tag 和指定也是,這些全部都要**」
|
||||
> 「可以在討論串延伸子票,它完成了子票就完工,不然這筆任務就是沒完工⋯⋯**票沒完工可以察覺嗎?**」
|
||||
> 「**每個任務結束必須要指派回總管**,要說明下一步怎麼做,直到最後交出正確 deliverable 並且驗證」
|
||||
|
||||
### 16.0 這一節在解什麼(可重現的掉棒時序)
|
||||
|
||||
```
|
||||
08-26 13:00 一條線交回 arcrun-rag#136 comment 4267:
|
||||
「Phase 1 的驗收在雲端那半出貨之前驗不了」
|
||||
← 一根帶著明確解除條件的接力棒,但它只是一段文字
|
||||
08-26 18-23 總管把雲端那半併進 main、出 1.4.56、推 prod
|
||||
← 解除條件在這裡被滿足了,沒有任何東西知道
|
||||
08-27 11:xx leo 問「這個 14 小時前的,你派了還是沒派?」
|
||||
← 14 小時後才發現棒子在地上
|
||||
```
|
||||
|
||||
當時那張票:**沒有子票、tag 沒動、沒有指派給任何人**——三格全缺。
|
||||
🔴 **根因不是誰忘了,是那件事沒有落在任何一個「撈一次就看得到」的欄位上。**
|
||||
|
||||
### 16.1 三個維度正交,缺一個就會掉
|
||||
|
||||
| 欄位 | 它回答的問題 | 缺了它會怎樣 |
|
||||
|---|---|---|
|
||||
| **子票 + 相依** | **這件事存在嗎?做完了嗎?** | 任務藏在討論串,撈 open 票看不到它 |
|
||||
| **tag(`s/*`)** | **它現在卡在哪一段?** | 撈得到票,但每次都要重讀整串才知道在等什麼 |
|
||||
| **指派(assignee)** | **現在誰該動?** | 知道有事、知道卡在哪,但**沒人認領** |
|
||||
|
||||
三個都是 Gitea 原生欄位,**都不必自造**(D58:充分利用 gitea 的機制)。
|
||||
|
||||
### 16.2 子票相依是**硬的**,不是提醒(2026-08-27 實測,Gitea 1.26.4)
|
||||
|
||||
```
|
||||
POST /repos/inkstone/ISEP/issues/56/dependencies {"owner","repo","index":57} → 201
|
||||
GET /repos/inkstone/ISEP/issues/56/dependencies → [(57,'open')]
|
||||
PATCH /repos/inkstone/ISEP/issues/56 {"state":"closed"} ← 子票還開著
|
||||
→ HTTP 412
|
||||
{"message":"cannot close this issue or pull request because it still has open dependencies"}
|
||||
關掉 #57 → 再 PATCH #56 state=closed → 201,母票 state=closed
|
||||
```
|
||||
|
||||
⇒ **子票沒關,母票關不掉。這是平台保證,不是自律。**
|
||||
畫面上也看得到:母票側欄出現 `Depends on → #57 …(inkstone/ISEP)`。
|
||||
|
||||
**跨 repo 也成立**(實測 `ISEP#56` 依賴 `arcrun-rag#136` → 201)
|
||||
⇒ 這正是跨 repo 的載體:milestone 只管得到同一個 repo,**相依管得到全部**。
|
||||
|
||||
- **R16.2.1** 順序/阻擋關係一律用相依(同 R2.5),**禁止只寫文字**。
|
||||
- **R16.2.2** 相依掛不上去 = 那張子票對母票是隱形的 ⇒ **視為整個動作失敗**,要當場報錯。
|
||||
|
||||
### 16.3 粒度:**傾向多開票,不是少開票**
|
||||
|
||||
> leo 2026-08-27(當場更正總管寫反的那條):
|
||||
> 「**小任務做完就關閉,不會讓池子爆掉,每個事情沒有歷史記錄才是大問題**」
|
||||
|
||||
```
|
||||
這件事需要被記得嗎?(做過什麼、為什麼、量到什麼)
|
||||
需要 → 開票。做完就關。
|
||||
不需要 → 才不開
|
||||
```
|
||||
|
||||
🔴 **不要用「會不會太多」當判準。** 池子爆掉的前提是「開了不關」——
|
||||
那由 **做完就關** 解決,不該由 **不開票** 解決。
|
||||
|
||||
三條線不衝突,順序是:
|
||||
1. **要不要有票**(本節)——傾向要。判準:這件事需要被記得嗎。
|
||||
2. **要不要拆成獨立票**(既有規約)——判準:「票的刀口不是大小,是**狀態**:
|
||||
它會不會需要跟隔壁那條不同的狀態?」
|
||||
3. **會不會變成池子**——由「做完就關」解決,不由前兩題解決。
|
||||
|
||||
📌 leo 2026-08-16「我不要把所有的票都放在一個 issues,不然就難 track 歷史記錄」
|
||||
與本節同一個目的:**可追蹤的歷史**。全塞一張 ⇒ 糊成一團;藏在討論串/prompt ⇒ 根本沒有歷史。
|
||||
|
||||
### 16.4 tag 與相依的關係:**流程狀態 vs 結構關係,兩個軸**
|
||||
|
||||
- `s/*` 是**這張票走到哪一格**(§3.0 的七態,exclusive)。
|
||||
- 相依是**這張票和別張票的結構關係**。
|
||||
- 兩者不衝突,也不能互相取代:
|
||||
- 一張票可以 `s/doing` 而且有未關的相依(它自己有事在做,只是還關不掉)
|
||||
- 一張票可以 `s/pending` 而且沒有相依(它卡的是票池外面的東西,例如等 leo 開閘)
|
||||
- **R16.4.1** 卡在**別張票**上 ⇒ 掛相依 **並** 轉 `s/pending`。
|
||||
只掛相依不改 tag = 看板上它看起來還在動;只改 tag 不掛相依 = 母票關得掉。
|
||||
- **R16.4.2** `Human` 仍是正交 overlay(§6.1),與本節三格互不取代。
|
||||
|
||||
### 16.5 指派:棒子的持有人,**是欄位不是文字**
|
||||
|
||||
可指派的身份只有兩個(2026-08-27 實查):`Leo`、`claude-code`。
|
||||
**總管就是 `claude-code`**(所有票都是這個 token 寫的),不必新增任何身份。
|
||||
|
||||
- **R16.5.1(收工)** 任何一條線收工 = **指派回 `claude-code` + 改 tag + 寫下一步**,
|
||||
三件事是**同一個動作**(`scripts/ticket handback`)。
|
||||
- **R16.5.2(要 leo 做)** 指派 `Leo` + 掛 `Human`(§6.1、既有交棒規約)。
|
||||
- **R16.5.3(終點)** 棒子有終點——leo 的原話是「**直到最後交出正確 deliverable 並且驗證**」。
|
||||
驗完 ⇒ 關票、清指派 ⇒ 它從所有人的待辦裡消失。
|
||||
**不要讓票變成永遠在傳的燙手山芋。**
|
||||
- **R16.5.4(撈一次)** 「哪幾根棒子在誰手上」用 `scripts/ticket mine` 撈,
|
||||
掛在**本來就會做的動作**上(session 開場、收工對帳)。🔴 **禁止排程輪詢**(D20)。
|
||||
|
||||
### 16.6 既有的幾十張票怎麼辦:**只從今天起適用,不回頭補**
|
||||
|
||||
- **R16.6.1** 不做全面回填。理由:回頭讀幾十張票的每一則 comment 是 O(票數×留言數),
|
||||
那正是本節說「人與 AI 都不會做」的那個動作——**用一個不會被執行的規定去補一個漏洞,等於沒補。**
|
||||
- **R16.6.2** 改成**碰到才補**:任何人(或閘)下一次動到某張票時,
|
||||
順手把它討論串裡還活著的待辦長成子票。**動到才補,成本落在本來就要付的那次。**
|
||||
- **R16.6.3** 例外:`hub` 票(§1)**要補齊**——它們本來就宣稱自己是聚合容器,
|
||||
而 §3.2「子票全關才能關 hub」在沒有相依的情況下是**靠自律**的。
|
||||
掛上相依之後,那條規則變成平台保證。
|
||||
✅ **2026-08-27 實查:六張 hub 全部已經掛好了**,且數量與各自內文列的來源票一致——
|
||||
`ISEP#30` 6/`#31` 7/`#32` 11/`#33` 5/`#34` 8/`#35` 7(跨 `InkStoneCo`/`Arcrun`/
|
||||
`arcrun-rag`/`system-dev-template` 四個 repo)。**這一格不用補,本條是為了讓它不再退化。**
|
||||
|
||||
### 16.7 工具與機械閘
|
||||
|
||||
```
|
||||
scripts/ticket subtask <母票> --title <User Story> -F <檔> [--label] [--assign]
|
||||
討論串裡的一件事 → 子票 + 回鏈 Parent: + Gitea 原生相依(三格一次到位)
|
||||
scripts/ticket handback <票> --to <claude-code|Leo> --next "<一句話>" [--label] [--evidence]
|
||||
收工 = 指派 + 改 tag + 寫下一步,一個動作三件事
|
||||
scripts/ticket mine [--user <誰>]
|
||||
撈一次:棒子在誰手上、每根的下一步、每根還有幾張未關的相依
|
||||
```
|
||||
|
||||
| 閘 | 掛在哪 | 抓什麼 | 測試 |
|
||||
|---|---|---|---|
|
||||
| `hooks/comment-carries-task-guard.sh` | PreToolUse `Bash` | 留言裡帶「等 X 才…/驗不了/還沒…」這種**未完成的未來式**,卻沒開子票 → 擋一次 | `scripts/test-comment-carries-task-guard.sh`(20 條) |
|
||||
| `hooks/baton-handback-guard.sh` | PostToolUse `Agent\|Task` | 一條線收工,票上**指派/tag/下一步**缺哪一格 → 當場說出來(提醒,不擋) | `scripts/test-baton-handback-guard.sh`(10 條) |
|
||||
|
||||
🔴 **兩支閘的誤攔設計**:`comment-carries-task-guard` 同一 session 只擋一次,
|
||||
關鍵詞刻意取窄,並留 `no-subtask: <理由>` 逃生口(留痕)。
|
||||
理由寫在 `.claude/branch-holds.md` 檔頭那句:
|
||||
**永遠在響的警報,等於訓練人忽略這個警報。**
|
||||
|
||||
🔴 **hook 裡比對中文一律用 `python3` 的 `re`,不要用 `grep` 的字元類**
|
||||
(2026-08-27 實撞:`等[^。]{0,20}出貨` 在真實 hook 呼叫路徑下對
|
||||
「等雲端那半出貨」不匹配,閘靜默失效;換成 python3 後測試由 19/20 變 20/20)。
|
||||
|
||||
Reference in New Issue
Block a user