e474b4cb6f
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>
61 lines
3.7 KiB
Bash
Executable File
61 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# 討論串裡的任務要長成子票——這道閘的測試
|
|
# 判準:6 種該擋(留言裡真的藏著待辦)、10 種不該擋
|
|
# 🔴 「不該擋」比「該擋」重要:branch-holds.md 檔頭那句——
|
|
# 永遠在響的警報,等於訓練人忽略這個警報。
|
|
cd "$(dirname "$0")/.." || exit 1
|
|
H=hooks/comment-carries-task-guard.sh
|
|
PASS=0; FAIL=0
|
|
SID=test-cctg-$$
|
|
run(){ # $1=want $2=cmd
|
|
rm -f "/tmp/.comment-task-guard-warned-$SID"
|
|
printf '%s' "{\"session_id\":\"$SID\",\"tool_name\":\"Bash\",\"tool_input\":{\"command\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$2")}}" \
|
|
| bash "$H" >/dev/null 2>&1
|
|
got=$?
|
|
if [ "$got" = "$1" ]; then PASS=$((PASS+1)); printf ' ✅ '; else FAIL=$((FAIL+1)); printf ' ❌ '; fi
|
|
printf 'want=%s got=%s %.62s\n' "$1" "$got" "$2"
|
|
}
|
|
|
|
echo "── 該擋:留言裡藏著一件還沒做完的事 ──"
|
|
# 這一條就是 2026-08-26 真的掉了的那則的形狀
|
|
run 2 'req("POST", f"{API}/repos/inkstone/arcrun-rag/issues/136/comments", {"body":"Phase 1 的驗收在雲端那半出貨之前驗不了"})'
|
|
run 2 'curl -X POST "$API/repos/inkstone/Arcrun/issues/12/comments" -d "{\"body\":\"要等 leo 開閘才能部署\"}"'
|
|
run 2 'req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"[blocker] 收端還沒上線"})'
|
|
run 2 'req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"這條路徑還沒測,先擱著"})'
|
|
run 2 'req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"TODO: 補一條端到端測試"})'
|
|
run 2 'req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"等雲端出貨之後要回頭重驗一次"})'
|
|
|
|
echo "── 不該擋 ──"
|
|
run 0 'curl -s "$API/repos/inkstone/ISEP/issues/30/comments"' # 純讀
|
|
run 0 'req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"已驗過,8/8 全綠"})' # 沒有待辦形狀
|
|
run 0 'scripts/ticket subtask inkstone/arcrun-rag#136 --title "身為x,我要y,我才z" -F /tmp/c.md'
|
|
run 0 'scripts/ticket handback inkstone/arcrun-rag#136 --to claude-code --next "還沒驗的那格去驗"'
|
|
run 0 'scripts/ticket mine'
|
|
run 0 'scripts/ticket close inkstone/x#1 --deliverable https://example.invalid/pr/1'
|
|
run 0 'grep -n "驗不了" hooks/comment-carries-task-guard.sh' # 只是讀這支閘
|
|
run 0 'echo "這則留言等雲端出貨才驗得了 —— no-subtask: 它已經有子票 #143 了"' # 逃生口
|
|
run 0 'curl -X POST "$API/repos/x/y/issues" -d "{\"title\":\"等出貨\"}"' # 開新票不歸這支管
|
|
run 0 'req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"🏃 **棒子交回** → claude-code\n\n**下一步**:等 #143"})'
|
|
|
|
echo "── 同一 session 只擋一次(不鬼打牆)──"
|
|
rm -f "/tmp/.comment-task-guard-warned-$SID"
|
|
C='req("POST", f"{API}/repos/x/y/issues/3/comments", {"body":"驗不了"})'
|
|
for want in 2 0; do
|
|
printf '%s' "{\"session_id\":\"$SID\",\"tool_name\":\"Bash\",\"tool_input\":{\"command\":$(python3 -c 'import json,sys;print(json.dumps(sys.argv[1]))' "$C")}}" \
|
|
| bash "$H" >/dev/null 2>&1
|
|
got=$?
|
|
if [ "$got" = "$want" ]; then PASS=$((PASS+1)); printf ' ✅ '; else FAIL=$((FAIL+1)); printf ' ❌ '; fi
|
|
printf 'want=%s got=%s 第 %s 次同樣的指令\n' "$want" "$got" "$([ "$want" = 2 ] && echo 1 || echo 2)"
|
|
done
|
|
|
|
echo "── -F <檔>:內文在檔案裡也要看得到 ──"
|
|
TMPF=$(mktemp); printf '這件事等雲端那半出貨才驗得了\n' > "$TMPF"
|
|
run 2 "scripts/ticket say inkstone/arcrun-rag#136 -F $TMPF"
|
|
printf '已驗完,全部綠燈\n' > "$TMPF"
|
|
run 0 "scripts/ticket say inkstone/arcrun-rag#136 -F $TMPF"
|
|
rm -f "$TMPF" "/tmp/.comment-task-guard-warned-$SID"
|
|
|
|
echo
|
|
echo "$PASS/$((PASS+FAIL)) 通過"
|
|
[ "$FAIL" = 0 ]
|