問題
#202 (PR #213 )把 115 個 return "Error: …" 拒絕改成 throw,協定層 isError 終於正確。但 verify 的 logic lens 與 DA 各自確認:另有 37 處 拒絕寫成 JSON 字面回傳,例如
return " { \" error \" : \" not_found \" , \" num_id \" : \( id) } "
不帶 Error: 前綴,所以既不在 #202 的站點盤點內、也不被新的 sweep test 涵蓋。DA 逐一分類(37 = 5 + 32):
5 處讀側查詢落空 (getStyleInheritanceChain、getNumberingDefinition、listRepeatingSectionItems、content-control 查詢 ×2)——是結果不是拒絕,維持 success 正確。
32 處寫側拒絕 (updateContentControlText、linkStylesTool、deleteContentControlTool、assignNumberingToParagraph、setTableIndentTool、createNumberingDefinition、linkSectionHeaderToPreviousTool 等 28 個 handler)——return 排在 try await storeDocument(...) 之前 ,文件一個位元組沒改,client 卻拿到 isError 未設的 success。失敗情境:link_styles 指定不存在的 paragraph_style_id,樣式沒被連結,依 isError 分流的 client 判定成功繼續往下走——與 拒絕/錯誤以 return "Error: …" 字串回傳時 MCP isError 未設——協定層仍是成功(repo-wide 慣例) #202 本文控訴的形態一字不差。沒有任何一處是 batch 工具的逐項錯誤 (DA 逐一核對)。
站點(logic lens 列出的行號,head a39253d ):Server.swift:11007 Server.swift:13969 Server.swift:461 Server.swift:7558 Server.swift:9889
把 JSON payload 改成拋錯會讓這 28 個工具的 client 可見輸出從 JSON 變成 Error: … 文字——是需要獨立決定的 API-shape break。#202 只欠文件修正(CHANGELOG 的「每一個拒絕」全稱已收斂)。
要決定的事
32 處寫側的處置:(a) 改 throw ToolRefusal(輸出變文字,與其他 refusal 一致);(b) 保留 JSON 但讓 handleToolCall 能標 isError(需要 handler 回傳帶旗標的型別,不再是 String)。(a) 簡單一致但 API break;(b) 保形狀但要改 dispatch 契約。
決定後把 RefusalIsErrorSweepTests 的規則擴到這個形態,否則同病會再長回來。
與 拒絕訊息沒有穩定的機器可讀碼:114 個 refusal 只有 5 個帶 E_ 代碼,其餘是自由文字(sister concern from #202) #212 (structured error codes)合流:若走 (a),這 32 處正好是「訊息帶 E_ 代碼」的第一批候選。
Source : surfaced during /idd-verify #202 (Step 5b) — logic MEDIUM, DA ruling 2; report: #213 (comment)
問題
#202(PR #213)把 115 個
return "Error: …"拒絕改成 throw,協定層isError終於正確。但 verify 的 logic lens 與 DA 各自確認:另有 37 處拒絕寫成 JSON 字面回傳,例如不帶
Error:前綴,所以既不在 #202 的站點盤點內、也不被新的 sweep test 涵蓋。DA 逐一分類(37 = 5 + 32):getStyleInheritanceChain、getNumberingDefinition、listRepeatingSectionItems、content-control 查詢 ×2)——是結果不是拒絕,維持 success 正確。updateContentControlText、linkStylesTool、deleteContentControlTool、assignNumberingToParagraph、setTableIndentTool、createNumberingDefinition、linkSectionHeaderToPreviousTool等 28 個 handler)——return排在try await storeDocument(...)之前,文件一個位元組沒改,client 卻拿到isError未設的 success。失敗情境:link_styles指定不存在的paragraph_style_id,樣式沒被連結,依isError分流的 client 判定成功繼續往下走——與 拒絕/錯誤以return "Error: …"字串回傳時 MCPisError未設——協定層仍是成功(repo-wide 慣例) #202 本文控訴的形態一字不差。沒有任何一處是 batch 工具的逐項錯誤(DA 逐一核對)。站點(logic lens 列出的行號,head a39253d):Server.swift:11007 Server.swift:13969 Server.swift:461 Server.swift:7558 Server.swift:9889
為什麼不併進 #202
把 JSON payload 改成拋錯會讓這 28 個工具的 client 可見輸出從 JSON 變成
Error: …文字——是需要獨立決定的 API-shape break。#202 只欠文件修正(CHANGELOG 的「每一個拒絕」全稱已收斂)。要決定的事
ToolRefusal(輸出變文字,與其他 refusal 一致);(b) 保留 JSON 但讓handleToolCall能標isError(需要 handler 回傳帶旗標的型別,不再是String)。(a) 簡單一致但 API break;(b) 保形狀但要改 dispatch 契約。RefusalIsErrorSweepTests的規則擴到這個形態,否則同病會再長回來。E_代碼」的第一批候選。Source: surfaced during /idd-verify #202 (Step 5b) — logic MEDIUM, DA ruling 2; report: #213 (comment)