Problem
idd-diagnose Step 0.5 的 Clarity Surface gate 有兩個缺陷,都在同一段 code 裡,方向相反:一個 fail-open(該擋沒擋)、一個是潛在 fail-closed(可能誤擋)。兩者都在 PsychQuant/plaud-mcp-connector#44 的實際執行中被觀察到。
缺陷 1:Status enum 漂移不被偵測,gate 靜默放行(fail-open)
實例:plaud-mcp-connector#44 的 ### Clarity Surface 只有一列,Status 寫的是 open:
| Type | Source | Suggested canonical | Status |
|---|---|---|---|
| missing-context | 責任歸屬(connector wrapper vs 上游 …)尚未讀 code 確認 | diagnose 時讀 npx 快取內的 server 源碼定位 timeout 路徑 | open |
open 不在 /idd-clarify 的 Status enum {surfaced, deferred, resolved, dismissed, passed} 內。而 Step 0.5 的 gate 是機械計數:
SURFACED_COUNT=$(echo "$BLOCK" | grep -cE '\| surfaced \|')
DEFERRED_TOTAL=$(echo "$BLOCK" | grep -cE '\| deferred \|')
TOTAL_UNRESOLVED=$((SURFACED_COUNT + DEFERRED_LEGACY))
open 兩個都不匹配 → TOTAL_UNRESOLVED=0 → PROCEED。一列語意上明確未解決的 row 被算成零。
方向是不安全的那一邊:gate 的用途是擋下「帶著沒對齊的假設往下做」,而 enum 外的值一律被當成「已解決」。當時放行是對的判斷(該列的 Suggested canonical 正是「diagnose 時讀源碼」,擋下來會死鎖),但那是人的判斷,不是 gate 給的——gate 根本沒看見它。
Status 值由 LLM 依模板生成、寫入端無 normalization,所以漂移是預期而非例外(同 #295 對 ## Closing Summary heading 的認定)。
缺陷 2:BLOCK 抽取會吃過頭(潛在 fail-closed)
BLOCK=$(echo "$BODY_SCAN" | awk '/^### Clarity Surface/{flag=1; print; next} flag && /^### /{flag=0} flag')
終止條件是 /^### /(三個井號)。碰到 ## Current Status(兩個井號)不會停。
實測輸出(同一次執行):
### Clarity Surface
| Type | Source | Suggested canonical | Status |
|---|---|---|---|
| missing-context | … | … | open |
---
## Current Status ← 已經吃過頭
**Phase**: created
**Last updated**: … ← 一路吃到這裡,才被下一個 ### Key Decisions 攔住
該次無害(被吃進去的幾行沒有 | surfaced | 字樣),但只要 ## Current Status 內出現含該字樣的表格列——例如 ### Tasks 記錄了一項叫「surfaced」的工作——gate 就會誤判為未解決並擋住一個乾淨的 diagnose。
Type
bug
Expected
- enum 外的 Status 值要被看見:不在
{surfaced, deferred, resolved, dismissed, passed} 內的值,應計入 unresolved(保守)或至少 surface 一行 warning。「靜默當成已解決」是最不該有的行為。
- BLOCK 抽取的終止條件應涵蓋同級與更高級標題(
^##+ 而非 ^### ),或改用明確的區塊邊界。
Actual
- enum 外的值靜默放行。
- 抽取範圍越過
## 標題,直到遇上下一個 ### 。
Impact
skills/idd-diagnose/SKILL.md Step 0.5
- 同一段 gate 邏輯若被
idd-all / idd-all-chain 引用,影響一併擴散
- 使用者流程:任何帶
### Clarity Surface 的 issue 跑 /idd-diagnose
補充:這兩個缺陷是怎麼被發現的
不是 code review,是執行時看輸出。缺陷 2 之所以看得見,正因為 Step 0.5 的 debug 輸出把 BLOCK 印了出來——如果它只回傳計數,這個越界永遠不會被注意到。
Source: surfaced during /idd-diagnose execution on PsychQuant/plaud-mcp-connector#44(2026-08-17),當時記為 cross-repo、待確認才開案。
Problem
idd-diagnoseStep 0.5 的 Clarity Surface gate 有兩個缺陷,都在同一段 code 裡,方向相反:一個 fail-open(該擋沒擋)、一個是潛在 fail-closed(可能誤擋)。兩者都在PsychQuant/plaud-mcp-connector#44的實際執行中被觀察到。缺陷 1:Status enum 漂移不被偵測,gate 靜默放行(fail-open)
實例:
plaud-mcp-connector#44的### Clarity Surface只有一列,Status 寫的是open:open不在/idd-clarify的 Status enum{surfaced, deferred, resolved, dismissed, passed}內。而 Step 0.5 的 gate 是機械計數:open兩個都不匹配 →TOTAL_UNRESOLVED=0→ PROCEED。一列語意上明確未解決的 row 被算成零。方向是不安全的那一邊:gate 的用途是擋下「帶著沒對齊的假設往下做」,而 enum 外的值一律被當成「已解決」。當時放行是對的判斷(該列的 Suggested canonical 正是「diagnose 時讀源碼」,擋下來會死鎖),但那是人的判斷,不是 gate 給的——gate 根本沒看見它。
Status 值由 LLM 依模板生成、寫入端無 normalization,所以漂移是預期而非例外(同
#295對## Closing Summaryheading 的認定)。缺陷 2:BLOCK 抽取會吃過頭(潛在 fail-closed)
BLOCK=$(echo "$BODY_SCAN" | awk '/^### Clarity Surface/{flag=1; print; next} flag && /^### /{flag=0} flag')終止條件是
/^### /(三個井號)。碰到## Current Status(兩個井號)不會停。實測輸出(同一次執行):
該次無害(被吃進去的幾行沒有
| surfaced |字樣),但只要## Current Status內出現含該字樣的表格列——例如### Tasks記錄了一項叫「surfaced」的工作——gate 就會誤判為未解決並擋住一個乾淨的 diagnose。Type
bug
Expected
{surfaced, deferred, resolved, dismissed, passed}內的值,應計入 unresolved(保守)或至少 surface 一行 warning。「靜默當成已解決」是最不該有的行為。^##+而非^###),或改用明確的區塊邊界。Actual
##標題,直到遇上下一個###。Impact
skills/idd-diagnose/SKILL.mdStep 0.5idd-all/idd-all-chain引用,影響一併擴散### Clarity Surface的 issue 跑/idd-diagnose補充:這兩個缺陷是怎麼被發現的
不是 code review,是執行時看輸出。缺陷 2 之所以看得見,正因為 Step 0.5 的 debug 輸出把 BLOCK 印了出來——如果它只回傳計數,這個越界永遠不會被注意到。
Source: surfaced during
/idd-diagnoseexecution onPsychQuant/plaud-mcp-connector#44(2026-08-17),當時記為 cross-repo、待確認才開案。