RCF-063 — Hook 設定前必評估 timeout 並展示執行鏈計算(IMP-154 升規)
類型:規則變更 日期:2026-06-01 觸發條件:條件 1 — 新增 HARD STOP 規則(🔧 開發模式新增 IMP-154 規則區塊) 里程碑:CLAUDE.md v2.9 → v3.0(首次版本號跨整數里程碑) 相關文件:
C:\Users\USER\Desktop\tzlth-hq\CLAUDE.md(主規則文件,v2.9→v3.0)C:\Users\USER\Desktop\tzlth-hq\.claude\settings.local.json(Stop[0] timeout:60 新增 + Stop[2] 10→60)knowledge/improvements.md(IMP-154 狀態 ⏳→✅;IMP-154 重複編號→IMP-161)
問題背景
precompact-distill-hook.py(2026-05-29 刪除)設定 timeout: 20(秒),實際執行鏈為:
JSONL 讀取 ~2s + Gemini API ~12s + 檔案寫入 ~1s + git add/commit/push 5-15s = 最短 20s、最長 30s。
Hook timeout 在 git push 完成前截斷,導致每次觸發都靜默失敗(exit code 非 0 不中斷 Claude 工作,但蒸餾結果從未寫入)。26 天試行期間 0 次有效蒸餾,直到刪除決策才發現根本從未工作過;設計缺陷被 Claude Code hook 的靜默失敗機制掩蓋。
根本模式:設定 hook timeout 時只考慮「主要任務時長」(Gemini API 12s),未計算完整執行鏈(含 git push 網路延遲 5-15s)。
現有機制缺口:CLAUDE.md 🔧 開發模式有「禁止靠記憶判斷」,但沒有任何規則要求「設定 hook timeout 前計算完整執行鏈」。
改善追溯發現:現有 settings.local.json 中:
- Stop[0] git auto-commit 含
git push origin main但無 timeout → 直接違反擬定規則 - Stop[2] stop-quality-hook.py 執行鏈最長 50s(5 repos × 2 git commands × inner timeout 5s),但 timeout 僅 10s → 不足
- knowledge-hook.py / query-gate-hook.py:補讀腳本確認為純本機操作(< 1s),無 timeout 合理
設計討論(三輪精煉 + 全面盤點框架)
本規則經四輪分析(含 Tim 要求「全面盤點,不要想到什麼才做什麼」觸發的系統性六維度框架),最終確立以下關鍵設計決策:
| 設計點 | 方案 A(排除) | 方案 B(採用) | 排除原因 |
|---|---|---|---|
| 觸發範圍 | 只限 settings.json timeout 值修改 | 包含「修改 hook 腳本執行步驟」 | A 遺漏「新增步驟但未改 timeout」情境(新步驟使執行鏈增長但規則不觸發) |
| 未設 timeout 處理 | 不觸發規則 | 觸發,改為說明掛起風險評估 | A 無法防止「應設未設」情境(與 IMP-154 根本問題並列的第二種風險) |
| 最低 timeout 標準 | 分層(含網路:60s / 純本機:20s) | 統一 60s | A 需要判斷「本次 hook 屬哪類」,判斷本身可能出錯;60s 對 Stop hook 用戶無感知影響(session 正在結束) |
| 執行鏈計算規則 | 只說「各步驟加總」 | 串行/並行/分支三情境明確說明 | A 在並行/條件分支時計算錯誤 |
| Stop hook 鏈安全 | 不要求前序 hook 評估 | 多個 Stop hook 時確認前序均完成 timeout 評估 | A 無法防止前序 hook(如含 git push 的 auto-commit)掛起導致後序 hook 永不執行 |
最終決策
採用方案 B 設計,建立以下規則文字並寫入 CLAUDE.md 🔧 開發模式(繼 IMP-153 之後):
觸發條件(以下任一成立):
① 新增或修改任何 hook 設定(settings.json / settings.local.json,含 inline shell command)
② 修改現有 hook 腳本(.py)的執行步驟
查照必填:
- (A) 是否設定 timeout:設定 → 展示計算表;不設定 → 說明掛起風險評估 + 理由
- (B) timeout 計算表(串行/並行/分支三情境;inner subprocess timeout 計入;無 inner timeout → 標注風險;retry × N;git push 預設 30s;設定值 = ΣX × 1.2,最低 60s)
- (C) Stop hook 鏈:前序含 git push/API 且無 timeout → 標注「⚠️ 後序 hook 可能永不執行」
禁止(5 條):
- 不評估 timeout 需求即新增或修改 hook
- 只計算主要任務時長忽略下游步驟
- 設定 timeout < 執行鏈最長路徑 × 1.0
- Stop hook 鏈含無 timeout 的前序 git push/API hook
- 修改 hook 腳本新增步驟後不重新驗算現有 timeout 是否仍充分
同步修正:settings.local.json
| Hook | 修正前 | 修正後 | 執行鏈最長 | 計算依據 |
|---|---|---|---|---|
| Stop[0] git auto-commit | 無 timeout | timeout: 60 | ~30s(git push 最長估計) | 30 × 1.2 = 36s → 統一最低 60s |
| Stop[2] stop-quality-hook.py | timeout: 10 | timeout: 60 | ~50s(5 repos × 2 × inner timeout 5s) | 50 × 1.2 = 60s |
| Stop[1] stop-notification-hook.py | timeout: 10 | 維持 10 | ~8.2s(inner PS timeout 8s) | 8.2 × 1.2 = 9.8s < 10,PASS |
影響範圍
| 影響類型 | 具體項目 |
|---|---|
| 修改文件 | CLAUDE.md v2.9→v3.0:快速索引 +1 行 + 🔧 開發模式新增 IMP-154 HARD STOP + 禁止行 +5 條 |
| 修改文件 | .claude/settings.local.json:Stop[0] timeout:60 新增 + Stop[2] 10→60 |
| 修改文件 | knowledge/improvements.md:IMP-154 ⏳→✅ + IMP-154 重複編號(tasks.md 參數確認)→ IMP-161 |
| 新增文件 | knowledge/decisions/RCF-063.md(本文件) |
| 更新文件 | knowledge/decisions/README.md +1 行 |
| 更新文件 | dev/tasks.md IMP-154 P2 [x] |
| 更新文件 | dev/CLAUDE.md 最近修改記錄 +1 行 |
| 觸發部門同步 | 無(主 CLAUDE.md 為 source of truth,部門通過指針繼承) |
附記
- 重複編號問題:improvements.md 存在 IMP-154 重複(L130 Hook timeout + L1792 tasks.md 技術參數)。本次已將 L1792 重命名為 IMP-161。同樣問題:IMP-155(L119 + L1808)、IMP-156(L108 + L1801)——建議在下次「整理知識庫」SKILL 時一併清理。
- v3.0 里程碑:v2.9 + 0.1 = v3.0,為 CLAUDE.md minor 版本號首次跨越整數。無特殊處理要求,記錄於此供歷史追蹤。