每個里程碑都要有真的期限,9999 也擋

leo 2026-08-21:「以後所有的 milestone 限制時間」「你根本沒有時間概念,浪費一整天」

實查七個 open milestone:六個期限是 9999-01-01、一個空白。
9999 比空白更糟——盤點時每一格看起來都有值,
於是沒有人發現這裡從來沒有時間壓力。七個已全部改成真日期。

新增 hooks/milestone-due-guard.sh,四向實測:
  無 due_on → exit 2
  due_on 帶 9999 → exit 2
  真期限 → exit 0
  只是讀 milestone → exit 0

規範補 M4.8(怎麼定期限、過期只對帳不自動關)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 01:25:12 +08:00
parent 1920d4cb06
commit 6772ca67d3
4 changed files with 73 additions and 2 deletions
+5 -1
View File
@@ -40,6 +40,10 @@
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/ticket-api-bypass-guard.sh"
},
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/milestone-due-guard.sh"
}
]
},
@@ -323,4 +327,4 @@
}
]
}
}
}
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# milestone-due-guard.sh — 建 milestone 一定要有真的期限(leo 2026-08-21 立)
#
# leo 原話:「**以後所有的 milestone 限制時間**」
# 「**你根本沒有時間概念,浪費一整天**」
#
# 🔴 為什麼連 9999 也要擋:立這條的當下實查七個 open milestone
# 六個的期限是 `9999-01-01`——那是「沒有期限」穿了一件期限的衣服,
# 比空白更糟,因為它讓盤點時看起來每一格都有值。
set -uo pipefail
INPUT=$(cat)
CMD=$(printf '%s' "$INPUT" | python3 -c "import json,sys;print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null || echo "")
[ -z "$CMD" ] && exit 0
# 只管「建 milestone」這個動作
printf '%s' "$CMD" | grep -qE 'milestones' || exit 0
printf '%s' "$CMD" | grep -qE '\-X *POST|--request *POST' || exit 0
DUE=$(printf '%s' "$CMD" | grep -oE '"due_on"[^,}]*' | head -1)
BAD=""
[ -z "$DUE" ] && BAD="沒有 due_on"
printf '%s' "$DUE" | grep -q '9999' && BAD="due_on 是 9999(等於沒有期限)"
[ -z "$BAD" ] && exit 0
cat >&2 <<MSG
⏱️ 里程碑期限閘:$BAD
【leo 2026-08-21】「**以後所有的 milestone 限制時間**」
「**你根本沒有時間概念,浪費一整天**」
🔴 9999-01-01 也算違規。立這條的當下實查七個 open milestone
六個是 9999——那是「沒有期限」穿了一件期限的衣服,
比空白更糟,因為盤點時每一格看起來都有值。
怎麼定:這個里程碑的 deliverable 是**一個可測的版本**。
問「這個版本幾號要能給 leo 打開?」,那天就是期限。
剩 1–3 張票 → 一週;4 張以上 → 兩週;本週要收 → 三天。
加上去再送一次: "due_on": "YYYY-MM-DDT23:59:59Z"
MSG
exit 2