You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/idd-edit --correct 的 compose-correction 會檢查「更正範圍以外的解析結果不變」,但它用的是 CommonMark parser:fence 與 HTML 註解留著沒關會被擋下,<details> 卻不會。GitHub 渲染時,一個沒關閉的 <details> 會把它後面的內容(包括 ## Current Status)收進摺疊區;同一手法也能把 Original text 引文藏進摺疊區,而逐字比對照樣通過。
compose-correction SHALL refuse with exit 6 when the composed body would parse differently outside the replaced region
:45 的第 (6) 條:
the replacement places a verbatim block inside a code block or an HTML block where the original did not
缺口在不變量的定義(parse 層),不在實作偏離 spec。
重現(throwaway probe:直接呼叫 main 上 helper 的 check-correction 與 compose-correction;正文為 ## Problem(含 Original text 引文)/## Expected/---/## Current Status。「渲染」欄是用 markdown-it-py 4.0.0 render 後交給 lxml(libxml2 HTML parser)建 DOM 的結果,作為瀏覽器的替代,沒有呼叫 GitHub 的 render API 驗證):
替換內容
目標段落
check
compose
## Current Status 在 <details> 裡
引文在 <details> 裡
new expected+<details><summary>…+內文,沒有 </details>
## Expected
0
0
是
否
同上,有 </details>
## Expected
0
0
否
否
一對 <details> 包住原樣的引文,後接新解讀
## Problem
0
0
否
是
新解讀後接沒關閉的 <details> 與原樣的引文
## Problem
0
0
是
是
四種都被接受。對照組(原文)兩欄都是「否」。
寫入後會一直留著:idd-update Branch A 只重寫 ## Current Status 以下,沒關閉的 <details> 在它上面那一節,所以之後每次同步 Current Status 仍是收合的。自動化不受影響(idd-all 以逐行比對讀 Current Status,skills/idd-all/SKILL.md:1240),受影響的是人類讀者。--scope whole-comment 之後沒有其他內容,只剩「把引文收合」這一種情形;comment 的 --section 則會收合之後的各節。
渲染結果用 lxml 當瀏覽器的替代,沒有呼叫 GitHub 的 render API 確認;未關閉元素包住後續內容是 HTML 解析的一般規則,兩邊應一致,實作時可在 Plan 階段用 GitHub 的 preview 手動確認一次。
Residue
GitHub 的渲染才是真正的判準,本機 parser 無法對所有 HTML 構造證明等價;issue 說的「隱藏的區塊」在這裡落實為 <details>(code block 與 HTML 註解已有檢查)。
Open questions(交給 /idd-plan)
Approach (can also be settled at the Plan approval gate): (a) local Details-depth invariant from the pinned markdown-it-py parser — tail depth unchanged + a verbatim block at depth>0 counts as hidden (recommended: offline, deterministic, matches the existing parser-based design) / (b) compare GitHub's rendered HTML (POST /markdown) before and after — ground truth, but adds a network call to prepare and to apply's re-check, must fail closed, needs fake-gh support and DOM analysis.
Note for the maintainer: a balancedDetails pair wrapping an unchanged 'Original text' quote also passes today, so 'require to be paired' alone does not meet the issue's second expectation.
Activity
spectra(idd-edit-in-place-correction): verify round 4 fixes — temp-di…
kiki830621 commentedon Oct 26, 2026
Diagnosis
Type
bug
Root Cause / Analysis
根因:兩道檢查都以 CommonMark 的 parse 結果定義「沒有改變」,而
<details>改的是渲染、不是 parse。compose-correction的不變量(plugins/issue-driven-dev/scripts/idd-edit-helper.py:1441-1468)只比對替換範圍之後每一行是否仍在 code/HTML block 裡(opaque)、是否仍是標題(headings),以及標記行是否仍是獨立的 HTML block。_Blocks(:785-834)只記錄fence/code_block/html_block的範圍、頂層標題與分隔線,沒有任何 HTML 元素巢狀的資訊。CommonMark 裡,以
<details>開頭的行開始一個 type 6 HTML block,遇到第一個空行就結束。所以沒關閉的<details>只讓它自己那一小塊變成 opaque,後面每一行 parse 結果完全不變,不變量照樣通過。瀏覽器(以及 GitHub 處理後的 HTML)則依 HTML 的解析規則,讓沒關閉的<details>元素包住其後到正文結尾的全部內容,而且預設是收合的。check-correction的第 (6) 條(:1333-1339)把「藏起來」定義為 verbatim block 有一行落在 code 或 HTML block 裡(_verbatim_runs,:1134-1141)。<details>後空一行再接Original text引文時,引文是頂層 blockquote,不算藏起來。這在<details>有正確關閉時也成立:用一對<details>…</details>包住原樣保留的引文,逐字比對與 hidden 檢查都通過,引文卻被收進摺疊區。所以 issue 提到的「<details>必須成對」只能涵蓋第一個預期(範圍外的可見性),涵蓋不到第二個(引文不被收合)。spec 與實作一致。
openspec/specs/in-place-correction/spec.md:103::45的第 (6) 條:缺口在不變量的定義(parse 層),不在實作偏離 spec。
重現(throwaway probe:直接呼叫 main 上 helper 的
check-correction與compose-correction;正文為## Problem(含Original text引文)/## Expected/---/## Current Status。「渲染」欄是用 markdown-it-py 4.0.0 render 後交給 lxml(libxml2 HTML parser)建 DOM 的結果,作為瀏覽器的替代,沒有呼叫 GitHub 的 render API 驗證):## Current Status在<details>裡<details>裡new expected+<details><summary>…+內文,沒有</details>## Expected</details>## Expected<details>包住原樣的引文,後接新解讀## Problem<details>與原樣的引文## Problem四種都被接受。對照組(原文)兩欄都是「否」。
寫入後會一直留著:
idd-updateBranch A 只重寫## Current Status以下,沒關閉的<details>在它上面那一節,所以之後每次同步 Current Status 仍是收合的。自動化不受影響(idd-all以逐行比對讀 Current Status,skills/idd-all/SKILL.md:1240),受影響的是人類讀者。--scope whole-comment之後沒有其他內容,只剩「把引文收合」這一種情形;comment 的--section則會收合之後的各節。Existing work
沒有處理本 issue 的 PR 或 branch(Step 1.6:clear)。相關的進行中工作:本機實作、尚未 push 的 #424(branch
idd/424-living-issue-write-back)讓--correct不再確認、偵測 skill 直接套用更正,並改了同一份in-place-correctionspec(不同的 requirement)。Impact
plugins/issue-driven-dev/scripts/idd-edit-helper.py(_Blocks、_compose的不變量、_verbatim_runs/check 第 (6) 條)、openspec/specs/in-place-correction/spec.md(:45第 (6) 條、:103不變量)、skills/idd-edit/SKILL.md:84(閘門表)、scripts/tests/in-place-correction/test.sh/idd-edit --correct --section(issue 正文與 comment);/idd-comment --type errata委派給--correct的路徑Strategy
scripts/tests/in-place-correction/test.sh,比照 H10、G1):(a)--section替換留下沒關閉的<details>、其後有---與## Current Status→ compose exit 6,prepare 記為REASON=unclosed-block;(b) 成對<details>只包新文字 → 接受;(c) 成對<details>包住原樣的Original text引文 → check exit 6;(d) 原文裡引文本來就在<details>裡、替換照樣保留 → 接受;(e) 替換拿掉一個用來關閉範圍外<details>的</details>→ 拒絕;(f) 大小寫與屬性(<DETAILS open>)、段落內的行內<details>_Blocks加上每一行的<details>深度:掃html_block與段落內html_inlinetoken 的內容,比對<details\b[^>]*>與</details\s*>(不分大小寫)<details>深度,替換前後要相同(併進:1457-1461的迴圈),沿用 exit 6/REASON=unclosed-block:45第 (6) 條與:103的不變量文字)與skills/idd-edit/SKILL.md:84的閘門表;CHANGELOG/markdown,仍需另做 DOM 分析。建議採本機 parser 的深度不變量,在 Plan 審核時定案Conflict Class
C_shared_module_coord
共享資源:
plugins/issue-driven-dev/scripts/idd-edit-helper.py(_Blocks、_compose、_verbatim_runs)與openspec/specs/in-place-correction/spec.md的 "Protected regions" requirement;#410 改同一個 requirement 與同一組 verbatim 函式,#407、#406 改同一支 helper,#424 改同一份 spec,要相鄰序列化。Complexity
Plan — Layer 2 不成立:這是收緊拒絕條件,遵守契約的呼叫端不受影響(Plan-Spectra line 表的 "Tighten input validation that callers already conform to"),spec 裡對應的一條在同一個改動中補上。Layer P 命中:decision-heavy(issue 自己列了兩種做法,選哪一種決定 prepare/apply 是否多一個網路依賴);risk-sensitive(這是保護原話引文與受管區的防竄改閘門)。
Hard-gate: not triggered — 同一概念涉及 helper、spec、
skills/idd-edit/SKILL.md、scripts/tests/in-place-correction/test.sh四個檔案(另有 CHANGELOG),未達 5;_Blocks只在scripts/idd-edit-helper.py內部使用,沒有其他檔案引用Risks
<details>、跨行的標籤、<details open>(預設展開、無害)、</details >、巢狀。<details>時,比較的是前後的深度差,不能因為原文的狀態就拒絕。<s>、<b>等)不屬於「可見性」,但會改變後面內容的呈現,列為 sister candidate,本 issue 不處理。--correct不再讓人確認完整預覽,這個缺口少了人工把關,優先度隨之提高;兩者改同一份 spec(不同 requirement),版本號(feat: 討論中持續更新 issue:問題變了改正文、診斷變了改 Diagnosis 留言、補充才新增 comment #424 與 PR feat: run /idd-all in Claude Code cloud sessions — REST egress and reads, (PR, attended) — 3.6.0 (#416) #426 都標 3.6.0)要依合併順序調整。Residue
GitHub 的渲染才是真正的判準,本機 parser 無法對所有 HTML 構造證明等價;issue 說的「隱藏的區塊」在這裡落實為
<details>(code block 與 HTML 註解已有檢查)。Open questions(交給
/idd-plan)Details
-depth invariant from the pinned markdown-it-py parser — tail depth unchanged + a verbatim block at depth>0 counts as hidden (recommended: offline, deterministic, matches the existing parser-based design) / (b) compare GitHub's rendered HTML (POST /markdown) before and after — ground truth, but adds a network call to prepare and to apply's re-check, must fail closed, needs fake-gh support and DOM analysis.Details
pair wrapping an unchanged 'Original text' quote also passes today, so 'requireSister Concerns Filed (mid-diagnose, v2.47.0+ #528)
、 等)可能改變後面內容的呈現Source: surfaced during /idd-diagnose #409 sister concern surfacing (Step 3.6)
Vagueness Pre-check
Original text引文不被收進摺疊或隱藏的區塊),也列出兩種可能做法。<details>之外還包括哪些機制,沒有封閉列出。Generated by Claude Code