Problem
PackageInspector.imageRelationshipIds(inRels:) / referencedRelationshipIds(inPart:) 以正則直接抓屬性字面值(\bId\s*=\s*(["'])([^"']*)\1),不做 XML entity 解碼;而 DocxReader 走 NSXML,attribute(forName: "Id")?.stringValue 是解碼後的值。同一個 relationship Id="rId6":reader 端是 rId6、inspector 端是 rId6。
任何把兩邊放在一起比的 consumer 都會錯:che-word-mcp#199 的 list_images 用 inspector 的 orphanImageRelationshipIds 對 getImages() 的列判定孤兒,entity 寫法的孤兒會被標 referenced: yes(security lens 實測,Direct Mode)。save gate 的 baseline 比對(qualified part:id 集合差集)兩邊都來自 inspector,所以內部一致,但同一 rel 在 reader 與 inspector 的名字不同仍是坑。
Type
bug
Expected
inspector 回傳的 id(orphanImageRelationshipIds / orphanImageRelationshipRefs.id)與 referencedRelationshipIds 的比對值都經標準 XML entity 解碼(&#NN; / &#xHH; / 五個預定義 entity),與 NSXML 讀出的值一致。
Actual
原始字面值;6 不會變成 6。
Source: surfaced during /idd-verify che-word-mcp#199 (Step 5b follow-up triage). Verify report: PsychQuant/che-word-mcp#218 (comment)
Refs PsychQuant/che-word-mcp#199
Current Status
Phase: needs-fix
Last updated: 2026-09-06 by idd-verify (R3 → fix round 3 landed; R4 running) — unattended /idd-all, cluster PR #141
Key Decisions
Blocking
Problem
PackageInspector.imageRelationshipIds(inRels:)/referencedRelationshipIds(inPart:)以正則直接抓屬性字面值(\bId\s*=\s*(["'])([^"']*)\1),不做 XML entity 解碼;而DocxReader走 NSXML,attribute(forName: "Id")?.stringValue是解碼後的值。同一個 relationshipId="rId6":reader 端是rId6、inspector 端是rId6。任何把兩邊放在一起比的 consumer 都會錯:che-word-mcp#199 的
list_images用 inspector 的orphanImageRelationshipIds對getImages()的列判定孤兒,entity 寫法的孤兒會被標referenced: yes(security lens 實測,Direct Mode)。save gate 的 baseline 比對(qualifiedpart:id集合差集)兩邊都來自 inspector,所以內部一致,但同一 rel 在 reader 與 inspector 的名字不同仍是坑。Type
bug
Expected
inspector 回傳的 id(
orphanImageRelationshipIds/orphanImageRelationshipRefs.id)與referencedRelationshipIds的比對值都經標準 XML entity 解碼(&#NN;/&#xHH;/ 五個預定義 entity),與 NSXML 讀出的值一致。Actual
原始字面值;
6不會變成6。Source: surfaced during /idd-verify che-word-mcp#199 (Step 5b follow-up triage). Verify report: PsychQuant/che-word-mcp#218 (comment)
Refs PsychQuant/che-word-mcp#199
Current Status
Phase: needs-fix
Last updated: 2026-09-06 by idd-verify (R3 → fix round 3 landed; R4 running) — unattended /idd-all, cluster PR #141
Key Decisions
nsWellFormed;守門測試把<zz:x/>放在根元素之後、revert 整個修法照綠);R2 用lowercased()索引模擬檔案系統本身是新的靜音開關(碰撞時依封裝順序選、APFS 摺 U+017F、./收合)。3807b6a,在隔離 worktree 完成、ff-merge 進 cluster branch):inspector 改走 reader 自己的ZipHelper.unzip、part 以 OPC 位址組字串交檔案系統查(不模擬);解壓失敗/無word/document.xml→invalidDocx;delegate 自判未宣告前綴(真實 writer 唯一會產生的那一類);撤回「reader 拒的 inspector 也拒」全稱宣稱(DA D1 裁決:走封閉列舉——拒絕理由四類、不模擬的 namespace 類別點名、isConsistent是關係陳述),以 leniency 測試釘住;預檢驗完整 UTF-8、自閉合算深度;writer 以 rels 檔存在判斷、拒非 UTF-8/零長度/含註解/CDATA/前綴<Relationship>的 rels、訊息依成因分句(DocxWriter把rId1–rId4寫死給 styles/settings/fontTable/numbering——真實封裝若把rId1用在圖片就無法存檔(sister concern from #139) #140 亦然)。1512 tests / 0 failures。hasNewTypedRelationships與RelationshipsOverlay.parseRels是 #137 的同一反模式(sister concern from #137) #142;固定槽 →DocxWriter把rId1–rId4寫死給 styles/settings/fontTable/numbering——真實封裝若把rId1用在圖片就無法存檔(sister concern from #139) #140。Blocking
3807b6a進行中;PASS → merge PR cluster: PackageInspector parses XML with the reader's parser, and no serialization path traps (#137, #138, #139) #141、tag v3.7.0、idd-close ×3;FAIL → fix round 4。