Skip to content

feat: write discussion changes back to the issue (#424) - #469

Merged
kiki830621 merged 13 commits into
mainfrom
idd/424-living-issue-write-back
Nov 10, 2026
Merged

kiki830621 merged 13 commits into
mainfrom
idd/424-living-issue-write-back

Conversation

@kiki830621

@kiki830621 kiki830621 commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Refs #424

Summary

討論 open issue 時,使用者定案的改變寫回它該在的地方,不再靠人記得:問題改正文段落、診斷改 Diagnosis 段落(/idd-edit --correct)、新資訊與決定新增 comment;改了診斷的決定兩處都寫。在有寫入權的 repo,由 AI 判斷類別、不先問、每次回報,而且只改執行者自己寫的內容。

第一版另外有兩塊:別人的 comment 自動觸發、偵測 skill 自動更正。verify 四輪沒有收斂,第 4 輪之後拿掉(#424 comment 6616229678)。第 5 輪之後再拿掉 verify 報告的註記、--body-file 的私人路徑閘與 /idd-edit 的 unattended 分支(comment 6617788666)。

Verification

While an issue is discussed, each change goes back to the place that owns
it: the problem to the issue body section, the diagnosis to the Diagnosis
section (/idd-edit --correct), new information or a decision to a new
/idd-comment. The AI decides the kind, writes without asking, reports each
write-back, and rewrites only the invoking user's own content.

- rules/issue-write-back.md (new) and a fifth SessionStart line
- /idd-edit --correct no longer asks for confirmation; --prepend-note skips
  it only on your own comment (strict author check)
- idd-verify / idd-diagnose / idd-reorganize apply corrections and report
  ### Applied Corrections; idd-diagnose Stage 1 rewrites its own Diagnosis
- append-vs-modify: in-place-correction without confirmation, write-back map
- Spectra change issue-write-back; plugin 3.6.0

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus

Aggregate

FAIL — 1 CRITICAL、17 HIGH、38 MEDIUM、17 LOW、7 INFO(合併後 80 則,含同一問題的多則;下面以主題歸併)

審的是 844e8ea,與目前 PR head 相同(freshness gate 通過)。CI suites 通過。全套 67 個 suite:65 個在全套裡通過;edit-run、idd-ci-gate 在高負載下失敗,單獨重跑通過(203、83 項)。

Scope coverage

PR refs: #424
Verified scope: #424

主題

  1. 來源沒有信任邊界(CRITICAL,idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1、idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4、idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6、[refactor] idd-list PR body parsing: ignore #N inside fenced code blocks (sister concern from #13) #14)。 作者閘只查寫入的目標,不查改變的來源。外人的 comment 可經由規則進入維護者署名的 Diagnosis,繞過 bug: type=meeting 的 issue 被 idd-all / idd-plan 的 actionability gate 判成 complexity-unparseable 擋下 #383 的作者過濾;### Type、### Complexity 也能被改。
  2. 別人的 comment 這條觸發沒有接上(idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3、idd-all Phase 0.2: GITHUB_REPO post-derive shape assertion #8)。 只有規則文字與 grep 斷言,idd-plan、idd-update 都沒有這一步。接上之前必須先有第 1 點的邊界(feature: spectra-apply auto-post Implementation Complete to GitHub issue (resolve /idd-close supersession friction) #56)。
  3. 偵測 skill 的自動套用(idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9、[enhancement] idd-list cluster_leader config (lowest | primary) (sister concern from #13) #15)。 findings 讀過不可信內容就直接改寫,只有一個 reviewer 也算;verify 能改寫自己驗收用的 ## Expected,下一輪就 PASS。
  4. 隱私與目標 repo(idd-all Examples: 跨 repo invocation 段重複描述,合併 #10、[SOP] umbrella split flow should mandate commit log scan before filing sub-issues #11、Complexity routing: vagueness 應該是一階信號,但目前 4 層 gate 都沒衡量需求清晰度 #12)。 自己的 public repo 是 warn,命中只提醒照寫;「貼來的原話照問 reply 型第三方 verbatim payload 應強制 heightened scrub tier(不論 repo visibility)—— #269 DA-3 follow-up #272」與 helper 不符;不先問的路徑沒有限制在有寫入權的 repo。
  5. 什麼算改變、讀者看得到什麼([refactor] idd-list Step 5: needs-fix × PR state matrix 應展開,不該摺疊成單行 (verify follow-up from #13) #16、[enhancement] idd-list Step 5: planning + has PR 應勸 user 處理 stale/zombie PR (verify follow-up from #13) #17)。 沒有定案門檻,拿不準時反而覆寫;改寫後畫面上看不出改過或為什麼改。
  6. 連帶更新(idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2、[test] idd-list cluster algorithm + footer rule + state matrix 沒被任何 production data 跑過 (verify follow-up from #13) #18)。 PASS 不失效、繞過 idd-reorganize、Spectra tier 沒有 Plan;「每份 verify 報告」可能改到協作者的 comment。
  7. 主 spec 自相矛盾(idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5、idd-list 應該顯示引用 issue 的 open PR 資訊 #13)。 封存後 append-vs-modify-discipline、in-place-correction 仍規定要確認。
  8. unattended 沒有處理(idd-all Phase 5: PR body heredoc 改 quoted (預防未來 RCE) #7、[Bundle test] Step 1: build schema #23、docs: idd-issue Step 4.8 Split Umbrella SOP — pre-flight scan before sub-issue file #38、feat(idd-list): markdown-aware fence strip + cluster_leader config (cluster #14 #15) #43)。 idd-edit 第一次會在 unattended 下跑,但沒有分支,還是會走到提問。

Devil's Advocate 的兩項修正:第 8 點的後果是卡住,不是寫錯(#71);現存風險主要走第 3 點的路徑,第 1、2 點要在同一個 commit 修(#56)。

Findings

# Severity Finding Source Action
1 CRITICAL 任何人的 comment 都能改寫受信任的 Diagnosis,繞過 #383 的作者過濾 — 作者閘只檢查寫入的目標,從不檢查改變的來源。 規則第 41 行:「任何人在 issue 上留的 comment,在下一次讀到時處理」。spec issue-write-back 的 scenario「Collaborator comment observed by the next skill run」寫的是 THEN「the AI SHALL classify the comment as a diagnosis change and write it back to the Diagnosis comment」。規則沒有資料/指令邊界,不要求獨立查證,也不看留言者的 author_association(對 rules/issue-write-back.md grep untrusted、資料、association 都沒有命中)。測試也沒有鎖這件事。 這正好打穿既有的信任模型: - skills/idd-pl… rules/issue-write-back.md:41` security Blocking
2 HIGH 診斷相依紀錄的更新流程仍可能改寫協作者的 verify comment — Codex 標為 [P1/高]。Codex 依 diff 判斷,未實際執行測試。 位置:plugins/issue-driven-dev/rules/issue-write-back.md:69–73,尤其第 72 行:「每份既有報告用 /idd-edit comment:<id> --prepend-note ... 在開頭加一行。」 問題:這裡要求處理「每份」verify 報告,對非本人內容只規定恢復確認,並未改走 errata。配合 skills/idd-edit/SKILL.md Step 3 第 5 點,嚴格作者檢查失敗後仍可經使用者確認套用 --prepend-note。當… rules/issue-write-back.md:72 codex Blocking
3 HIGH R1 / Clarity 1 / D5:「別人的 comment 下一次讀到時觸發」沒有接到任何 skill,spec 的 /idd-plan scenario 不會發生 — 規則第 41 行寫「IDD skill 讀 comments 的時候(diagnose、plan、verify、update 都會讀)」,spec scenario「Collaborator comment observed by the next skill run」也點名 /idd-plan #N:讀到後 AI SHALL classify 並寫回。實際情況: - grep -rl issue-write-back 在 skills 底下只命中 idd-edit、idd-diagnose、idd-verify、idd-reorganize。idd-plan、idd-update、i… rules/issue-write-back.md:41 requirements Blocking
4 HIGH 任何人的 comment 都能不經確認進入受信任的 Diagnosis,繞過既有的信任邊界 — 「任何人的 comment 都會觸發」是已定案的決定,這裡不質疑觸發本身。缺的是這條路徑上的防護:規則第 43 行只說「寫回的是它對問題或診斷造成的改變」,沒有要求把 comment 當資料看,也沒有依 author_association 分流。spec scenario 甚至寫 AI SHALL「classify the comment as a diagnosis change and write it back」,並未要求先查證。 既有 skill 刻意不信任陌生人:skills/idd-plan/SKILL.md 第 77 行寫「只信任 OWNER / MEMBER / CO… rules/issue-write-back.md:43 requirements Blocking
5 HIGH 主 spec 保留與 D1、D4 矛盾的 SHALL,/spectra-archive 之後會自相矛盾 — Decision comment 6388243217 的 Rationale 寫明這兩條規範要改成 MODIFIED requirement。但 delta 只動了 in-place-correction 的兩條 requirement,以及新增 issue-write-back。合併後要跑 /spectra-archive,以下內容會留在主 spec: - openspec/specs/append-vs-modify-discipline/spec.md 第 266-268 行,requirement 名稱是「SHALL replace confirmed errors」,內… openspec/specs/append-vs-modify-discipline/spec.md:268 requirements Blocking
6 HIGH Trigger 2 lets any commenter's words be written into your own Diagnosis, with no trust check on the source — The 'only your own content' safeguard (rule L47) checks who wrote the TARGET, never who is the SOURCE of the change. Rule L41 makes a comment by 任何人 a trigger, kind 2 includes 分流 (L16), and L63 says write without asking. Spec scenario 'Collaborator comment observed' says the AI SHALL classify the co… rules/issue-write-back.md:41 logic Blocking
7 HIGH idd-edit now runs unattended for the first time but has no unattended handling; its questions remain and the directive cannot reach it — Before #424 the detection skills said 'unattended 只列不做', so idd-edit never ran under /idd-all unattended. Now idd-verify L1220, idd-diagnose L770, idd-reorganize and the spec ('SHALL hold in attended and unattended mode alike ... SHALL NOT ask') send it there. idd-edit contains no 'unattended' or … skills/idd-edit/SKILL.md:183 logic Blocking
8 HIGH Trigger 2 has no implementation: no skill that reads comments is told to write back — Spec scenario 'Collaborator comment observed by the next skill run' requires that when /idd-plan #N reads the comments, the AI SHALL classify the comment and write it back. Design D5 and rule L41 name diagnose, plan, verify and update as the trigger points. grep -rln issue-write-back over skills… openspec/changes/issue-write-back/specs/issue-write-back/spec.md logic Blocking
9 HIGH D4 把讀過不可信內容的 findings 當成證明,直接改寫已發表內容 — Step 3.5 的觸發條件是「合併後的 findings 證明本 issue body 或某則 comment 已發表的敘述是錯的」,之後「直接套用、不先問,attended 與 unattended 相同」。DATA_GUARD(SKILL:214)只保護 reviewer 讀 PR 內容的那一刻;主 agent 拿到 findings 後沒有任何污染標記,也不必自己重新查證,就由它組出替換內容並寫入。步驟 merge_findings 是合併去重、severity 取最高,所以一個 reviewer 的單一 finding(誤判,或被 PR 文字帶偏)就夠觸發。 舊文字的防線被一… skills/idd-verify/SKILL.md:1216 security Blocking
10 HIGH 隱私閘在自己的 public repo 擋不下任何東西,「enforce 命中就 discard」只保護第三方 repo — _scrub_tier(idd-edit-helper.py:2058)的等級是:第三方與探測失敗 → enforce、自己的 public → warn、private → light。換句話說,你能寫入的 repo 永遠不是 enforce。而 D1 的安全敘述全部以 enforce 為準: - 規則第 65 行:「warn 命中 → 一行提醒後照寫」。 - idd-edit/SKILL.md:182:只有 enforce 才 discard。 - spec in-place-correction:only 在 enforce 或 #272 拒絕時 discard;… rules/issue-write-back.md:65 security Blocking
11 HIGH 「貼來的第三方原話照問 #272」與 helper 不符,light 的承諾也沒有對應分支 — 規則第 66 行:「要寫入的文字含使用者貼來的第三方原話時,/idd-edit 的 #272 那一題照問,這不在『不先問』的範圍內」。 實作不是這樣。_reply_272(idd-edit-helper.py:1615)只比對 reply template 的兩個標記 type=reply 與 points-from=user-pasted。討論寫回的 Diagnosis、Expected、note 都不帶這兩個標記。我實測:一段貼來的信件轉述寫進 ### Root Cause / Analysis,_reply_272=False,_floor('light')… rules/issue-write-back.md:66` security Blocking
12 HIGH 不先問的寫回沒有限定目標 repo,別人的 repo 也會被貼 comment 與 errata — hooks.json 的 SessionStart 沒有 matcher,第 16 行「討論 issue 時就地寫回、不先問…新資訊與決定新增 comment…別人的用 errata/correction」會注入每個 session,不限 repo。規則的 Scope 只寫「任何使用 IDD 的 repo,只要在討論一張 issue」,全文沒有檢查目標 repo 權限。這一行是沒有 skill 在跑時唯一確定會讀到的文字,而它也沒提隱私自審。 design.md:49 的依據是「別人的內容自動貼 errata 或 correction comment(屬全域規則『GitHub 紀錄不用… hooks/session-start-commit-rule.sh:16 security Blocking
13 HIGH After /spectra-archive the normative specs still require confirmation, contradicting the new requirement — The delta only REMOVEs and ADDs two requirements. I ran spectra archive issue-write-back in a throwaway clone (added 10, removed 2) and the resulting main spec still says the old behaviour next to the new 'SHALL NOT ask for confirmation'. Line numbers below are the current tree: - in-place-correct… openspec/specs/in-place-correction/spec.md:253 regression Blocking
14 HIGH An outsider's comment can now rewrite the trusted Diagnosis, undoing the #383 trust boundary — Trigger 2 is '任何人在 issue 上留的 comment', the diagnosis kind includes '分流' (routing), and the AI writes without asking. The rule has no author_association filter and no statement that comment text is data, not instructions. The author gate in /idd-edit checks who wrote the target, not who prompted the … rules/issue-write-back.md:41 regression Blocking
15 HIGH verify 可以改寫自己驗收用的判準(regression 標 MEDIUM 的那條應升級) — regression 的「下一輪對著被改過的文字驗」只寫到現象,少算了後果。Step 3.5 的觸發只排除一種情況:「code 寫壞不算」。issue 正文的 ## Expected、Diagnosis ### Strategy 的 - [ ](idd-implement L34 稱之為「契約」)、使用者在 plan mode 核准過的 Plan,全都在可改寫的範圍內,spec 又規定 unattended 照做。 路徑:idd-all unattended 第 1 輪 findings 指出 code 與 Expected 不符 → AI 判定是 Expected 寫錯(這個判斷… skills/idd-verify/SKILL.md:1218 devils-advocate Blocking
16 HIGH 沒有「討論已定案」的門檻,拿不準時的預設是覆寫,而規則引用的 Foresay 分支不涵蓋這種情況 — 規則定義了改變屬於哪一類,卻沒有定義什麼算「已經改變」。再加上「寫回發生在討論當下,不等討論結束」,以及 L23「拿不準屬於哪一類,就照兩類都寫;不要因此把它降級成一則 comment」,不確定時走的是破壞性最大的方向。issue 的 Expected 原文是「兩處都寫,或先問」,規則拿掉了「或先問」。 L63 把這些寫入歸到 Foresay 的 traceable 分支,但 core/protocol.yaml 的定義是 clarity AND reversible,不清楚的情況走 disambiguation。「拿不準」正好在這個分支之外。CLAUDE.md 也寫明 IDD 遵守 … rules/issue-write-back.md:23 devils-advocate Blocking
17 HIGH 讀者看不出內容被改過、為什麼改、是誰決定的 — 其他 reviewer 查了寫入是否安全,沒有查寫入後讀者看到什麼。我用 helper 的 compose-correction 對 #424 真實的 Diagnosis 跑 ### Strategy,畫面上只剩新文字。標記是 HTML comment,只帶 backup id 與日期,算繪後看不見。spec(in-place-correction L101)規定標記只帶這些,Step 3.5 也明寫 --correct 不帶 --reason。 其他管道也補不上: - GraphQL userContentEdits 的 editor 是使用者本人的 login,AI 自… rules/issue-write-back.md:64 devils-advocate Blocking
18 HIGH R3 只改到文字,狀態不動;Spectra tier 上 Plan 那一步是空操作 — Diagnosis 被改之後,規則只做三件事:改 Plan、在 verify 報告前加一行、跑 /idd-update。 1. PASS 不失效。 phase 由 ## Verify (PASS) 標題推斷(idd-update、idd-list),註記不影響它;idd-N-verified tag 留在原處,idd-close 也不看註記。root cause 被推翻後,issue 仍顯示 verified,可以照常結案。idd-edit 的 Next Step 自己寫了「修 diagnosis comment,可能要重跑 /idd-verify」,規則沒有這一步。 … rules/issue-write-back.md:68 devils-advocate Blocking
19 MEDIUM 自動更正的 errata 分支沒有傳入更正檔案,可能重新卡在互動詢問 — Codex 標為 [P2/中]。Codex 依 diff 判斷,未實際執行測試;Codex 只給出 Step 編號,沒有給行號。 位置: - plugins/issue-driven-dev/skills/idd-verify/SKILL.md,Step 3.5 第 3 點 - plugins/is… skills/idd-verify/SKILL.md codex In-scope fix
20 MEDIUM R3 / Clarity 4 的連帶更新在最常見的路徑上沒有提醒:session 討論直接跑 /idd-edit — spec「A corrected diagnosis SHALL update the records that depend on it」只在 idd-diagnose Stage 1 與 Step 3.8、idd-verify Step 3.5、idd-reorganize Step 3.5 有… skills/idd-edit/SKILL.md:184 requirements In-scope fix
21 MEDIUM PR mode 的 verify 報告不在規則的覆蓋範圍:註記會落在 pointer,不是帶 findings 的 master — 規則第 73 行寫「每份既有報告」,spec 寫「each existing verify report of the issue」。但 PR mode(idd-all 的預設路徑)下,master 報告貼在 PR 上,issue 上只有 pointer:skills/idd-verify/SKI… rules/issue-write-back.md:73` requirements In-scope fix
22 MEDIUM D2 要在每份 verify 報告最上方 prepend,而 idd-comment 的同段文字說這會讓其他 skill 認不出 comment — skills/idd-comment/SKILL.md 第 383 行寫:原 comment 第一個非空行是 ATX 標題(## Diagnosis 等)時不做 prepend,因為「提示會把它擠到下面,其他 skill 就認不出這則 comment」。verify 報告全部以 ## Ve… skills/idd-comment/SKILL.md:383` requirements In-scope fix
23 MEDIUM D4「unattended 也直接套用」遇到 /idd-edit 的 AskUserQuestion 時沒有定義行為 — spec 要求「This SHALL hold in attended and unattended mode alike」,idd-verify、idd-diagnose、idd-reorganize 也都寫 unattended 直接呼叫 /idd-edit。但 skills/idd-ed… skills/idd-edit/SKILL.md:183` requirements In-scope fix
24 MEDIUM D1b 的 scenario 與實際行為不符;bot 或 OWNER 的報告可在確認後被改,違反「別人的內容不改」 — spec scenario「Note on a collaborator's comment」寫:strict check 失敗,「the skill SHALL ask for confirmation with NO as the default」。實測 helper 的作者閘(用它的 test… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:68 requirements In-scope fix
25 MEDIUM 隱私自審捨棄時,finish 報告寫「使用者在預覽時拒絕」,這句話會流進公開的 Applied Corrections — D1 之後,--correct 的 discard 主要來自隱私自審或 #272,但 discard_subcmd 只記 declined,finish 第 2688 行固定印「DECLINED {target}(使用者在預覽時拒絕,未寫入)」。隱私自審命中時沒有人被問過,unatt… scripts/idd-edit-helper.py:2688 requirements In-scope fix
26 MEDIUM 還有多處寫著確認,與任務 3.1 與 CHANGELOG「idd-comment --type errata wording follows」不符 — 這些都是 HEAD 上實際的文字,與 D1、D4 不符: - skills/idd-comment/SKILL.md 第 648 行:「委派 /idd-edit ... --correct ...,經它的預覽與確認後就地取代」。 - skills/idd-comment/SKILL.md… skills/idd-comment/SKILL.md:648 requirements In-scope fix
27 MEDIUM finish reports '使用者在預覽時拒絕' when no user was asked — discard records declined with no reason, and finish prints the only wording it has. I ran prepare, discard, finish on a --correct target with … scripts/idd-edit-helper.py:2688 logic In-scope fix
28 MEDIUM A --correct on ### Residue makes idd-close raise a false residue gate — --correct puts its marker inside the replaced section. idd-close Step 3.6 extracts the section with awk and tests [ "$RESIDUE_CONTENT" = "(none)" ]… skills/idd-close/SKILL.md:706` logic In-scope fix
29 MEDIUM Write-back has no path for a refused --correct; Stage 1 is left stuck; Applied Corrections has no outcome for exit 7 or 9 — The rule routes only by author. When own content is refused it says nothing, and the one-line report (L64) has no refusal field. Reachable refusals I … rules/issue-write-back.md:64 logic In-scope fix
30 MEDIUM The rule's own command does not run outside a skill, and its failure reads as 'not your content' — D3 exists because discussions happen with no skill running. But ${CLAUDE_PLUGIN_ROOT} is substituted only when a skill loads, and the Bash tool has … rules/issue-write-back.md:50 logic In-scope fix
31 MEDIUM Applied Corrections can rewrite an earlier verify report's findings, which D2 forbids — Step 3.5 triggers on '某則 comment 已發表的敘述是錯的' and sends own content to --correct. The same wide trigger is in idd-diagnose Step 3.8 ('既有 comment') and… skills/idd-verify/SKILL.md:1218 logic In-scope fix
32 MEDIUM Step 3.8 writes corrections before Stage 1 asks whether the diagnosis is right, and Stage 1 has no way to undo them — Order: Step 3.8 applies corrections to the issue body and other comments, and posts errata to collaborators' comments. Step 4 Stage 1 (L806) then asks… skills/idd-diagnose/SKILL.md:766 logic In-scope fix
33 MEDIUM idd-reorganize's auto-apply contradicts its own iron rule and its adjudication table — Step 3.5 corrects 'Step 1 那個錯的 artifact 與 Step 3 判為 redo / invalidate 的項目' without asking. But: - L141 says a judgment overturned by later information… skills/idd-reorganize/SKILL.md:141 logic In-scope fix
34 MEDIUM The mandated prepend on verify reports contradicts idd-comment's guard, and pushes the heading off line 1 — idd-comment L383 and its errata_pointer task forbid --prepend-note when the comment's first non-empty line is an ATX heading or IDD marker: '提示會把它擠到… rules/issue-write-back.md:73 logic In-scope fix
35 MEDIUM '不先問' also covers other people's repos, which the design's justification does not — Scope is 'any repo using IDD', and the helper resolves READ permission to the enforce tier, so third-party targets are an expected case. In such a r… rules/issue-write-back.md:3 logic In-scope fix
36 MEDIUM The new behaviour is tested only by grep; D1b and the no-question paths are never executed — Every assertion in issue-write-back/test.sh is a grep over prose, and the changed in-place-correction ones are too. assert_output_grep "$s applie… scripts/tests/issue-write-back/test.sh` logic In-scope fix
37 MEDIUM Applied Corrections 表會把 gate 擋下的內容再發佈一次 — 第 1241 行規定「錯在哪」要寫「位置與錯誤類型加正確內容」,第 1244 行規定被拒時 Outcome 寫 idd-edit 給的原因。沒有任何一句說被擋下時要省略「正確內容」。所以 /idd-edit 因 egress 拒絕或隱私 discard 而沒有寫入,同一段文字仍會出現在報告那一列… skills/idd-verify/SKILL.md:1241 security In-scope fix
38 MEDIUM idd-edit 現在會在 unattended 下執行,但沒有 unattended 分支,#272 的拒絕規則落空 — privacy-scrubbing.md § #272 第 2 點:「Unattended contexts SHALL NOT post such a reply: refuse with an explanatory notice and defer to an attended session… skills/idd-edit/SKILL.md:183 security In-scope fix
39 MEDIUM 引數建構的限制只寫在偵測 skill,討論寫回路徑仍可把 GitHub 文字貼進指令 — spec 的「SHALL NOT paste text read from GitHub into the command」只在 Skills that detect errors 這個 requirement 裡。討論寫回才是最常見、來源又最不可信的路徑(D5),但: - 規則第 15、16 … rules/issue-write-back.md:15 security In-scope fix
40 MEDIUM --body-file 路徑閘放行憑證與私人檔案,之前靠人工確認兜底 — _REFUSED_CREDENTIAL_DIRS 只有 .ssh .aws .gnupg .kube .docker 五個目錄。我實測 validate_body_file_path 的結果:~/.netrc、~/.zsh_history、~/.claude.json、~/… scripts/idd-edit-helper.py:215` security In-scope fix
41 MEDIUM 更正檔沒有帶 repo、不會清除,舊內容可能無人攔阻地送進別的 repo — 替換內容寫到 $HOME/.cache/idd/corrections/correction-<N>-<k>.md。三個問題: - 路徑不含 repo:兩個 repo 的 #42 用同一個檔名。 - k 每次從 1 開始:同一張 issue 的下一輪 verify 又是同一個檔名。 - 沒有任何… skills/idd-verify/SKILL.md:1228 security In-scope fix
42 MEDIUM D1 的前提「舊版一律歸檔、可還原」只在特定 clone 成立 — design.md:33:「舊版一律歸檔、可還原,所以拿掉確認不會讓錯誤變成不可逆」。規則第 63 行與 design 的 Migration Plan 也這樣寫。這是拿掉確認的主要理由,但 idd-edit/SKILL.md 自己列出了不成立的情況: - 「歸檔只存在執行 --corre… openspec/changes/issue-write-back/design.md:33` security In-scope fix
43 MEDIUM 'Attended and unattended alike' sends unattended runs into idd-edit questions it has no unattended branch for — Before this change, unattended runs never called /idd-edit ('unattended 只列不做'). Now they do, through Skill(skill="issue-driven-dev:idd-edit", args="<… skills/idd-verify/SKILL.md:1228` regression In-scope fix
44 MEDIUM A privacy or #272 discard is reported as 'the user declined at the preview', which is now false — discard_subcmd records outcome 'declined' with no reason, and finish prints – DECLINED {target}(使用者在預覽時拒絕,未寫入). --correct no longer asks, so for a… scripts/idd-edit-helper.py:2688 regression In-scope fix
45 MEDIUM ### Applied Corrections records real writes outside the diff, but the external-writes collector does not scan it — EW_SECTIONS still lists only the six filing sections. ### Proposed Corrections wrote nothing, so leaving it out was correct. ### Applied Correcti… skills/idd-verify/SKILL.md:262` regression In-scope fix
46 MEDIUM The rule's main scenario is a session with no skill running, where its author check cannot work and the rule is not loaded — The Scope says '不論當下有沒有 IDD skill 在跑'. The bash block uses ${CLAUDE_PLUGIN_ROOT}, which Claude Code substitutes only in skill content; the Bash tool… rules/issue-write-back.md:50 regression In-scope fix
47 MEDIUM Automatic errata and correction comments rely on a global rule whose exclusions were not carried over — D4 justifies posting without asking as '屬全域規則「GitHub 紀錄不用問」的第 1 類'. That category is limited to repos with write access, and the global rule returns t… openspec/changes/issue-write-back/design.md:49 regression In-scope fix
48 MEDIUM A verify round can now rewrite the text the next round verifies against, with no one looking — Step 3.5 applies to any published statement in 'issue body 或某則 comment', with no exclusion for ## Expected or the requirements list in the Diagnosis… skills/idd-verify/SKILL.md:1218 regression In-scope fix
49 MEDIUM Callers and catalogs of /idd-edit still describe the old confirmation — All of these remain in the tree at 844e8ea and contradict the applied behaviour: - idd-comment:648 example: '經它的預覽與確認後就地取代'. - idd-comment:551: '已更正 /… skills/idd-comment/SKILL.md:648 regression In-scope fix
50 MEDIUM 問題類改變完全沒有連帶更新 — 連帶更新只寫了「診斷更正後」。第一類(## Expected、範圍)改了,什麼都不會跟著動。spec 的 Scenario「Scope widened in a session」還規定只改 ## Expected、SHALL NOT 貼 comment。 結果是範圍擴大之後,Diagnosi… openspec/changes/issue-write-back/specs/issue-write-back/spec.md devils-advocate In-scope fix
51 MEDIUM #351 的讀取防護前提被 D1 反轉 — hooks/archive-read-guard.py L6-7 的理由是:歸檔裡是「content the user confirmed to be wrong」,AI 讀了會繼承錯誤。D1 之後沒有人確認,歸檔裡可能是對的版本,GitHub 上可能才是錯的。防護這時保護的是 AI 自己寫錯的… hooks/archive-read-guard.py:6 devils-advocate In-scope fix
52 MEDIUM 修正 security 的「歸檔只在特定 clone」:不是不可回復,而是規則指了最差的那條路 — security 說 D1 的前提只在特定 clone 成立,對 restore 而言正確,但當成「回不去」就講過頭了。GitHub 的編輯歷史保留每個舊版本,任何讀得到 issue 的人都能看(UI 的 edited 選單,或上一條的 GraphQL),不限 clone。 真正的問題是規則 L… rules/issue-write-back.md:64 devils-advocate In-scope fix
53 MEDIUM verify 只凍結程式碼、沒有凍結需求,design.md 的緩解說法不成立 — design.md L87 對「verify 在飛時被改到 Diagnosis」的回答是:「verify 讀的 context 以啟動時為準,報告結束後才可能被加註記」。這句話有兩處不對: - Step 3.5 明訂在 Step 4 貼報告之前改寫,同一輪就改了。 - 另一個 session… openspec/changes/issue-write-back/design.md:87 devils-advocate In-scope fix
54 MEDIUM 偵測 skill 自動貼 errata 超出使用者定案的範圍 — 使用者對五條假設回「都OK」(comment 6388243217),第 3 條原文是「自己的內容直接套用並回報,attended 與 unattended 相同」。design.md D4 多加了一句「別人的內容自動貼 errata 或 correction comment」,spec 又… openspec/changes/issue-write-back/design.md:47 devils-advocate In-scope fix
55 MEDIUM 交付行為與 Stage 1 定案的 Diagnosis 不符:warn 不再擋 — 這條補強 security 的「隱私閘擋不下」。#424 的 Diagnosis Risks 寫的是「每次寫回都要過 privacy gate,warn 以上等級照常擋」,使用者是對著這句話確認的。規則 L65 卻是「warn 命中 → 一行提醒後照寫」。 舊流程裡 warn 之後還有 As… rules/issue-write-back.md:65 devils-advocate In-scope fix
56 MEDIUM 修正:Trigger 2 的 CRITICAL 與「Trigger 2 沒有實作」互相依賴,修復順序不能照現在的排序 — security 的 CRITICAL(任何人的 comment 改寫 Diagnosis)與 logic、requirements 的 HIGH(Trigger 2 沒有接到任何 skill)不可能同時完整成立。我查過,rules/issue-write-back.md 只被 idd-veri… rules/issue-write-back.md:41 devils-advocate In-scope fix
57 LOW 文件總覽沒有跟上:rule 數量、SessionStart 說明、rules-layering 對照表 README.md:11 requirements In-scope fix
58 LOW tasks.md 4.1 仍寫 3.6.0,與「已改到 3.7.0」的說明不符 openspec/changes/issue-write-back/tasks.md:22 requirements In-scope fix
59 LOW idd-edit Step 3 的順序:第 3 點依賴第 5 點才跑的檢查 skills/idd-edit/SKILL.md:182 requirements In-scope fix
60 LOW idd-diagnose 範例的 backup id 不符合歸檔格式 skills/idd-diagnose/SKILL.md:786 requirements In-scope fix
61 LOW design.md 引用不存在的 /idd-edit --restore openspec/changes/issue-write-back/design.md:84 requirements In-scope fix
62 LOW 「不先問」的新步驟需要的工具,不在偵測 skill 的 allowed-tools 裡 skills/idd-reorganize/SKILL.md requirements In-scope fix
63 LOW SessionStart 的寫回那一行沒有點名規則檔 hooks/session-start-commit-rule.sh:16 requirements In-scope fix
64 LOW Verify-report notes stack on every diagnosis correction rules/issue-write-back.md:73 logic In-scope fix
65 LOW Step 3 point 3 depends on a result only produced in point 5 skills/idd-edit/SKILL.md:182 logic In-scope fix
66 LOW Leftover confirmation wording and small spec contradictions skills/idd-comment/SKILL.md:82 logic In-scope fix
67 LOW 規則檔的嚴格作者檢查範例在 skill 外跑不起來,失敗會走向公開貼 errata rules/issue-write-back.md:50 security In-scope fix
68 LOW Correcting ### Residue to (none) makes idd-close demand a residue acknowledgement skills/idd-close/SKILL.md:706 regression In-scope fix
69 LOW Prepending to verify reports contradicts idd-comment's stated guard, and PR-mode targets are unspecified rules/issue-write-back.md:73 regression In-scope fix
70 LOW Small drift in counts, version text and references README.md:11 regression In-scope fix
71 LOW 修正:「idd-edit 在 unattended 沒有處理」的 HIGH 偏高,這是卡住的問題,不是寫錯的問題 skills/idd-edit/SKILL.md devils-advocate In-scope fix
72 LOW 修正:沒有 skill 的 session,作者檢查其實還在;失效的是規則本身沒被載入 hooks/session-start-commit-rule.sh devils-advocate In-scope fix
73 LOW errata 指令少了 --body,unattended 會走到提問 rules/issue-write-back.md:55 devils-advocate In-scope fix

查過且成立的部分

  • 有查過而且成立的部分:嚴格作者檢查、mention 網、受保護區塊:以下有讀碼,沒有發現問題: - validate-target ... --correct:bot 拒絕、OWNER 由別人執行時拒絕、只有 login == me 才放行,查不到使用者回 exit 1,欄位缺漏 fail-closed;mock 環境變數只在 test mode 有效。ADMIN 不會因此改到別人的內容。 - 新增 mention:_existing_mentions 只放行目標原有的 login,更正新增的 mention 會被 egress 拒絕,所以寫回不會通知到新的人。 - Original text 等受保護區塊與 ## Current Status、### Clarity Surface:helper 拒絕。 - apply 前重讀與 state hash:目標在預覽後被改動會 refuse。 一點補充(不算缺陷):D1b 的嚴格檢查只存在於 skill 文字。_edit_apply 重驗時用的是 --prepend-note 的一般閘,對 OWNER 與 bot 放行,所以 helper 不會擋模型跳過這一步。舊的確認同…
  • 查過且成立的部分:- 標記不影響其他 gate。 用 compose-correction 對真實 Diagnosis 改 ### Complexity 與 ### Type,idd_parse_complexity、idd_diagnosis_type 都讀到新值(只讀第一行)。所以 logic、regression 的 ### Residue 假警報確實存在(idd-close 比對完全等於 (none),標記會讓它不成立,我實測重現),但只限這個讀取點,沒有擴散到 actionability gate。 - 帶單引號的 $HOME 路徑沒問題。 --body-file '$HOME/...' 由 helper 的 _home_path 展開,範例指令可以跑。 - 測試。 issue-write-back 42、in-place-correction 229、session-start-commit-rule 29 全過;只跑了這三組,且新行為確實只有字串斷言。 - 外部寫入(ew-block)。 `### Sister Con…

Scope Check

沒有超出 #424 範圍的程式改動。rules-layering 對照表、rule 數量等文件沒有跟上(#57、#70)。

Process note

reviewer 指出本次 context 把流程指示放在標為不可信的區塊內(#77),下一輪改放到區塊外。

…ible line (#424)

Verify round 1 (PR #469) failed on one CRITICAL and seventeen HIGH. The
maintainer decided four points after reading the findings:

- Comments: only OWNER, MEMBER and COLLABORATOR can lead to a write-back,
  factual claims are checked in the repository first, and Type and
  Complexity never move because of a comment. New script
  writeback-candidates.py; idd-diagnose, idd-plan, idd-update run it.
- Detecting skills correct only the user's own Diagnosis Root Cause,
  Impact and Risks, after the main agent checks the evidence itself.
  Expected, Strategy, checklists and everything else are listed.
- Only a decided change counts; a closed issue is not rewritten.
- --correct ends the replaced text with a visible line (--note).

Also from the findings: a privacy hit at any level stops the no-ask path;
SCRUB=enforce keeps the confirmation; idd-edit no longer asks in unattended
mode (discard --reason, finish reports HELD); corrections after
implementation that overturn the premise go to idd-reorganize; the main
specs no longer require a confirmation; idd-close ignores the line when it
reads Residue; --body-file refuses more private paths; verify scans Applied
Corrections.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 2 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus

Aggregate

FAIL — 0 CRITICAL、15 HIGH、63 MEDIUM、25 LOW、5 INFO(合併後 108 則,同一問題有多則)

審的是本機 commit a23ebe0(尚未推上 PR;PR head 仍是 844e8ea)。第 1 輪的 CRITICAL(來源沒有信任邊界)已修。

主題

  1. idd-update 跑寫回(idd-all Phase 5: PR body heredoc 改 quoted (預防未來 RCE) #7、idd-all Phase 0.2: GITHUB_REPO post-derive shape assertion #8、[SOP] umbrella split flow should mandate commit log scan before filing sub-issues #11、Complexity routing: vagueness 應該是一階信號,但目前 4 層 gate 都沒衡量需求清晰度 #12、idd-list 應該顯示引用 issue 的 open PR 資訊 #13、[refactor] idd-list PR body parsing: ignore #N inside fenced code blocks (sister concern from #13) #14)。 它在每個 skill 結尾都會跑,所以 verify 也跑到了,可能在輪次之間改驗收依據;會遞迴;和它「只改 Current Status」的定位矛盾。
  2. verify 的自動更正是循環的(idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2、idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3、idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9、[enhancement] idd-list cluster_leader config (lowest | primary) (sister concern from #13) #15)。 feature issue 的 ### Root Cause / Analysis 就是需求清單,查證用的證據又是受驗的 code。連帶更新也和封閉列舉衝突(Clarity 第 4 列與 2026-11-03 決定 2 互相矛盾,[bug] idd-issue multi-finding: run_id second-precision collision + symlink overwrite hardening #76)。
  3. 條件寫反(idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6、[refactor] idd-list Step 5: needs-fix × PR state matrix 應展開,不該摺疊成單行 (verify follow-up from #13) #16、[refactor] idd-list regex #(\d+) 應加 \d{1,7} 上限 + 過濾 #0 (verify follow-up from #13, related #14) #19、feat(idd-all-chain): Phase 0 diagnosis-readiness gate (Step 0.4) #50)。 skill 寫「定案或查證」,規則要的是兩者都成立。
  4. 其他 HIGH: 委派 /idd-edit 沒帶 --repo(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1);listed 在 unattended 下沒有東西會停(idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4,[docs] idd-issue multi-finding: backward compat migration note for legacy CI callers (v2.55.0+) #78 修正:feat: idd-all 在 verify 乾淨通過後自己 merge 並 close,結束時回報(Foresay traceable:可逆操作先做再回報) #392 合併後才成立);已關閉的 issue 只在規則與候選清單擋(idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5);外人 comment 經 idd-update Step 3 進 Current Status(idd-all Examples: 跨 repo invocation 段重複描述,合併 #10,[enhancement] idd-issue multi-finding spec gap audit: 7 corner-case contract gaps (v2.55.0+) #77 修正:這條路早已存在)。
  5. 回歸(tracking: Claude Code plugin cache path schema 變動 watch-list (tangential from #28) #35、[refactor] Sync diagnosis-detection narrowing to sister skills idd-all/idd-list/idd-update (verify follow-up from #53) #59)。 可見文字讓「只有標記的空更正」檢查失效,整則 comment 可能被清空。
  6. 隱私自審的範圍(bug: idd-all Phase 0.6 graceful-degrade 對 unattended automation caller 是 functional regression (DA R4.a from #28 verify) #40、feature: /idd-ask skill — query GitHub issues knowledge base (mirror /spectra-ask) #72)。 對整份 PREVIEW 審,既有內容會讓更正永遠寫不進去;light 的命中沒有定義。

Devil's Advocate 指出前兩個主題可以用砍掉來解,不必再補防線(#69、#70、#76)。

Findings

# Severity Finding Source Action
1 HIGH 自動更正呼叫未傳入已解析的 repository,可能修改錯誤的 repo — Codex 標為 P1/高(靜態審閱,未實際執行測試)。 位置:idd-verify/SKILL.md Step 3.5 第 2 項;idd-diagnose/SKILL.md Step 3.8、idd-reorganize/SKILL.md Step 3.5 亦同。 具體內容:comment:5805214375 --correct --section ... --body-file ... --note ...。這些新加入的自動呼叫均未帶 --repo… skills/idd-verify/SKILL.md codex Blocking
2 HIGH 偵測 skill 仍會自動改寫 Implementation Plan,與決定 2 和同一節的封閉列舉衝突 — 決定 2 是偵測 skill「只改診斷的事實」。同一節 L1224 也寫「只有這三個段落可以直接改(封閉列舉)」,spec Skills that detect errors 寫「The targets SHALL be exactly the sections ... (closed list)」,並把 verify reports of any round 列為 listed and not changed。 但 L1257 又規定:「目標是 Diagnosis 時…… skills/idd-verify/SKILL.md:1257 requirements Blocking
3 HIGH 前提被推翻時,unattended 會自動走 idd-reorganize,沒有「停給人」 — 決定 2:列為 finding,「停給人。attended 與 unattended 相同」。 idd-verify:1226(idd-diagnose:788 同句)寫「這次更正讓既有實作的前提不成立時,不在這裡改,走 idd-reorganize」。規則 L96 與 spec A corrected diagnosis... 寫 the AI SHALL invoke idd-reorganize。三處都沒有 attended/unattended 分支。 i… skills/idd-verify/SKILL.md:1226 requirements Blocking
4 HIGH Outcome listed 在 unattended 下沒有任何東西會停,決定 2 的「停給人」不成立 — 決定 2 把 ## Expected、範圍、checklist、### Type、### Complexity 定為 finding,停給人,attended 與 unattended 相同。 idd-diagnose Step 3.8 的 listed 只寫進 Diagnosis comment 的 ### Applied Corrections。grep 確認 idd-all、idd-all-chain、idd-close 都不讀這個區塊,Phas… skills/idd-diagnose/SKILL.md:786 requirements Blocking
5 HIGH 決定 3「已關閉的 issue 不改」只落在規則與候選清單,偵測 skill 與 /idd-edit 沒有檢查 — 決定 3 與 spec 都寫「A closed issue SHALL NOT be rewritten」。實際只有兩處處理:規則 L15 的散文,以及 writeback-candidates.py 對 closed 不列。 idd-verify Step 3.5、idd-diagnose Step 3.8、idd-reorganize Step 3.5 都沒有查 issue state(grep closed/關閉/reopen 沒有相關結果)。helper 的 r… rules/issue-write-back.md:15` requirements Blocking
6 HIGH 三個 skill 把「定案而且查證」寫成「定案或查證」,兩邊都漏 — idd-update:117、idd-plan:144、idd-diagnose:230 同一句:「TRUSTED:是定案的決定,或事實主張經你用 repo 證據查證成立,且這張 issue 還沒反映 → 依三類寫回」。 規則第 60 行與 spec(issue-write-back spec 第 9、37 行)要的是兩者都成立:只有定案才算改變,而且裡面的事實主張要先查證。維護者決定 1 寫「AI 要自己查證」,決定 3 寫「假設與提問不算」。 照 skill 的「或」… skills/idd-update/SKILL.md:117 logic Blocking
7 HIGH idd-update 的寫回會遞迴回 idd-update,停止條件只有模型判斷 — 回答任務的問題:可以遞迴,沒有任何東西擋。 路徑:idd-update Step 1.1 → TRUSTED 第三類 → /idd-comment → idd-comment Step 6(第 556 行,「強制,不可省略」)→ idd-update → Step 1.1。第一、二類:/idd-edit --correct → 規則第 94 行「Current Status:跑 /idd-update #N」→ idd-update → Step 1.1。 Ste… skills/idd-update/SKILL.md:121 logic Blocking
8 HIGH /idd-verify 不跑這一步的規定被自己的 Auto-Update 繞過 — spec(issue-write-back spec 第 37 行)寫「/idd-verify SHALL NOT run this trigger」,規則第 52 行寫「idd-verify 不跑這一步:驗收中不改驗收依據」。 但 idd-verify:1575 寫「Verify comment 完成後,自動執行 idd-update」,而 idd-update:121 明說 Step 1.1「在每個階段結束時都會跑」。所以每次 /idd-verify 都會… skills/idd-verify/SKILL.md:1575 logic Blocking
9 HIGH 偵測 skill 的封閉列舉與「連帶更新」互相矛盾,verify 仍能改 Implementation Plan — 同一個 Step 3.5 有兩句相反的話: - 第 1224 行:「只有這三個段落可以直接改(封閉列舉,不得依性質相似類推)」,checklist 列為只列出不改。 - 第 1257 行:「你自己的 Implementation Plan 受影響的段落用 --correct」。idd-diagnose:819、idd-reorganize:118 相同。 Plan 不在三個段落之內,而 Plan 的內容正是 - [ ] 項目:idd-implement:518 從 P… skills/idd-verify/SKILL.md:1257 logic Blocking
10 HIGH 外人的 comment 仍可經 idd-update Step 3 自動改寫 issue 正文,連 ### Blocking 這個 gate 欄位也會動 — Step 1.1(L118)寫 UNTRUSTED「不改正文與 Diagnosis」,但同一個 skill 的 Step 3(L171)是「掃描所有 comments,提取」Key Decisions、Scope Changes、Blocking,再由 Step 4 寫進 issue 正文的 ## Current Status。整份 skill 除了新增的 Step 1.1,沒有任何 author_association 過濾(grep author|associati… skills/idd-update/SKILL.md:171 security Blocking
11 HIGH idd-verify 不跑觸發,但它結尾的 idd-update 會跑,comment 仍能在 verify 輪次之間改驗收依據 — 規則 L52 與 spec 寫「/idd-verify SHALL NOT run this trigger」(驗收中不改驗收依據)。可是 idd-verify L1575 在報告貼出後自動執行 idd-update,idd-all L1467 也寫每個 sub-skill 都會跑,idd-update L120 更明寫 Step 1.1「在每個階段結束時都會跑」。Step 1.1 的 TRUSTED 分支可以依三類寫回,沒有 phase 限制,也沒有 unattended … skills/idd-verify/SKILL.md:1575 security Blocking
12 HIGH idd-verify 的收尾 idd-update 仍會跑寫回觸發,可以改驗收依據 — spec issue-write-back 寫「/idd-verify SHALL NOT run this trigger」,規則 L52 寫「idd-verify 不跑這一步:驗收中不改驗收依據」,D5 也這樣說;測試只檢查 idd-verify 的文字裡沒有 writeback-candidates.py。 但 idd-verify L1575 規定 verify comment 貼出後自動執行 idd-update,而 idd-update 新的 … skills/idd-verify/SKILL.md:1575 regression Blocking
13 HIGH idd-update Step 1.1 會重複詢問同一則 comment,寫回時還會巢狀呼叫自己 — 重複詢問。 候選視窗是 Last updated 減一天(writeback-candidates.py cutoff_of),而 idd-update 每次都把 Last updated 蓋成今天,所以今天與昨天的 comment 每次都重新列出。唯一的跳過條件是「已經反映過的」。UNTRUSTED 或尚未定案的 comment 永遠不會被反映,使用者答過也沒有地方記錄。attended 的 idd-all(Plan tier)至少有 6 次讀取點:… skills/idd-update/SKILL.md:119 regression Blocking
14 HIGH idd-update 自己的鐵律與文件仍寫「只改 Current Status」,和 Step 1.1 直接矛盾 — Step 1.1 現在可以改 ## Expected、Diagnosis,也可以貼 comment,但同一份檔案仍然寫: - description L4-5:「保留原始記錄(Problem/Type/Expected),只更新狀態區塊」、「最 idempotent 的 batch」 - 核心原則:「原始記錄不動」 - Batch 段 L28:「Pure idempotent,最安全的 batch 之一」,並建議重啟 session 後先 batch update - 設… skills/idd-update/SKILL.md:381 regression Blocking
15 HIGH 封閉列舉用標題當 proxy:feature issue 的 Root Cause / Analysis 就是需求拆解,verify 仍能改自己的驗收依據 — Step 3.5 開放 ### Root Cause / Analysis,理由是 ## Expected、### Strategy、checklist 才是驗收依據。但 idd-diagnose 的模板(SKILL L340-343)規定這一段在 feature 寫 {feature: requirements breakdown},在 refactor 寫現況與問題。#424 自己的 Diagnosis 就把 R1–R6 需求表放在這段。所以 featur… skills/idd-verify/SKILL.md:1224 devils-advocate Blocking
16 MEDIUM 候選 comment 的處理條件繞過「明確定案」門檻 — Codex 標為 P2/中(靜態審閱)。 位置:idd-diagnose/SKILL.md Step 1.1 的 TRUSTED 分支;idd-plan/SKILL.md… skills/idd-diagnose/SKILL.md` codex In-scope fix
17 MEDIUM idd-reorganize 在自身流程內要求再次呼叫自己,缺乏終止條件 — Codex 標為 P2/中(靜態審閱)。 位置:idd-reorganize/SKILL.md Step 3.5「先親自查證」:「這次更正讓既有實作的前提不成立時,不在這裡改,… skills/idd-reorganize/SKILL.md codex In-scope fix
18 MEDIUM 「idd-verify 不跑這個觸發」不成立:它的 Auto-Update 會執行 idd-update Step 1.1 — 規則 L52、spec(/idd-verify SHALL NOT run this trigger)與 design D5 都這樣寫。但 idd-verify:1575 規定… skills/idd-verify/SKILL.md:1575 requirements In-scope fix
19 MEDIUM Step 1.1 的信任條件是「或」,與規則、決定 1 和決定 3 不符 — idd-update:117、idd-plan:144、idd-diagnose:230 都寫「TRUSTED:是定案的決定,或事實主張經你用 repo 證據查證成立」。 規則… skills/idd-update/SKILL.md:117 requirements In-scope fix
20 MEDIUM unattended 下,別人的 comment 既沒有記成 note,也沒有問人 — 決定 1:其他人的 comment「只記成 note 或問人」。實作改成 unattended「只列在這次 skill 的報告裡」(規則 L61、三個 skill 的 Step 1… skills/idd-update/SKILL.md:340 requirements In-scope fix
21 MEDIUM attended 下,同一則 UNTRUSTED comment 會被重複詢問 — docstring 寫 A comment seen twice is skipped by the reader once it is reflected,Step 1.1 寫「… scripts/writeback-candidates.py:14 requirements In-scope fix
22 MEDIUM 決定 1「接進會讀 comment 的 skill」只接了三個,idd-implement 與 idd-close 留有缺口 — 決定 1 寫「這一步接進會讀 comment 的 skill」。grep 顯示 idd-implement(L113、L457)、idd-close、idd-reorganiz… skills/idd-implement/SKILL.md:113 requirements In-scope fix
23 MEDIUM 帶受信任 association 的 bot 被標為 TRUSTED,與規則的信任表不符 — 規則 L61 把 bot 列在「其他人」。script 只看 association:label = "TRUSTED" if assoc in TRUSTED else "UN… scripts/writeback-candidates.py:114` requirements In-scope fix
24 MEDIUM 決定 4 的「一句原因」不是必要條件;errata 路徑沒帶 --note,還標成「AI 判斷」 — 決定 4:段落尾留一行,含日期、AI 判斷、一句原因。helper 的 --note 是選用的,沒給就只印 _更正於 YYYY-MM-DD(AI 判斷)_,spec 與 e… skills/idd-comment/SKILL.md:353 requirements In-scope fix
25 MEDIUM Stage 1 的流程句放錯位置,確認之後又回到確認 — L830(要調整)原本結尾的「然後回到這個 Stage 1 重新確認」被留到 L831:「Stage 1 確認之後,才套用 Step 3.8 的更正……然後回到這個 Stage 1… skills/idd-diagnose/SKILL.md:831 requirements In-scope fix
26 MEDIUM idd-reorganize 叫自己去走 idd-reorganize — L87 是從 idd-verify 複製過來的句子:「這次更正讓既有實作的前提不成立時,不在這裡改,走 idd-reorganize」。在這個 skill 裡,前提不成立正是它… skills/idd-reorganize/SKILL.md:87 requirements In-scope fix
27 MEDIUM CHANGELOG 宣稱 verify 會註明 Diagnosis 或正文被改過,但 Step 1 沒有記錄基準值 — L1206 寫「Step 1 另記最新 Diagnosis comment 的 updated_at 與 issue 正文的雜湊,這裡再讀一次」。Step 1(L797–818… skills/idd-verify/SKILL.md:1206 requirements In-scope fix
28 MEDIUM 封存後的主 spec 與規則仍保留舊條件:enforce 才擋、一律不問、errata 指標要確認 — 我在拋棄式 clone 跑過 spectra archive issue-write-back(added 14、modified 3、removed 4)。主 spec 仍有… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:25 requirements In-scope fix
29 MEDIUM 主 spec user-rule-injection 仍要求 hook 內容 statically defined,而這個 change 沒有修改它 — spec 寫「The hook content SHALL be statically defined and token-aligned」。hook 現在是 cat <<RUL… openspec/specs/user-rule-injection/spec.md:11` requirements In-scope fix
30 MEDIUM idd-update 的自述與新行為矛盾:仍稱只更新狀態區塊、idempotent — Step 1.1 讓 idd-update 可以改 ## Expected、Diagnosis,還可以貼 comment、呼叫 reorganize。但這些文字沒改: - de… skills/idd-update/SKILL.md:5 requirements In-scope fix
31 MEDIUM allowed-tools 沒補齊新步驟:idd-update 沒有 python3 與 Skill,idd-edit 第一次跑 unattended 卻沒有 python3 — 第 1 輪 #62 修了一部分。at a23ebe0: - idd-update:Bash(gh:*) Bash(git:*) Read Edit。Step 1.1 要 pyt… skills/idd-update/SKILL.md:11 requirements In-scope fix
32 MEDIUM 使用者自己在 GitHub 上留的 comment 永遠不觸發,與 Clarity 1 的「任何人」有落差,且沒有記錄這個決定 — issue 的 Clarity 1 已 resolved:「session 裡的討論與 GitHub 上任何人的 comment 都觸發寫回」,Diagnosis R1 也這樣寫。… scripts/writeback-candidates.py:100 requirements In-scope fix
33 MEDIUM 規則要求第三類等「討論告一段落再記」,與 issue 的 Expected 和規則自己 L34 衝突 — issue ## Expected:「寫回發生在討論當下,不等討論結束才補」。規則 L34 也寫「定案之後就寫回,不等討論結束才一次補」。 但 L16 寫「同一段討論不要一個回… rules/issue-write-back.md:16 requirements In-scope fix
34 MEDIUM 第 1 輪 #18、#50 只修了實作之後;實作之前的連帶更新是空的,也沒有說明這是刻意留下 — 第 1 輪 #18 的 Spectra tier 與 #50 的問題類改變,現在由 L96 處理,但只限「phase 到 implemented 以後」。在那之前: - Spect… rules/issue-write-back.md:88 requirements In-scope fix
35 MEDIUM 可見文字讓「只有標記」的空更正檢查失效(回歸) — run-start 把可見文字接進 body(第 2222 行),之後 _correct_prepare 第 1749 行的檢查「替換內容只有這則 comment 的標記 → … scripts/idd-edit-helper.py:2222 logic In-scope fix
36 MEDIUM body 已有舊的可見文字時會疊兩行,舊的那行可能寫著已經錯的值 — 決定 4 是段落尾留一行,原因寫正確的內容,不重述錯的值。helper 不處理 body 裡既有的 _更正於 行,規則也沒說替換文字要不要含它。AI 最自然的做法是讀段落、改一… rules/issue-write-back.md:27 logic In-scope fix
37 MEDIUM 候選腳本沒有記憶,同一則 comment 會反覆列出、反覆問人 — 篩選條件只有 created_at >= Last updated - 1 天。skill 的說法是「同一天的 comment 可能再出現一次」,docstring 是「see… scripts/writeback-candidates.py:99 logic In-scope fix
38 MEDIUM cutoff 假設每次更新 stamp 前都成功列過,讀取失敗與 unattended 的報告都會讓 comment 消失 — Step 1.1 寫「exit 1(讀不到)→ 回報一行,往下」。往下就會更新 Last updated,下一次的 cutoff 跟著前進,比新 stamp 早一天以上而沒看過的 … skills/idd-update/SKILL.md:113 logic In-scope fix
39 MEDIUM idd-edit 的 unattended 偵測與 idd-all 寫旗標的位置對不上,--cwd 與子目錄都判成 attended — idd-all 把旗標寫在 $CWD(第 347 行),$CWD 是 --cwd 的值或 $(pwd)(第 150 行),沒有正規化到 toplevel。idd-e… skills/idd-edit/SKILL.md:196 logic In-scope fix
40 MEDIUM 不問的路徑對整份 PREVIEW 做隱私自審,既有內容也會讓更正永遠寫不進去 — 規則第 84 行是「對要寫入的文字」做語意檢查,idd-edit Step 3 第 4 點是「對 PREVIEW」。--correct 的 PREVIEW 是整則 commen… skills/idd-edit/SKILL.md:187 logic In-scope fix
41 MEDIUM idd-diagnose Stage 1 的流程接反:確認後要再確認,調整後反而不再確認 — 舊文字是一條:「如果要調整 → 修改後追加修正,然後回到這個 Stage 1 重新確認」。#424 拆成兩條,結尾那句跟到了第二條: - 第 830 行:「如果要調整 → /id… skills/idd-diagnose/SKILL.md:831` logic In-scope fix
42 MEDIUM idd-reorganize 的 Step 3.5 叫自己去走 idd-reorganize — 這段是從 idd-verify、idd-diagnose 複製來的:「這次更正讓既有實作的前提不成立時,不在這裡改,走 idd-reorganize」。在 idd-reorga… skills/idd-reorganize/SKILL.md:87 logic In-scope fix
43 MEDIUM 被拒時的處置是開放列舉,暫時性失敗也會貼公開 comment;exit 7 沒有下一步 — 第 85 行:「/idd-edit 被拒(section-not-found、protected、setext、archive 等):這個改變改貼一則第三類 c… rules/issue-write-back.md:85 logic In-scope fix
44 MEDIUM allowed-tools 只補了偵測 skill,新接的 idd-update 與 idd-plan 沒補 — 第 1 輪 #62 之後,idd-verify、idd-reorganize、idd-diagnose 補了工具,但接上觸發的另外兩個沒有: - idd-update:只有 Ba… skills/idd-update/SKILL.md` logic In-scope fix
45 MEDIUM verify 的需求端檢查沒有基準值,Step 1 也沒有讀 Diagnosis comment — 第 1206 行在 Step 2.9 寫「Step 1 另記最新 Diagnosis comment 的 updated_at 與 issue 正文的雜湊,這裡再讀一次」。但 … skills/idd-verify/SKILL.md:1206 logic In-scope fix
46 MEDIUM errata 委派沒帶 --note,讀者只看到沒有原因的可見文字 — 決定 4 是段落尾留「日期、AI 判斷、一句原因」。idd-comment 就地更正的委派指令(第 354-355 行)只帶 --body-file,結果是 _更正於 YYY… skills/idd-comment/SKILL.md:354` logic In-scope fix
47 MEDIUM 帶 MEMBER/COLLABORATOR 的 bot 被標成 TRUSTED,與規則表相反 — 規則 L61 把 bot 列在「其他人」,腳本卻只看 association。我用替身 gh 跑 {"login":"ci[bot]","type":"Bot"}、associ… scripts/writeback-candidates.py:103 security In-scope fix
48 MEDIUM author_association 不代表寫入權限,用途卻從過濾讀取升級成改寫內容 — GitHub 自己的定義(我用 GraphQL introspection 查的):MEMBER 是「member of the organization that owns th… scripts/writeback-candidates.py:26 security In-scope fix
49 MEDIUM 受信任作者引用外人的話,整則都算受信任;隱藏的 HTML comment 也算 — 信任是以整則 comment 為單位。規則、spec、Step 1.1 都沒有區分作者自己寫的文字和 > 引文。協作者用 quote reply 貼一段外人的話並寫「+1」,或… rules/issue-write-back.md:60 security In-scope fix
50 MEDIUM Step 1.1 的「或」讓事實主張換個說法就能跳過查證 — 規則 L60 要求定案決定「裡面的事實主張」也要先查證。三個 skill 的 Step 1.1 寫的卻是「是定案的決定,或事實主張經你用 repo 證據查證成立」,定案的決… skills/idd-update/SKILL.md:117 security In-scope fix
51 MEDIUM 不可信內容可以經「報告」與 listed 列進入維護者署名的 Diagnosis — Step 1.1 規定 UNTRUSTED「unattended 列在這次的報告裡」,沒有限制能列什麼。idd-diagnose 的報告就是 Diagnosis comment(… skills/idd-diagnose/SKILL.md:226` security In-scope fix
52 MEDIUM 「repo 內的證據」沒有綁定 ref,外部 PR 與附件都能製造證據 — Step 3.5 要主 agent 用「repo 內的證據(檔案與行、自己跑的輸出)」查證,並排除 PR 文字。但 PR mode 在 L649 已 gh pr checkout… skills/idd-verify/SKILL.md:1226` security In-scope fix
53 MEDIUM 正文裡偽造一行 Last updated 就能讓候選清單永遠為空 — STAMP_RE 搜尋整份正文、取第一個命中,不限於 ## Current Status,也不限制未來日期。我實測:外人開的 issue 正文裡放 **Last upda… scripts/writeback-candidates.py:30` security In-scope fix
54 MEDIUM 沒有處理紀錄:協作者的 comment 可以蓋掉使用者之後在 session 的決定 — 「已經反映過的就跳過」完全靠模型比對現在的內容,沒有記錄哪則 comment 處理過。情境:協作者的決定 X 已寫回;使用者當天在 session 裡定案改成 Y,--corre… skills/idd-update/SKILL.md:119` security In-scope fix
55 MEDIUM 「不改」的清單太窄,而且只寫在散文裡;helper 不擋 — 規則保護 ### Type、### Complexity 的理由是「下游的 gate 與分流都吃這兩段」。同樣的理由也適用於別的段落,但它們不在清單內,comment 觸發… rules/issue-write-back.md:63 security In-scope fix
56 MEDIUM 隱私閘只在 idd-edit 改了;第三類 comment 走 idd-comment,warn 仍是提醒後照發 — 規則 L84 與 spec 要求每次寫回「任何等級命中都停下」。這段邏輯只寫進 idd-edit Step 3。第三類 comment、--correct 被拒之後的 fall… skills/idd-comment/SKILL.md:539 security In-scope fix
57 MEDIUM 來自 GitHub 的自由文字還有幾條路會進 shell 指令 — L36 的「不把文字貼進指令」只涵蓋 /idd-edit --correct 的替換內容。其餘仍是模型手動組引號: - --note:本身就是一句內容,L36 要求附 co… rules/issue-write-back.md:36 security In-scope fix
58 MEDIUM --body-file 的黑名單仍放行憑證與私人檔案 — 第 1 輪 #40 之後只加了四個檔名和 .claude/projects。我用假的 HOME 實測,以下 run-start 都是 rc=0:~/.claude/.cred… scripts/idd-edit-helper.py:226` security In-scope fix
59 MEDIUM 可見文字讓「只有 top marker 的替換內容」不再被拒,整則 comment 會被清空 — 已實測。spec 規定「one that holds only a copy of the comment's top marker SHALL be refused as em… scripts/idd-edit-helper.py:2222` regression In-scope fix
60 MEDIUM 人下的更正也標「AI 判斷」,errata 的可見文字也沒有那一句原因 — _correct_note_line 對每個 --correct 都寫「(AI 判斷)」,包括這些由人決定的情況: - 使用者直接跑 /idd-edit --correc… scripts/idd-edit-helper.py:1622` regression In-scope fix
61 MEDIUM idd-update 的 Step 1.1 分 attended/unattended,但沒有任何偵測方式 — Step 1.1 寫「attended 告訴使用者、問要不要採信;unattended 列在這次的報告裡」,而 idd-update 全檔只有這一處提到 unattended,沒有… skills/idd-update/SKILL.md:118 regression In-scope fix
62 MEDIUM allowed-tools 只補了偵測 skill,新步驟的工具在其他 skill 沒有預先核准 — 官方文件(code.claude.com/docs/en/skills,2026-11-03 查證):allowed-tools 只預先核准,不限制;沒列的工具由使用者的 pe… skills/idd-update/SKILL.md:11 regression In-scope fix
63 MEDIUM 規範文字仍寫 privacy 只在 enforce 命中才停,與 D6 的「任何等級」矛盾 — D6、規則、CHANGELOG、idd-edit Step 3 都改成「任何等級命中都停」,但以下兩處還是舊條件: - rules/append-vs-modify.md:129… rules/append-vs-modify.md:129` regression In-scope fix
64 MEDIUM idd-update 新步驟的成本沒有上限,而且不過濾 IDD 自己產生的 comment — gh 呼叫。 每次 idd-update 多 3 個 gh 呼叫(api user、issue、comments --paginate),每則候選再加 1 個。St… skills/idd-update/SKILL.md:109 regression In-scope fix
65 MEDIUM 「驗證期間 Diagnosis 被改過」的比對沒有接上,測試只查到一句文字 — Step 2.9 寫「Step 1 另記最新 Diagnosis comment 的 updated_at 與 issue 正文的雜湊,這裡再讀一次」。但 Step 1 沒有這… skills/idd-verify/SKILL.md:1206 regression In-scope fix
66 MEDIUM idd-diagnose Stage 1 的「回到 Stage 1 重新確認」被移到錯的分支 — 改版前是「如果要調整 → 修改後追加修正,然後回到這個 Stage 1 重新確認」。 現在這句跑到新的第二個 bullet 尾端:「Stage 1 確認之後,才套用 Step 3.… skills/idd-diagnose/SKILL.md:831 regression In-scope fix
67 MEDIUM 「明確定案」無法執行也無法事後查核,且未依專案規則處理這個屬性判斷 — 回答 premise:只靠散文,不能強制。 - 寫法是一句總括判準加兩個例子(L11-14),這正是 common-spec-prose-enumeration 禁止的形狀。「… rules/issue-write-back.md:11 devils-advocate In-scope fix
68 MEDIUM 信任邊界只擋「改寫 Diagnosis」,不擋「重新寫一份 Diagnosis」 — 回答「信任邊界撐不撐得住」:作者閘在改寫路徑上撐得住,但旁邊還有一條路。 - idd-diagnose Step 1 用 --json title,body,labels,com… skills/idd-diagnose/SKILL.md:231` devils-advocate In-scope fix
69 MEDIUM 多則 finding 同根:把 Step 1.1 從 idd-update 拿掉,比一條條補防線小 — 其他 reviewer 分開報的下列問題,都因為把觸發放進 idd-update: - verify 的 Auto-Update 繞過「verify 不跑」(requirement… skills/idd-update/SKILL.md:109 devils-advocate In-scope fix
70 MEDIUM 第 2 輪多出來的機件可以更小:候選腳本與 Last updated 截止 — 數字:844e8ea→a23ebe0 共 33 檔 +990/-213;腳本 110 行、測試 125 行;規則由 86 行增為 109 行。Step 1.1 貼了 3 份,Ste… scripts/writeback-candidates.py:55 devils-advocate In-scope fix
71 MEDIUM 已被隱藏(minimized)的 comment 仍列為 TRUSTED — 協作者把自己的 comment 隱藏為 Outdated 或 Resolved,等於撤回。REST 回應有 minimized 欄位(實查 #424 的 comment key… scripts/writeback-candidates.py:99 devils-advocate In-scope fix
72 MEDIUM 「任何等級命中都停」在 LIGHT 沒有定義:private repo 要嘛每次都停,要嘛永遠不命中 — privacy-scrubbing.md L81:LIGHT 是 do not block ordinary identifiers,只守第三方逐字內容。idd-edit St… skills/idd-edit/SKILL.md:187 devils-advocate In-scope fix
73 MEDIUM 「使用 IDD 的 repo」沒有人判斷,也沒有關閉的方法;所有可寫入的 repo 都會被影響 — 規則 Scope 寫「任何使用 IDD 的 repo」,但 hook 沒有 matcher、也沒有條件,那一行只限「有寫入權」。grep write_back 與 write… hooks/session-start-commit-rule.sh:19` devils-advocate In-scope fix
74 MEDIUM 沒有任何證據顯示那一行會改變沒有 skill 的 session;5 行上限也管不到成本 — 回答 premise:目前未知,diff 沒有驗。Diagnosis 第 3 點說討論大多發生在 skill 之外,proposal 也說這一行「讓 skill 之外的討論也套用」… scripts/tests/session-start-commit-rule/test.sh devils-advocate In-scope fix
75 MEDIUM unattended 的「列在這次的報告裡」在 idd-update 沒有報告可列 — 其他 reviewer 報的是沒有記成 note,以及 cutoff 會讓 comment 消失。實際比那更糟:Step 6(L340)規定被其他 skill 自動呼叫時「只輸出上… skills/idd-update/SKILL.md:118 devils-advocate In-scope fix
76 MEDIUM 修正 HIGH「偵測 skill 仍會自動改 Implementation Plan」:這是兩個維護者決定互相衝突,要問人,不是實作錯誤 — requirements 與 logic 把它報成違反決定 2。但 Clarity 第 4 列(使用者 resolved)、decision-orig 第 5 點、Diagnosi… skills/idd-verify/SKILL.md:1224 devils-advocate In-scope fix
77 MEDIUM 修正 security 的 HIGH「外人 comment 經 Step 3 改寫正文」:這條路早已存在,不是這個 diff 引入的 — git log -S 顯示 Step 3 自 ae31417(2026-03-27)就在,a23ebe0 的 idd-update 只多 15 行(TaskCreate 與 S… skills/idd-update/SKILL.md:169 devils-advocate In-scope fix
78 MEDIUM 修正 requirements 的 HIGH「Outcome listed 沒有東西會停」:在這棵樹上有停,真正的風險在 #392 合併之後 — a23ebe0 的 idd-all 一律停在 verified,不 auto-close、不 auto-merge(L24、L58、L1339),人一定會讀到報告,「停給人」目前成… skills/idd-verify/SKILL.md:1252 devils-advocate In-scope fix
79 LOW 已勾選的任務與 design 範圍描述的是舊行為 openspec/changes/issue-write-back/tasks.md:9 requirements In-scope fix
80 LOW CHANGELOG 的「shell history」只成立於兩個檔名,憑證檔仍可通過路徑閘 scripts/idd-edit-helper.py:226 requirements In-scope fix
81 LOW Diagnosis Strategy 的「上線後把 #423 寫回」沒有任何追蹤 openspec/changes/issue-write-back/tasks.md requirements In-scope fix
82 LOW 幾處小的殘留文字與遺漏 skills/idd-edit/SKILL.md:83 requirements In-scope fix
83 LOW idd-edit Step 3 第 3 點最後一項可讀成 attended 的 enforce 也要捨棄;discard 後沒有說跳過其餘步驟 skills/idd-edit/SKILL.md:186 logic In-scope fix
84 LOW Step 1.1 在 idd-diagnose 第一次診斷時沒有 Diagnosis 可寫;idd-diagnose、idd-plan 沒有重讀 skills/idd-diagnose/SKILL.md:230 logic In-scope fix
85 LOW writeback-candidates.py 的四個邊界 scripts/writeback-candidates.py:30 logic In-scope fix
86 LOW --note 的連結後面接中文會壞掉 rules/issue-write-back.md:60 logic In-scope fix
87 LOW PR mode 的 Applied Corrections 不會被 external-writes collector 掃到;verify 報告頂端加註後第一行摘要變了 skills/idd-verify/SKILL.md:258 logic In-scope fix
88 LOW 只看 created_at:被編輯的舊 comment 看不到,範圍內的編輯也沒有任何信號 scripts/writeback-candidates.py:99 security In-scope fix
89 LOW --note 只擋換行與 HTML comment 標記,可見行能放 HTML、圖片與跨 repo 引用 scripts/idd-edit-helper.py:2219 security In-scope fix
90 LOW SessionStart 這一行寫了「不先問」,卻沒提來源信任與隱私自審 hooks/session-start-commit-rule.sh:19 security In-scope fix
91 LOW 新增的工具授權比需要的寬,也不一致 skills/idd-diagnose/SKILL.md:15 security In-scope fix
92 LOW 同一段 Step 1.1 照貼到三個 skill,沒有配合各自的位置 skills/idd-plan/SKILL.md:136 regression In-scope fix
93 LOW idd-reorganize 的 Step 3.5 叫自己走 idd-reorganize skills/idd-reorganize/SKILL.md:87 regression In-scope fix
94 LOW 讀取失敗之後蓋掉 Last updated,舊 comment 會永遠不再列出 scripts/writeback-candidates.py:37 regression In-scope fix
95 LOW EW 掃描讀不到 PR mode 的 Applied Corrections,註解的說法不成立 skills/idd-verify/SKILL.md:265 regression In-scope fix
96 LOW 腳本的信任判斷沒有排除 bot,和規則不一致 scripts/writeback-candidates.py:97 regression In-scope fix
97 LOW 其他仍描述舊行為或與實作不符的文字 openspec/changes/issue-write-back/design.md:90 regression In-scope fix
98 LOW 「phase 判定逐行掃,註記不影響」的說法太滿,#392 的 reader 看首行,也把被編輯過的報告當無效 rules/issue-write-back.md:93 devils-advocate In-scope fix
99 LOW 可見文字只幫到重讀的人,先前讀過舊版的讀者仍然收不到訊號 scripts/idd-edit-helper.py:970 devils-advocate In-scope fix
100 LOW idd-edit 新讀的 unattended 旗標,會把人親手下的 --replace 變成 HELD skills/idd-edit/SKILL.md:196 devils-advocate In-scope fix
101 LOW 拿掉確認之後,issue: 指錯 repo 就沒有最後一道檢查 rules/issue-write-back.md:24 devils-advocate In-scope fix
102 LOW 修正 security 的 MEDIUM「author_association 不代表寫入權限」:這是維護者看過 findings 後的明確選擇 rules/issue-write-back.md:60 devils-advocate In-scope fix
103 LOW 修正兩則 finding 的範圍:「AI 判斷」標籤與「已關閉不改」的修法 scripts/idd-edit-helper.py:974 devils-advocate In-scope fix

Scope Check

程式改動沒有超出 #424。規則、skill、spec 的文字有殘留(#28、#29、#63、#79、#97)。

…rify lists only (#424)

Verify round 2 (PR #469) failed on fifteen HIGH. The maintainer decided two
points (comment 6611450882):

- Other people's comments are looked at when idd-diagnose, idd-plan or
  idd-implement starts. idd-update and idd-verify no longer run the
  candidates script: idd-update runs at the end of every stage, so verify
  could rewrite its own acceptance criteria between rounds, and it recursed.
- idd-verify lists published errors as findings and changes nothing; an
  error in Expected, scope, a checklist, Type or Complexity is Blocking.
  idd-diagnose and idd-reorganize correct only an open bug's Diagnosis
  facts, checked on the default branch; the Implementation Plan is listed.

Also from the findings: a trusted comment must be decided and checked;
"decided" and the refusals that become a comment are closed lists; quoted
text in a trusted comment is someone else's; listed corrections reach
Blocking through idd-update, which now reads trusted comments only;
--repo is always passed; the privacy review covers the text being added;
writeback-candidates takes its cutoff from your own IDD comments and marks
bots untrusted; a marker-only replacement is refused again; an earlier
visible line is replaced; --note and --body-file refuse more.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 3 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus

Aggregate

FAIL — 0 CRITICAL、5 HIGH、33 MEDIUM、24 LOW(合併後 63 則,同一問題有多則)

審的是本機 commit 5795a1d(PR head 仍是 844e8ea)。全套測試 68 個 suite 全過。第 2 輪的 HIGH(idd-update 跑寫回、verify 的循環更正)已不再出現。

主題

  1. 候選清單的截止點(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1、idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3、idd-all Phase 5: PR body heredoc 改 quoted (預防未來 RCE) #7、docs: track upstream gap — Claude Code plugin schema 缺 inter-plugin dependency 機制 (sister from #28) #29、refactor: 抽出 generic plugin-presence detector helper (tangential from #28 plan) #34、feature: /idd-all (無參數) bulk-solve mode — AI 自動 sequence + bundle 所有 open issue #37、docs: clarify #37 close reason — supersession by #44 chain-solve? (sister from #48 diagnosis) #49)。 截止點取自己 stage comment 的 updated_at,而寫回本身就會改它,沒列過的 comment 會永久漏掉;讀取失敗或跨日的階段也一樣。
  2. listed 進 Blocking(idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5、[Bundle test] Step 2: add API #24、[Bundle test] Step 3: add UI #25、feat+docs: ralph-loop dependency declaration + runtime detect (Plan tier) #36、docs: idd-issue Step 4.8 Split Umbrella SOP — pre-flight scan before sub-issue file #38)。 重新診斷改了 Type 或 Complexity 就會擋下 idd-all;解除條件靠模型判斷;verify 的「要人決定」finding 會進自動修。
  3. 偵測範圍太窄(idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2)。 Step 3.8 只在 Diagnosis 有錯時觸發,## Expected 錯了反而不會列出。
  4. 外人的話經由自己的 comment 進來(idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4、[refactor] idd-list footer direct-commit count 應排除 closed phase issue (verify follow-up from #13) #20、[Bundle test] Step 1: build schema #23)。 ### Comments Not Taken 要轉述外人的主張,idd-update 又照單收自己的 comment。
  5. 其他: req_state 在新的 shell 裡不存在(idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6、[enhancement] idd-list cluster_leader config (lowest | primary) (sister concern from #13) #15);spec 與 append-vs-modify 仍寫 enforce 才擋(idd-all Phase 0.2: GITHUB_REPO post-derive shape assertion #8、docs: spec 出 #27 fail-fast 訊息實際長相 (sister from #26) #32、feature: /idd-all chain-solve mode — 自動接續解 spawned issues + 單 review PR #44);design、proposal 殘留舊行為(idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9、[enhancement] idd-list Step 5: planning + has PR 應勸 user 處理 stale/zombie PR (verify follow-up from #13) #17);allowed-tools([test] idd-list cluster algorithm + footer rule + state matrix 沒被任何 production data 跑過 (verify follow-up from #13) #18、feature+docs: idd-verify --loop / idd-all unattended 隱性依賴 ralph-loop — 應宣告 + auto-detect + 內建探索 #28);--body-file 規則的大小寫繞過([refactor] idd-list PR body parsing: ignore #N inside fenced code blocks (sister concern from #13) #14)。

Findings

# Severity Finding Source Action
1 HIGH Cutoff derived from Diagnosis updated_at permanently skips unprocessed comments — Codex [P1/high], verbatim substance: At writeback-candidates.py lines 103-118 (specifically latest = when and cutoff = latest - datetime.timedelta(days=1)), the script takes the updated_at of its own phase comment as evidence that the older candidate comme… scripts/writeback-candidates.py:103 codex Blocking
2 HIGH idd-diagnose and idd-reorganize only look for errors in the Diagnosis, so a wrong ## Expected is never listed and never stops the run — The 2026-11-03 decision after round 1, point 2, says errors in ## Expected, scope, checklist, ### Type and ### Complexity are always listed as findings and stop for a person, in attended and unattended mode alike. The in-place-correction spec agrees (Sk… skills/idd-diagnose/SKILL.md:780` requirements Blocking
3 HIGH writeback-candidates 的截止點跟著自己 stage comment 的 updated_at 前進,沒列過的 comment 會永久漏掉 — latest 取自己 ## Diagnosis|Implementation Plan|Implementation Complete comment 的 stamp(),也就是 updated_at。docstring 的前提是「比這些 comment 舊的 comment,在它們貼出時已經列過」,但這個前提有三種情況不成立: (a) 在列出流程以外編輯自己的 stage comment。session 討論時的寫回(觸發 1,#424 的主路徑)、idd-reorganize Ste… scripts/writeback-candidates.py:105 logic Blocking
4 HIGH idd-update 照單全收你自己的 comment,外人的話可以經由這輪自己造出來的載體進入 Scope Changes/Blocking — Step 3 的新過濾只看 comment 作者:「只採 OWNER、MEMBER、COLLABORATOR 與你自己寫的 comment」(L156)。可是這一輪的設計,正好規定 AI 把外人的主張寫進你自己的 comment:idd-diagnose L228、idd-plan L142、idd-implement L361 要求 unattended 時把每則 UNTRUSTED comment 寫成 ### Comments Not Taken 一行,內容是「連結與一句自己的話」。這一句必然轉述外人的主… skills/idd-update/SKILL.md:156 security Blocking
5 HIGH Blocking from listed Type/Complexity rows stops idd-all after an ordinary re-diagnosis — idd-update Step 3 now puts into ### Blocking every ### Applied Corrections row whose Outcome is listed and whose Section is ## Expected, scope, checklist, ### Type or ### Complexity. idd-diagnose Step 3.8 (L780-784) runs when "本次診斷指出先前的 Diagnosis c… skills/idd-update/SKILL.md:171 regression Blocking
6 MEDIUM Step 2.9 re-check calls req_state() defined only in an earlier Bash invocation — Codex [P2/medium], verbatim substance: req_state() is defined at idd-verify/SKILL.md lin… skills/idd-verify/SKILL.md:819 codex In-scope fix
7 MEDIUM The candidates cutoff moves whenever your own Diagnosis or Plan is edited, so comments are skipped and never shown — The round-2 decision (comment 6611450882) says comments by other people are looked at when… scripts/writeback-candidates.py:108 requirements In-scope fix
8 MEDIUM Privacy stop still reads 'enforce only' in the in-place-correction spec and in append-vs-modify.md — D6 says any level stops: the rule, the issue-write-back spec, idd-edit Step 3, the CHANGEL… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:25 requirements In-scope fix
9 MEDIUM design.md, proposal.md and tasks.md still describe superseded behaviour (idd-update trigger, verify applying corrections) — These statements contradict the maintainer decision of 2026-11-03 (comment 6611450882) and… openspec/changes/issue-write-back/design.md:53 requirements In-scope fix
10 MEDIUM The same untrusted comment is listed and asked about again at each of diagnose, plan and implement — Round 2 HIGH #13 had two parts. The recursion part is fixed by removing the trigger from i… skills/idd-plan/SKILL.md:142 requirements In-scope fix
11 MEDIUM unattended 下沒寫回的 TRUSTED comment 既不寫回也不列出,下一輪就被截止點略過 — diagnose、plan、implement 三處 Step 1.1 只規定 UNTRUSTED 在 unattended 時「列進這次貼出的 …(### Comments No… skills/idd-diagnose/SKILL.md:228 logic In-scope fix
12 MEDIUM 替換內容照抄現有段落(含 marker)時,舊的「更正於…」不會被移除,兩行並存 — while lines and (not lines[-1].strip() or lines[-1].startswith(NOTE_LINE_PREFIX)) 只移除位在*… scripts/idd-edit-helper.py:2248 logic In-scope fix
13 MEDIUM section scope 的空替換檢查放過「只有舊可見行加 marker」的內容,段落正文會被清空 — run-start 移除尾端可見行之後,只檢查 _strip_target_heading(lines, …) 是否為空。prepare 的 marker-only 檢查(k… scripts/idd-edit-helper.py:2250` logic In-scope fix
14 MEDIUM --body-file 私密路徑規則:大小寫不同的 home 前綴可繞過,另有漏擋與誤擋 — _private_path 用 _under_folded(不分大小寫)判斷路徑在 home 底下,再用 os.path.relpath(path, base)(**分… scripts/idd-edit-helper.py:243 logic In-scope fix
15 MEDIUM idd-verify Step 2.9 在新的 shell 呼叫 Step 1 定義的 req_state,每一輪都會誤報「需求被改過」 — req_state 是 Step 1 bash 區塊裡定義的 shell function。Step 2.9 只寫成散文,再加上行內的 req_state "$I" | c… skills/idd-verify/SKILL.md:1214` logic In-scope fix
16 MEDIUM idd-diagnose attended:Step 3.8 的更正延到 Stage 1 之後才套用,但 Stage 1 改過診斷後沒有重新推導 — Step 3.8(L784)在 attended 時「等 Step 4 Stage 1 確認之後才套用」。Stage 1 的「要調整」分支用 --correct 改寫本次 Di… skills/idd-diagnose/SKILL.md:830 logic In-scope fix
17 MEDIUM design.md D5 與 proposal.md 仍寫 idd-update 是觸發點,和第 3 輪的決定矛盾 — D5 寫「idd-diagnose、idd-plan、idd-update 執行時用 scripts/writeback-candidates.py … idd-… openspec/changes/issue-write-back/design.md:53` logic In-scope fix
18 MEDIUM idd-plan、idd-implement 新增了 Step 1.1 寫回,allowed-tools 沒補 — Step 1.1 的寫回依規則要做三件事:mktemp -d、用 Write 工具寫 body file、經 Skill 呼叫 /idd-edit(或 /idd-comm… skills/idd-plan/SKILL.md:142` logic In-scope fix
19 MEDIUM verify Step 3.5 說 bug 的 Diagnosis 事實「下一次 /idd-diagnose 會自己更正」,流程裡沒有這一步 — verify 只把已發表內容的錯誤列成 finding,非 Expected/scope/Type/Complexity 的項目照 Step 5a 分類,可能不是 Blocking… skills/idd-verify/SKILL.md:1236 logic In-scope fix
20 MEDIUM Applied Corrections 的 listed 列可以來自外人,又沒有來源欄,進 Blocking 後外人一則 comment 就能讓 unattended run 停下 — idd-diagnose L786 與 idd-reorganize L89 寫:「reviewer 的轉述……別人的 comment 都不算,列出」。「別人」包含 UNTRUST… skills/idd-diagnose/SKILL.md:786 security In-scope fix
21 MEDIUM idd-update 的信任條件漏了 bot 排除,同一條邊界有兩套定義 — 規則 L68–69 的表寫「OWNER、MEMBER、COLLABORATOR(不是 bot)」,bot 歸在「其他人」。spec 的觸發 requirement 寫「and wh… skills/idd-update/SKILL.md:156 security In-scope fix
22 MEDIUM 不確認的 --correct 仍沿用黑名單式的 --body-file 閘門,以及模型自己就能打開的逃生口 — 我實測 validate_body_file_path(python3 -I -B 載入 helper,沒有改動樹),下列路徑都回 (True, 0):~/Libra… scripts/idd-edit-helper.py:318` security In-scope fix
23 MEDIUM UNTRUSTED 的內文直接讀進持有不確認寫入路徑的主 agent,而且要把它轉述後以維護者名義公開 — 三個 skill 的 Step 1.1 都對每一列(包含 UNTRUSTED)跑 gh api 'repos/<REPO>/issues/comments/<id>' --jq … skills/idd-plan/SKILL.md:142` security In-scope fix
24 MEDIUM A person's decision on a listed row does not stick: idd-all re-diagnoses and lists it again — A listed ## Expected or scope row clears only when "之後的 comment 或正文已經處理了它". idd-all Phas… skills/idd-update/SKILL.md:171 regression In-scope fix
25 MEDIUM Round-1 verify example row 'issue:42 ## Expected 與實作不符 listed' now feeds Blocking from diagnose/reorganize — The example | 3 | issue:42 | ## Expected | 與實作不符 | listed | was copied from the ro… skills/idd-diagnose/SKILL.md:803 regression In-scope fix
26 MEDIUM verify's new 'needs a human' Blocking findings go into idd-all's unattended auto-fix loop — Step 3.5 makes an error in ## Expected, scope, a checklist, ### Type or ### Complexit… skills/idd-verify/SKILL.md:1235` regression In-scope fix
27 MEDIUM idd-implement Step 1.1 writes back after the gate, branch and Stage-1 approval, and re-processes what diagnose just handled — In idd-implement, Step 1.1 runs after Step 0.35 (actionability gate), 0.4 (tree-lock) and … skills/idd-implement/SKILL.md:355 regression In-scope fix
28 MEDIUM Write-back sites have inconsistent allowed-tools; idd-implement and idd-plan cannot pre-authorize the /idd-edit path — Round 3 adds Step 1.1 to idd-implement. A TRUSTED decided change there calls /idd-edit --… skills/idd-implement/SKILL.md:75` regression In-scope fix
29 MEDIUM writeback-candidates cutoff uses updated_at of your own stage comments, so write-backs silently hide comments nobody has seen — latest is the newest stamp() (updated_at) of your own Diagnosis, Implementation Plan a… scripts/writeback-candidates.py:105 regression In-scope fix
30 MEDIUM --body-file private-path gate applies to every mode and to idd-comment correction files, not only to the no-confirm paths — _private_path runs inside validate_body_file_path, which every mode calls, archive --… scripts/idd-edit-helper.py:343` regression In-scope fix
31 MEDIUM idd-edit's new --cwd unattended detection is never fed: no caller passes --cwd — Round 3 changed the unattended check to is_unattended "$(git -C '<CWD>' …)", with <CWD>… skills/idd-edit/SKILL.md:182` regression In-scope fix
32 MEDIUM Normative specs disagree on which privacy hit stops a --correct write — The in-place-correction ADDED requirement says the skill "SHALL discard the target instead… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:25 regression In-scope fix
33 MEDIUM Spectra tier 不經過 idd-plan、idd-implement,comment 觸發在實作期間不存在,偏偏是 #424、#399 這類 issue — 第 3 輪把觸發點改成「idd-diagnose、idd-plan、idd-implement 開始時」(rules/issue-write-back.md:60,sp… rules/issue-write-back.md:60 devils-advocate In-scope fix
34 MEDIUM 截止點的前提「較舊的已經列過」還有兩條路會破:Step 1.1 exit 1 照樣往下,以及跨日的階段 — writeback-candidates.py 的 docstring(第 13–15 行)認為:三種 stage comment 都由跑這支 script 的 skill 貼… scripts/writeback-candidates.py:13 devils-advocate In-scope fix
35 MEDIUM 第 3 輪在 idd-update Step 3 加的作者過濾範圍過大:外部回報者的回覆從 Current Status 完全消失,等待回覆的 Blocking 清不掉 — skills/idd-update/SKILL.md:156 改成「只採 OWNER、MEMBER、COLLABORATOR 與你自己寫的 comment」,範圍是 Step 3 … skills/idd-update/SKILL.md:156 devils-advocate In-scope fix
36 MEDIUM 「listed 進 Blocking、等人決定」在機械上不成立:準則列的值 Section 欄不會出現,解除條件也分不出是人還是 AI — idd-update:171、idd-diagnose:813、idd-reorganize:116 與 spec〈A correction left for a person S… skills/idd-update/SKILL.md:171 devils-advocate In-scope fix
37 MEDIUM 更正:截止點 updated_at 的問題應為 HIGH(security 判 LOW 偏低),而且測試 B 把這個缺陷當成正確行為鎖住 — security 把「截止點用自己 stage comment 的 updated_at」判為 LOW,logic 判為 HIGH。依證據應採 HIGH:scripts/tests… scripts/tests/writeback-candidates/test.sh:81 devils-advocate In-scope fix
38 MEDIUM verify 標成「要人決定」的 Blocking,可以被 unattended auto-fix 把 code 改成符合有爭議的 Expected 而消掉 — regression 已經指出這類 finding 會進 idd-all 的 auto-fix 迴圈。補上後果:skills/idd-all/SKILL.md 的 auto-fix… skills/idd-verify/SKILL.md:1236 devils-advocate In-scope fix
39 LOW idd-comment points to an explanation in issue-write-back.md that round 3 deleted skills/idd-comment/SKILL.md:383 requirements In-scope fix
40 LOW Your own GitHub comments never trigger write-back; Clarity row 1 says anyone's do, and no decision records the change rules/issue-write-back.md:62 requirements In-scope fix
41 LOW The verify Step 2.9 comparison relies on a shell function defined in a different Bash call skills/idd-verify/SKILL.md:1214 requirements In-scope fix
42 LOW Small stale or inaccurate text: a duplicated clause in CLAUDE.md, and a checked task that claims a full-suite pass CLAUDE.md:58 requirements In-scope fix
43 LOW req_state 的 Diagnosis 判定與 gate、writeback-candidates 三者不一致,可能漏偵測 skills/idd-verify/SKILL.md:820 logic In-scope fix
44 LOW append-vs-modify §8 (a) 說只有 enforce 命中才捨棄,和 idd-edit Step 3 與 spec 矛盾 rules/append-vs-modify.md:129 logic In-scope fix
45 LOW Applied Corrections 的 Outcome 封閉列舉和 idd-edit 的實際結果對不上 skills/idd-diagnose/SKILL.md:809 logic In-scope fix
46 LOW idd-edit Step 3:第 4 點捨棄之後沒說要跳過第 5、6 點,會重複 discard skills/idd-edit/SKILL.md:188 logic In-scope fix
47 LOW idd-plan Step 1.1 寫回後沒有要求重新跑 Step 1 的 gate、重讀 Diagnosis skills/idd-plan/SKILL.md:142 logic In-scope fix
48 LOW 三個讀取點的信任定義不一致:idd-update 與 gate 接受帶 MEMBER/COLLABORATOR 的 bot skills/idd-update/SKILL.md:156 logic In-scope fix
49 LOW 截止點用自己 stage comment 的 updated_at,之後任何編輯都會永久藏掉還沒處理的 comment scripts/writeback-candidates.py:108 security In-scope fix
50 LOW 被維護者隱藏的 comment(spam/abuse/off-topic)照樣列出,會被轉述進以維護者名義貼出的報告 scripts/writeback-candidates.py:96 security In-scope fix
51 LOW verify 的需求端基準不分作者,外人的「## Diagnosis」comment 可以遮蔽或偽造「驗證期間被改過」 skills/idd-verify/SKILL.md:823 security In-scope fix
52 LOW 信任過濾只加在 Step 3,Step 2 的 phase 判定仍吃任何人的標題 skills/idd-update/SKILL.md:123 security In-scope fix
53 LOW --note 把來自 GitHub 的自由文字放進指令列,與 --body-file 的理由互相矛盾 rules/issue-write-back.md:44 security In-scope fix
54 LOW SessionStart 的 heredoc 改成不加引號;fallback 的 cd 在 CDPATH 下會多印一行 hooks/session-start-commit-rule.sh:14 security In-scope fix
55 LOW design.md D5 仍寫 idd-update 跑候選清單,正是第 2 輪 HIGH 移除的觸發 openspec/changes/issue-write-back/design.md:53 security In-scope fix
56 LOW verify 報告的註記目標取自 comment 裡的連結,--repo 與作者都只靠模型 rules/issue-write-back.md:101 security In-scope fix
57 LOW verify req_state is a shell function reused in a later Bash call; it falls outside allowed-tools and hashes Current Status skills/idd-verify/SKILL.md:820 regression In-scope fix
58 LOW Round 1/2 behaviour still described in the change's design, proposal and rules openspec/changes/issue-write-back/design.md:53 regression In-scope fix
59 LOW idd-update trusts comment authors for Step 3 only; Step 2 phase detection still reads every comment skills/idd-update/SKILL.md:156 regression In-scope fix
60 LOW 呼叫者自己沒有 stage comment 時,共同維護者的整串歷史(含他的 Diagnosis、Plan、Verify)每個階段都會被列為 TRUSTED 候選 scripts/writeback-candidates.py:102 devils-advocate In-scope fix
61 LOW 可見文字「(AI 判斷)」也蓋在使用者自己執行或口述的更正上,spec scenario 把這個錯誤歸屬寫成規範 scripts/idd-edit-helper.py:1640 devils-advocate In-scope fix
62 LOW 可以砍掉的部分:idd-plan Step 1.1 的 unattended 分支是死碼;verify Step 2.9 的 req_state 不擋 aggregate 又跑不起來 skills/idd-plan/SKILL.md:142 devils-advocate In-scope fix

…he report (#424)

Verify round 3 (PR #469) left five HIGH, all in machinery rounds 2 and 3
added. The maintainer decided two points (comment 6615341615):

- writeback-candidates.py has no time cutoff. The cutoff came from your own
  stage comments' updated_at, which a write-back moves, so comments nobody
  read were hidden for good. Comments not written back are listed under
  ### Comments Not Taken by link and login only.
- Listed corrections stay in the report. idd-update no longer turns them
  into Blocking entries; a re-diagnosis that changed Type blocked idd-all.
  idd-all stops at verified for a person; #392's close gate is asked to
  stop on listed rows (#392 comment 6615342214).

Also from the findings: idd-verify's published-error findings have Action
listed and stay out of the fix loop; idd-diagnose looks at the issue body
again; idd-update reads trusted non-bot authors only and skips Comments Not
Taken, quotes and HTML comments, for phases too; the unrunnable req_state
check is removed; a copied earlier marker is dropped with the earlier line;
the private-path check survives a home path in other case; allowed-tools,
design, proposal and append-vs-modify updated.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 4 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus

Aggregate

FAIL — 0 CRITICAL、6 HIGH、28 MEDIUM、19 LOW

審的是本機 commit 0cee4e6(PR head 仍是 844e8ea)。全套測試 68 個 suite 全過。第 3 輪的截止點與 listed 進 Blocking 已拿掉。

主題

  1. verify 的 PASS/FAIL 取決於「Expected 錯還是 code 錯」(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1、idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5、idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6)。 listed 不算 Blocking 後,這個沒有證據門檻的分類就直接決定能不能過。
  2. 別人的 comment 這條觸發(idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2、idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4)。 沒有截止點後,寫回過又被你在 session 推翻的決定會再被寫回一次;受信任作者「採用某人的做法」時,寫進去的是那人之後還能改的文字。
  3. 列出的項目夾帶外人的主張(idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3、docs: spec 出 #27 fail-fast 訊息實際長相 (sister from #26) #32)。 listed 列與 verify finding 會轉述外人的話,idd-update 再把它讀進 Current Status;「別人的回覆可解除 Blocking」讓任何帳號都能放行 gate。
  4. 自動更正改的是剛被取代的舊 Diagnosis(docs: marketplace lookup hint + 對照表 — fix #26 placeholder UX gap #33)。 每次重新診斷都貼新的一則,Step 3.8 改舊的那則,改完反而自相矛盾。

Devil's Advocate 的結論:D4 經兩輪縮窄後,剩下的自動更正只有負面效果,可以整塊砍掉(#33)。

Findings

# Severity Finding Source
1 HIGH Spec scenario makes every code-vs-Expected difference a non-blocking listed finding — Round 4 changed the scenario 'Verify does not move its own acceptance criteria' to: WHEN /idd-verify finds that the code differs from ## Expected, or that the Diagnosis is wrong, THEN '...the difference SHALL be a finding whose Action i… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:66 requirements
2 HIGH With no cutoff, a TRUSTED decision that was written back and later reversed in a session gets written back again without asking — Three rules combine here. (1) writeback-candidates.py now lists every comment by someone else at every start of diagnose, plan or implement, whatever its age (rule L63, spec 'Write-back SHALL be triggered…'). (2) Step 1.1 in idd-diagnose … rules/issue-write-back.md:63 logic
3 HIGH Listed rows and listed verify findings still carry outsiders' claims into your own comments, and idd-update reads them into Key Decisions, Scope Changes and Blocking — Round 4 closed this path for ### Comments Not Taken (link and login only), but the same path is still open through two other carriers. (1) idd-diagnose Step 3.8 (L786) and idd-reorganize Step 3.5 (L89) say that a claim from "別人的 comment" … skills/idd-update/SKILL.md:156 security
4 HIGH A trusted decision that adopts an outsider's comment by reference writes the outsider's current, editable text with no confirmation — What counts as a change, category 2 (L14): a trusted author's comment that 「明說某件事定了」. The trust table (L65-69) treats only > lines and HTML comments as other people's words. Nothing covers a trusted decision whose content lives somewhere … rules/issue-write-back.md:14 security
5 HIGH Spec turns 'code differs from ## Expected' into a non-blocking listed finding, so a requirements violation can pass verify — The scenario 'Verify does not move its own acceptance criteria' (spec.md:66-69) says: WHEN /idd-verify finds that the code differs from ## Expected THEN the difference SHALL be a finding whose Action is listed. The requirement above i… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:66 regression
6 HIGH 更正兼補充:verify 的 PASS/FAIL 現在取決於「是 Expected 錯還是 code 錯」這個沒有證據門檻的判斷;只改 spec scenario 修不好 — requirements 與 regression 都把這個 HIGH 定位在 spec scenario 的 WHEN 子句(in-place-correction/spec.md:66-69,「code differs from ## Expected」→ listed)。就實際執行的文字而言,這個定位偏大:idd-verify SKILL.md:1219 明寫「code 寫壞是一般的 finding,不在這裡」。真正的缺陷更深一層,改掉 WHEN 子句也修不好。 第 3… skills/idd-verify/SKILL.md:1224 devils-advocate
7 MEDIUM Skipping a candidate by comment identity misses later edits to the same comment — Codex (gpt-6.1-sol, blind cross-model pass) rated this P2 (medium). Its finding,… rules/issue-write-back.md:63 codex
8 MEDIUM idd-verify Step 5a and the Aggregate line do not include the new listed Action — Step 3.5 (L1224) adds a fourth Action, listed. Step 5a (L1399-1407) still says… skills/idd-verify/SKILL.md:1399 requirements
9 MEDIUM Nothing points the person who is meant to read the report to the listed rows; idd-all's final report says 'Next: merge' — Decision 6615341615: 'idd-all 目前一律停在 verified,由人看報告'. The stop holds: idd-all on… skills/idd-all/SKILL.md:1149 requirements
10 MEDIUM The claim '#392's close gate stops on listed' is not true of #392's implementation, and nothing in #424 pins it — idd-verify:1224, idd-diagnose:813, idd-reorganize:116, rules/issue-write-back.md… skills/idd-diagnose/SKILL.md:813 requirements
11 MEDIUM idd-update can still put listed rows into Blocking through a generic bullet, and the test forbids writing the exclusion — The spec (issue-write-back spec.md:117) says 'idd-update SHALL NOT turn liste… skills/idd-update/SKILL.md:170` requirements
12 MEDIUM idd-update skips 'HTML comments', which removes the errata markers it must honour — Step 3 (L156) says: '這些 comment 裡的 ### Comments Not Taken、引用(> 開頭的行)與 HTML 註… skills/idd-update/SKILL.md:156 requirements
13 MEDIUM Skipping comments 'already listed in Comments Not Taken' loses comments edited after listing, which the decision did not ask for — Decision 6615341615 says '每次列出全部別人的 comment,已經反映過的由 AI 跳過'. The rule (L63), the … rules/issue-write-back.md:63 requirements
14 MEDIUM Privacy scenario 'at any privacy level' contradicts the light rule in the requirement it belongs to — Scenario 'Privacy review holds the target back': WHEN the preview 'contains an u… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:42 requirements
15 MEDIUM design.md D9 says verify errors in Expected, Type and Complexity are Blocking; Goals and D4 still say detection skills apply corrections — D9 (L68) still says '## Expected、範圍、checklist、Type、Complexity 的錯誤是 Blocking', … openspec/changes/issue-write-back/design.md:68 requirements
16 MEDIUM proposal.md still says idd-update runs the candidates script and verify applies corrections — L14: '新增 scripts/writeback-candidates.py,idd-diagnose、idd-plan、idd-update… openspec/changes/issue-write-back/proposal.md:14` requirements
17 MEDIUM Skipping by comment id means a comment edited after it was listed is never read again — The script prints only <label> <id> <login> <assoc>. Step 1.1 in the three ski… scripts/writeback-candidates.py:91 logic
18 MEDIUM Step 1.1 does not list every TRUSTED comment that is not written back; refused or held write-backs repeat at every stage, and failed checks are silent — Step 1.1 (diagnose L228, the same text in plan and implement) defines what goes … skills/idd-diagnose/SKILL.md:228 logic
19 MEDIUM verify's new listed Action has no place in Step 5a, the Aggregate line, Step 5c or idd-update's 'verify findings' Blocking bullet — Step 3.5 (L1224) adds a fourth Action value, listed. Step 5a (L1401) still say… skills/idd-verify/SKILL.md:1401 logic
20 MEDIUM idd-all's unattended follow-up auto-filing ('every P3/follow-up finding') also files listed findings as new issues — idd-verify Step 3.5 says a listed finding 'needs a human, is neither Blocking … skills/idd-all/SKILL.md:1006 logic
21 MEDIUM idd-update Step 3 and its spec say to skip HTML comments, but errata markers are HTML comments — The same paragraph says 'errata 標記也只在作者是這幾類時生效' and then 'these comments' ### C… skills/idd-update/SKILL.md:156` logic
22 MEDIUM idd-edit's unattended detection uses a path the callers never pass, so it can ask questions inside an unattended idd-all run — Step 3 point 3 sets <CWD> to the value of --cwd, or . when none is given, … skills/idd-edit/SKILL.md:182 logic
23 MEDIUM The private-path rules still miss obvious secret or private text and refuse ordinary repo files in every mode — The code comment states the requirement: '--correct no longer stops for a person… scripts/idd-edit-helper.py:230 logic
24 MEDIUM idd-plan and idd-implement Step 1.1 now load every outsider's comment body into the agent that implements and writes without confirmation — Before #424, idd-plan and idd-implement deliberately read comments only through … skills/idd-implement/SKILL.md:362 security
25 MEDIUM The no-confirm --correct path still accepts any file under home that the blacklist misses, and honours the model-settable escape hatch — I ran validate_body_file_path with python3 -I -B against the tree at 0cee4e6… scripts/idd-edit-helper.py:236 security
26 MEDIUM listed is not among verify Step 5a's three closed classes, so a disputed Expected can still be classed Blocking and auto-fixed — Step 3.5 (L1224) now gives published-error findings the Action listed. It says… skills/idd-verify/SKILL.md:1401 security
27 MEDIUM listed is a fourth Action that Step 5a, 5c, the Aggregate line and idd-all's report do not know about — Step 3.5 (line 1224) adds the Action listed. Step 5a still says '合併後的每個 findin… skills/idd-verify/SKILL.md:1401 regression
28 MEDIUM idd-update is told to skip HTML comments, but errata detection depends on the errata HTML marker — Step 3 now says: 'errata 標記也只在作者是這幾類時生效。這些 comment 裡的 ### Comments Not Taken、引… skills/idd-update/SKILL.md:156 regression
29 MEDIUM Comments from outside reporters can no longer inform a Diagnosis, a regression for public-repo bug reports — For authors other than OWNER, MEMBER and COLLABORATOR (NONE, CONTRIBUTOR, bot), … rules/issue-write-back.md:70 regression
30 MEDIUM With no cutoff, every comment from another trusted account, its IDD stage records included, is a candidate at every stage — The script now prints every comment not written by the invoking login, whatever … scripts/writeback-candidates.py:76 regression
31 MEDIUM The new private-path gate refuses ordinary repo files in every /idd-edit mode, while the AI write-back path it targets never reaches it — _private_path runs inside validate_body_file_path. That check runs for every… scripts/idd-edit-helper.py:346 regression
32 MEDIUM idd-update 新增「別人的回覆可解除 Blocking」:任何帳號(NONE)都能改 issue 正文的 ### Blocking,直接放行 unattended idd-all 的 actionability gate,與同一份 spec 的信任邊界矛盾 — 第 4 輪在 idd-update Step 3(SKILL.md:156)加了一句「別人的回覆可以讓「等待他回覆」的 Blocking 解除,但不加別的內容」… skills/idd-update/SKILL.md:156 devils-advocate
33 MEDIUM 前提攻擊:idd-diagnose Step 3.8 的自動更正改的是同一次執行剛被取代的舊 Diagnosis,改完反而自相矛盾;#424 要消除的 append 路徑(重新診斷)原封不動,verify 還把人導向它 — idd-diagnose Step 3(SKILL.md:326-328)每次都貼出一則新的 Diagnosis。Step 3.8 的目標是「本 skill 讀… skills/idd-diagnose/SKILL.md:817 devils-advocate
34 MEDIUM 第 4 輪替維護者「接受」了兩項已知限制(Spectra tier 實作期間看不到 comment、verify 期間的需求變動不再比對),沒有維護者決定 — design.md:53(D5)與 rules/issue-write-back.md:63 新增「Spectra tier 的實作走 spectra-appl… openspec/changes/issue-write-back/design.md:53 devils-advocate
35 LOW Scenario 'Diagnose finds the Expected wrong' is attached to the idd-update requirement openspec/changes/issue-write-back/specs/in-place-correction/spec.md:188 requirements
36 LOW Small spec and doc drift: visible-line requirement, Comments Not Taken by mode, trust wording openspec/changes/issue-write-back/specs/issue-write-back/spec.md:84 requirements
37 LOW tasks.md marks a full-suite pass that has not finished, and keeps checked tasks whose behaviour round 4 removed openspec/changes/issue-write-back/tasks.md:45 requirements
38 LOW Published #424 content is stale; under the new Step 3.5 these would be listed requirements
39 LOW run-start's trailing pop recognises only the correct marker; a carried IDD marker leaves the old visible line in place, and the empty check can be passed scripts/idd-edit-helper.py:2252 logic
40 LOW Step 3.8 does not say whose ### Type decides a re-diagnosis that changes the type skills/idd-diagnose/SKILL.md:782 logic
41 LOW After implementation, the premise-overturn exclusion leaves verify's redirect and idd-reorganize's correction step list-only skills/idd-verify/SKILL.md:1225 logic
42 LOW design.md D9 and the Goals, and tasks.md 6.1, 6.3 and 6.4, still describe superseded behaviour openspec/changes/issue-write-back/design.md:68 logic
43 LOW --note travels on the command line through two quoting layers, with text that may come from GitHub skills/idd-diagnose/SKILL.md:792 security
44 LOW Skipping comments 'already listed in Comments Not Taken' is not limited to your own comments skills/idd-diagnose/SKILL.md:228 security
45 LOW idd-update Step 2 filters phase headings by author but does not skip quoted lines or HTML comments, which the spec requires skills/idd-update/SKILL.md:110 security
46 LOW The new author filter on phase detection diverges from idd-list's fallback and drops IDD comments posted by non-O/M/C identities skills/idd-update/SKILL.md:110 regression
47 LOW idd-edit now runs inside unattended diagnose, but its unattended check and allowed-tools do not cover that path skills/idd-edit/SKILL.md:182 regression
48 LOW Proposal, design, tasks and a test header still describe round 1–3 behaviour openspec/changes/issue-write-back/proposal.md:14 regression
49 LOW Re-running /idd-diagnose to fix a published fact moves a verified issue back to diagnosed skills/idd-verify/SKILL.md:1225 regression
50 LOW Attended idd-reorganize loses main's per-item 'correct now?' for Strategy, Expected and Plan errors skills/idd-reorganize/SKILL.md:2406 regression
51 LOW 第 3 輪 #18 的 allowed-tools 只修了一半:寫回規定要 mktemp -d 並在結束後刪目錄,diagnose、plan、implement 都沒有 Bash(mktemp:) 與 Bash(rm:) skills/idd-diagnose/SKILL.md:790 devils-advocate
52 LOW verify Step 3.5 第 4 輪新加的文字叫人去「重跑 /idd-diagnose」,違反 dev 規則 human-vs-claude-skills 的寫 skill 規定 1、2 skills/idd-verify/SKILL.md:1225 devils-advocate
53 LOW Step 3.8 的觸發從「先前的 Diagnosis」擴大到「issue 正文或既有 comment」,超出第 3 輪 #2 的需要;沒有去重,idd-all 每跑一次就重列一次,attended 也重問一次 errata skills/idd-diagnose/SKILL.md:780 devils-advocate

…-correct (#424)

Four verify rounds failed without converging, and every HIGH was in two
parts added for #424: other people's comments triggering write-back, and
detecting skills correcting published text on their own. The core (a
change the user decides in a session is written back by kind) was never
hit. The maintainer cut both parts (comment 6616229678):

- Someone else's comment no longer triggers anything. It counts only when
  the user raises it in a session and decides to adopt it.
  writeback-candidates.py, its tests, the trust table, Comments Not Taken
  and the idd-update author filter are gone; idd-update, idd-plan and
  idd-implement are back to main.
- idd-verify, idd-diagnose and idd-reorganize are back to the 3.6.0
  proposal flow (Proposed Corrections, asked when attended, listed only
  when unattended). The one change kept: after the user chooses "run now",
  /idd-edit --correct shows its preview and writes without a second
  question.
- idd-diagnose Stage 1 still rewrites its own Diagnosis instead of
  appending a correction comment.

Kept: decided session write-back, --correct without confirmation, the
visible line (--note), no questions in unattended mode, the private-path
rules, the Residue reader. Rule, specs, design, proposal, tasks group 8,
CHANGELOG 3.7.0, READMEs, plugin.json and marketplace rewritten to match;
the hook line says other people's comments do not trigger.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 5 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus

Aggregate

FAIL — 0 CRITICAL、3 HIGH、17 MEDIUM、24 LOW、4 INFO

審的是本機 commit 353f686(PR head 仍是 844e8ea)。全套測試 67 個 suite 全過。維護者 2026-11-04 的決定(#424 comment 6616229678,兩塊都砍)其餘處都成立,第 4 輪的 6 個 HIGH 全部隨砍除消失(#46)。

主題

  1. 砍掉的自動更正還留在 rules/append-vs-modify.md §8(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1–idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3,三個 HIGH 是同一處)。 那一段仍寫「其他 skill 呼叫指令並列在 ### Applied Corrections」,與同檔、spec、三個偵測 skill 矛盾;issue-write-back 測試第 96 行把 main 的正確寫法擋掉。同類殘留:main spec 的 Purpose(idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6、[test] idd-list cluster algorithm + footer rule + state matrix 沒被任何 production data 跑過 (verify follow-up from #13) #18)、tasks.md(idd-all Phase 5: PR body heredoc 改 quoted (預防未來 RCE) #7、cluster: #27 source-type adapter fail-fast + #34 generic plugin-presence helper (Plan tier) #39)、測試與 helper 註解(feat(idd-issue): bundle flags — --parent / --blocked-by / --bundle-mode for ordered/unordered issue bundles #21、feat(idd-list): markdown-aware fence strip + cluster_leader config (cluster #14 #15) #43)。
  2. 「現在執行」當確認,但那一題看不到要寫的文字,重建的指令也沒帶 --repo(idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9、idd-all Examples: 跨 repo invocation 段重複描述,合併 #10、feature: /idd-all (無參數) bulk-solve mode — AI 自動 sequence + bundle 所有 open issue #37)。
  3. 私人路徑閘:漏的多、誤擋的也多(idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5、idd-list 應該顯示引用 issue 的 open PR 資訊 #13、[enhancement] idd-list Step 5: planning + has PR 應勸 user 處理 stale/zombie PR (verify follow-up from #13) #17、[refactor] idd-list regex #(\d+) 應加 \d{1,7} 上限 + 過濾 #0 (verify follow-up from #13, related #14) #19)。 Devil's Advocate 認為這塊保護不到任何不問的路徑,最小形式是拿掉或只在 --correct 檢查(feature: /idd-all chain-solve mode — 自動接續解 spawned issues + 單 review PR #44)。
  4. 在 session 採納別人的 comment,寫進去的可能是對方之後改過的文字([enhancement] idd-list cluster_leader config (lowest | primary) (sister concern from #13) #15);隱私自審沒有列出 credential([refactor] idd-list Step 5: needs-fix × PR state matrix 應展開,不該摺疊成單行 (verify follow-up from #13) #16)。
  5. 前提攻擊([refactor] idd-list footer direct-commit count 應排除 closed phase issue (verify follow-up from #13) #20):實作之後定案的設計改變被規則送去 idd-reorganize,結果又是追加一則新 Diagnosis,bug: idd-close Step 1.55 flags squash-merged commits whose lines a later branch commit rewrote #399 這個起因案例沒有被解決。
  6. 其他: SessionStart 那一行的「你」會被模型讀成自己(Complexity routing: vagueness 應該是一階信號,但目前 4 層 gate 都沒衡量需求清晰度 #12);--prepend-note 的嚴格作者檢查只在 skill 文字裡([refactor] idd-list PR body parsing: ignore #N inside fenced code blocks (sister concern from #13) #14);unattended 分支砍完後沒有呼叫端(docs: explicit plugin-presence trust model (#41) #42);每份 verify 報告都加註記會把首行擠下去,也太多(idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4、feature: /idd-all chain-solve mode — 自動接續解 spawned issues + 單 review PR #44)。

Findings

# Severity Finding Source
1 HIGH canonical 分類規則仍要求偵測 skill 自動套用更正(D4 殘留),與撤回決策衝突 — Codex [P1/高]:### 8. in-place-correction 的 Scope boundary 仍寫 "other skills reach it by invoking the command and reporting the result under ### Appli… rules/append-vs-modify.md` codex
2 HIGH append-vs-modify still describes the cut automatic correction (Applied Corrections, D4), and a test now blocks main's correct wording — Decision 6616229678 sends idd-verify, idd-diagnose and idd-reorganize back to the 3.6.0 proposal flow. The shipped plugin rule still says the opposite… rules/append-vs-modify.md:129 requirements
3 HIGH append-vs-modify rule still says other skills apply corrections and report them under ### Applied Corrections, and a test locks this in — §8 Scope boundary (L129) ends: "other skills reach it by invoking the command and reporting the result under ### Applied Corrections (#424 D4)". Tha… rules/append-vs-modify.md:129 regression
4 MEDIUM verify 報告一律 --prepend-note,會把 ATX 標題/IDD marker 推離首行,與 idd-comment 的首行防護矛盾 — Codex [P2/中]:issue-write-back.md「診斷更正後,連帶更新依賴它的紀錄」的 verify 報告條目,以及 skills/idd-diagnose/SKILL.md Stage 1 新增的連帶更新要求,規定每份自己的 verify 報告都執行 --prepend-… rules/issue-write-back.md` codex
5 MEDIUM 使用者暫存目錄豁免一併跳過敏感檔名檢查(.env、id_rsa、*.pem、credential) — Codex [P2/中]:validate_body_file_path() 新增的判斷 if not in_user_tmp and _private_path(path): 中,_private_path() 同時負責「家目錄私人路徑」與「任何位置的敏感檔名」兩種檢查,此條件把兩者一… scripts/idd-edit-helper.py codex
6 MEDIUM Canonical in-place-correction spec Purpose was edited directly and still says other skills may apply corrections themselves — The diff edits the canonical spec directly, not through the change's delta. The Purpose now ends "It also fixes which regions can never be corrected a… openspec/specs/in-place-correction/spec.md:5 requirements
7 MEDIUM tasks.md: checked tasks still state the comment trigger and auto-correction as done, with verification claims false at 353f686 — The brief requires that no comment trigger or automatic correction is left in tasks. Several items are still marked [x] with acceptance that does no… openspec/changes/issue-write-back/tasks.md:4 requirements
8 MEDIUM --correct requirement says 'apply without asking' unconditionally; its own scenario and the code ask when SCRUB=enforce — The ADDED requirement "/idd-edit --correct SHALL replace a bounded region after reporting the preview" says the skill "SHALL show the diff … and then … openspec/changes/issue-write-back/specs/in-place-correction/spec.md:19 requirements
9 MEDIUM The run-now answer that now counts as confirmation is given before any diff or preview exists — Decision 6616229678 makes the user's "run now" the confirmation, and /idd-edit --correct no longer asks again. In all three detecting skills (idd-veri… skills/idd-verify/SKILL.md:1233 logic
10 MEDIUM Run-now rebuilds /idd-edit arguments without --repo; in a cross-repo run an issue: target can rewrite the wrong issue with no question — The rule says 「一律帶 --repo:拿掉確認之後,指錯 repo 就沒有最後一道檢查」 (rules/issue-write-back.md), and the Stage 1 bullet does pass --repo. The proposal tables restor… skills/idd-diagnose/SKILL.md:774 logic
11 MEDIUM The cut D4 auto-correct is still normative in append-vs-modify and the main spec Purpose, and a test locks it in — Decision 6616229678 does not hold in the shipped rule. Line 127 still defines in-place-correction as content found wrong 「by the AI … in a skill that … rules/append-vs-modify.md:127 logic
12 MEDIUM The SessionStart line says the change you decide, but its reader is the model, which inverts the decided-by-the-user gate — The hook output goes to the model, which then reads 「你明確定案的改變就地寫回、不先問」 with itself as 你. The rule (and decision 6600258374 item 3) requires 「只有**使用者在 … hooks/session-start-commit-rule.sh:19 logic
13 MEDIUM The private-path rules still let obvious secret and history files through, and refuse ordinary repo files in every mode — I ran validate_body_file_path at 353f686 with the real HOME and no escape hatch. Allowed: ~/.zsh_sessions/.history (macOS per-session zsh histor… scripts/idd-edit-helper.py:230 logic
14 MEDIUM --prepend-note skips the question on a strict author check that only the skill's prose runs; the helper's own gate still lets the OWNER's and a bot's comments through — D1b (design.md) and the spec requirement '/idd-edit --prepend-note SHALL skip confirmation only for the invoking user's own content' rest on validate… skills/idd-edit/SKILL.md:184` security
15 MEDIUM Adopting someone else's comment in a session writes that comment's current text with no question, and the text the AI fetches may not be the text the user read — L15 and spec 'Decided discussion changes SHALL be written back by kind' say a comment by someone else counts once the user raises it in a session and … rules/issue-write-back.md:15 security
16 MEDIUM The write-back privacy review never names credentials, and at light its closed wording makes a token in the added text not a hit — With the confirmation gone, the semantic review is the only check on content in the no-question --correct, --prepend-note and kind-3 paths (design… rules/issue-write-back.md:73 security
17 MEDIUM Round 4 #25 is still open: the --body-file private-path gate accepts common secret files, and the escape hatch the rule forbids can be set inline — The helper is unchanged in round 5's delta. The comment at L224-229 states the requirement: 'a wrong path would publish it with nobody looking; the ga… scripts/idd-edit-helper.py:230 security
18 MEDIUM Canonical in-place-correction spec Purpose edited directly to describe skills applying corrections themselves — The change edits the canonical spec in place, outside its delta: "It also fixes which regions can never be corrected and which corrections other IDD s… openspec/specs/in-place-correction/spec.md:5 regression
19 MEDIUM New private-path rules refuse ordinary files in every /idd-edit mode, including modes that still ask — _private_path runs inside validate_body_file_path, which every mode's --body-file and archive --from-file pass through. _PRIVATE_NAME_RE mat… scripts/idd-edit-helper.py:346 regression
20 MEDIUM 前提攻擊:#424 的動機案例(#399)被規則送回 append 路徑;實作後定案的設計改變沒有合理去處 — 規則 L85 與 spec issue-write-back〈A corrected diagnosis…〉最後一句的寫法是:實作之後(phase ≥ implemented),這次更正讓既有實作的前提不成立,「或問題本身改變了」,就不改文字、改呼叫 idd-reorganize。只有「敘述寫錯、實… rules/issue-write-back.md:85 devils-advocate
21 LOW Leftover references to the cut parts in test and helper comments — Three comments still refer to the cut parts: - issue-write-back/test.sh:8: "the Applied Corrections blocks in scripts/tests/in-place-correction". Th… scripts/tests/issue-write-back/test.sh:8 requirements
22 LOW #424's own Diagnosis and Current Status still describe the cut parts; the decided cut was not written back — The kept rule says a decided diagnosis change goes to the Diagnosis section via --correct. For #424 itself: - Diagnosis comment 6388200931 still has… requirements
23 LOW The visible line always says 'AI 判斷', and the run-now path writes it without a reason — run-start adds _更正於 YYYY-MM-DD(AI 判斷)…_ to every --correct. That includes corrections a person asked for: idd-comment errata on the user's own c… scripts/idd-edit-helper.py:998 requirements
24 LOW '不再問第二次' is stated unconditionally, but /idd-edit still asks on SCRUB=enforce, a privacy hit or FLOOR=272 — The three detecting skills ("/idd-edit --correct 顯示預覽後直接寫入,不再問第二次(這一題就是確認)"), the rule (line 91), the CHANGELOG and the spec scenario "Attended diag… rules/issue-write-back.md:91 requirements
25 LOW Round-4 #51 still applies to the kept Stage 1 path: idd-diagnose allowed-tools lacks what --correct write-back needs — Stage 1 (line 794) now calls /idd-edit … --correct --body-file <檔> --note … and follows rules/issue-write-back.md. That rule requires Write into a … skills/idd-diagnose/SKILL.md:10` requirements
26 LOW run-start removes an earlier visible line only at the very end, and its empty check knows only the correct-mode marker — I reproduced this with the fake gh. A whole-comment correction ('right is right'), then an --append, then a second whole-comment correction whose repl… scripts/idd-edit-helper.py:2252 logic
27 LOW The visible line says (AI 判斷) on every --correct, including corrections the user wrote or confirmed — _correct_note_line hard-codes (AI 判斷). The helper applies it to every --correct path: idd-comment errata with the user's own --correction-file, a us… scripts/idd-edit-helper.py:1646 logic
28 LOW Gaps in the dependent updates: a re-diagnose touches the superseded records, and Spectra-tier artifacts are not covered before implementation — (a) Stage 1's 「這張 issue 已有 Implementation Plan 或 verify 報告時」 only happens on a re-diagnose, because each diagnose posts a new Diagnosis comment. Those… skills/idd-diagnose/SKILL.md:794 logic
29 LOW In unattended mode the PICK question is still asked, contrary to 'SHALL NOT ask questions in unattended mode' — Step 1's PICK=#N branch asks the user to choose a comment with AskUserQuestion. The unattended check (UNATTENDED=) runs only in Step 3, after prep… skills/idd-edit/SKILL.md:156 logic
30 LOW allowed-tools do not cover the new Stage 1 path or idd-edit's unattended block — The Stage 1 bullet now needs Write (for the body file), Skill (to call idd-edit), and the rule's mktemp -d and cleanup. idd-diagnose's allowed-tools… skills/idd-diagnose/SKILL.md:794 logic
31 LOW Kind-3 write-backs send AI-composed, possibly third-party-derived text through /idd-comment --body, which idd-comment stages through a shell variable — For --correct the rule requires the replacement to go through a Write-tool file and --body-file, 「不把文字貼進指令」 (L39). For kind 3 it prescribes /idd-… rules/issue-write-back.md:27` security
32 LOW The rule does not say which comment is 'the Diagnosis'; a Diagnosis-shaped comment by someone else diverts the write-back into a public errata, and a superseded Diagnosis of your own can be rewritten — Kind 2 targets comment:<Diagnosis id> (L26, spec Example) with no selection rule: not 'your latest comment carrying the Diagnosis marker', and not t… rules/issue-write-back.md:26 security
33 LOW <CWD> is pasted into single quotes in idd-edit's unattended check with no shape check and no '\'' rule — The new block runs is_unattended "$(git -C '<CWD>' rev-parse --show-toplevel 2>/dev/null || echo '<CWD>')", where <CWD> is the raw --cwd value… skills/idd-edit/SKILL.md:196 security
34 LOW The helper's R5 refusal tells the agent to gh auth switch and run again, which conflicts with the rule's errata route on a question-free path — On a --correct refusal the helper prints 'If you wrote it under another GitHub account, switch to it (gh auth switch) and run again'. That advice … scripts/idd-edit-helper.py:788 security
35 LOW A second whole-comment correction of an own IDD comment leaves two visible lines, the old one stating the replaced value — Reproduced with the correct-flow fake gh. Comment 500 is ## Decision / we chose A / <!-- idd:comment type=decision … -->. Step 1: --correct --scope… scripts/idd-edit-helper.py:2252` regression
36 LOW SessionStart hook switched to an unquoted heredoc; every future edit is now shell-expanded at each session start — cat <<'RULES' became cat <<RULES so that ${ROOT} would expand. The other four lines are now expanded too. A backtick span, which this repo uses … hooks/session-start-commit-rule.sh:14 regression
37 LOW Detecting skills' run-now path no longer gets a second confirmation, but its rebuilt command still carries neither --repo nor --note — In 3.6.0, the preview and confirm inside /idd-edit was where a wrong target or repo got caught. Now "run now" is the only check (decision 6616229678).… skills/idd-verify/SKILL.md:1233 regression
38 LOW idd-issue multi-finding 'edit body' is another --correct caller that now writes without the text being seen; not listed among affected flows — Step 2d's "edit body" option sends a wrong body on the user's own issue to /idd-edit issue:<N> --correct --section …. In 3.6.0, idd-edit's per-targe… skills/idd-issue/SKILL.md:1559 regression
39 LOW tasks.md and the new test still describe the removed parts — These tasks are still checked [x] and describe behavior the tree no longer has. 1.1: two triggers, with issue comments under D5. 1.2: tests asserting … openspec/changes/issue-write-back/tasks.md:11 regression
40 LOW 更正 logic 的 MEDIUM(run now 的回答發生在任何預覽之前):前提不成立;真正的缺口在
Details 的替換內容 — logic 說「run now 的回答發生在任何 diff 或預覽出現之前」,這個前提不成立。三個偵測 skill 都把替換內容附在表下的
,先貼出報告、再逐項問:idd-verify L1227、L1233(「報告貼出後逐項 AskUserQuestion」)、idd-diagn… skills/idd-verify/SKILL.md:1227
devils-advocate
41 LOW 更正 logic 的 MEDIUM(SessionStart 寫「你明確定案」):降為 LOW;但這是第 5 輪自己引入的,同輪還拿掉了「comment 當資料讀」 — 同一行結尾要求「動手前先讀 …/rules/issue-write-back.md」,規則第一節明寫「只有使用者在 session 裡明確定案才算」。所以誤讀會在寫入前被規則改正,不是直接把「由使用者決定」的閘門反轉過來,MEDIUM 偏高。 要補兩點,都是第 5 輪的回歸: (1) 這個「你」是… hooks/session-start-commit-rule.sh:19 devils-advocate
42 LOW 保留的 unattended 分支在砍完之後沒有呼叫端,只會被殘留旗標觸發,讓在場的使用者得到 HELD — 砍完以後,unattended 模式下已經沒有任何流程會呼叫 /idd-edit:idd-all 與 idd-all-chain 都不呼叫 idd-edit 或 idd-comment,偵測 skill 在 unattended 只列不做,idd-diagnose Stage 1 只在 attend… skills/idd-edit/SKILL.md:182 devils-advocate
43 LOW 「(AI 判斷)」與兩段程式註解是被砍的 D4 的殘留:剩下的每一條 --correct 路徑都是人決定或人確認的 — 幾處說法只在 D4(偵測 skill 自動更正)存在時才成立: - 可見文字寫死「AI 判斷」。 - helper _correct_note_line 的註解(L1644)的理由是「since #424 nobody confirms a correction」。 - hooks/archiv… scripts/idd-edit-helper.py:1644 devils-advocate
44 LOW 最小形式:維護者還會砍的兩處(私人路徑閘、對每份 verify 報告疊註記) — (1) _private_path 保護不到任何不問的路徑。規則自己的寫回路徑用 mktemp 放在 TMPDIR 底下,validate_body_file_path L329 判定 in_user_tmp 為真之後,L345 直接跳過私人路徑檢查。偵測 skill 用的 ~/.cache/i… scripts/idd-edit-helper.py:345 devils-advocate
45 INFO cross-model 審閱範圍說明 — Codex 自述:審閱僅依據提供的 diff(353f686 起的整個變更),未實際執行測試。Codex 輸出中未發現任何類似指令或 prompt-injection 的內容。輸出檔已讀取並刪除。 codex
46 INFO Decision 6616229678 otherwise holds; all six round-4 HIGHs are gone with the cut — Checked at 353f686 against main (fe11459): - idd-plan, idd-implement, idd-update, idd-all and idd-list are byte-equal to main. `scripts/writeback-cand… requirements
47 INFO Checked and holding — I ran or traced the following at 353f686 (clone not modified). Suites: edit-run 264/264, in-place-correction 227/227, issue-write-back 78/78, session-… logic
48 INFO Visible line says 'AI 判斷' even for a correction a person runs by hand — run-start always appends _更正於 DATE(AI 判斷)…_ for --correct. That includes the v3.5.0 use where a person runs /idd-edit --correct --body-file my-fi… scripts/idd-edit-helper.py:2258` regression

…d branch (#424)

Verify round 5 failed on one leftover (append-vs-modify §8 still said other
skills apply corrections, and a test locked it in). The maintainer decided
four points after it (comment 6617788666):

- Verify reports get no note after a diagnosis correction (D2 withdrawn);
  --prepend-note asks again, as on main (D1b withdrawn).
- The --body-file private-path gate is gone; main's system and credential
  directory checks stay, and a credential in the added text is a privacy
  hit at every level.
- /idd-edit's unattended branch, discard --reason and finish's HELD are
  gone: no unattended flow calls /idd-edit after the cut.
- A change decided after implementation is written back in place when the
  same pull request carries it; idd-reorganize only when built work is
  thrown away.

Also from the findings: §8, the canonical spec Purpose and the tasks no
longer describe the cut parts; a detecting skill's run-now question shows
the full replacement and its command carries --repo and --note; the hook
line names the user as the one who decides and keeps comments as data; an
adopted comment counts only for the items the user names; the Diagnosis
target is your newest one; Spectra-tier issues take the change through
spectra-ingest; idd-diagnose Stage 1 touches only the Diagnosis it just
posted; every earlier visible line in a replacement is removed and a
replacement of markers only is empty.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 6 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus。Devil's Advocate 第一次跑時撞到用量上限,之後只重跑它,其他 reviewer 的結果從快取重播。

Aggregate

PASS(有 findings) — 0 CRITICAL、0 HIGH、9 MEDIUM、38 LOW、5 INFO

審的是本機 commit f9a7322(PR head 仍是 844e8ea)。commit 後全套測試 67 個 suite 全過。維護者兩次砍除的決定(#424 comment 6616229678、6617788666)都成立(#48–#52)。這是第一輪沒有阻擋級發現;照慣例在同一個 PR 修完再合併。

主題

  1. 前提攻擊(idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9,Devil's Advocate):feat: 討論中持續更新 issue:問題變了改正文、診斷變了改 Diagnosis 留言、補充才新增 comment #424 自己跑了六輪,Diagnosis 與 Current Status 一次都沒寫回,重現 bug: idd-close Step 1.55 flags squash-merged commits whose lines a later branch commit rewrote #399。 規則讓改策略的決定只能歸第 2 類(改 Diagnosis)或第 3 類(decision comment)其一,使用者的原話與理由在第 2 類沒有位置,實作者就一直選第 3 類。
  2. 實作之後的去處(idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2–idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4): idd-reorganize 的入口描述沒對齊「同 PR 就地寫回」;Diagnosis 目標規則會選到被取代的舊一則;「保留已建好的東西、又沒有 PR 承載」的改變沒有去處。
  3. 替換文字的處理(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1、feature: /idd-all chain-solve mode — 自動接續解 spawned issues + 單 review PR #44): 每一行舊可見文字都刪,會誤刪 code fence 範例與其他段落的更正紀錄;Devil's Advocate 建議改成 fail-closed。規則指定的 mktemp 寫回檔在 TMPDIR 不同的兩個呼叫之間會被路徑閘拒絕(feat(idd-list): markdown-aware fence strip + cluster_leader config (cluster #14 #15) #43)。
  4. 其他不問的呼叫端(idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6–idd-all Phase 0.2: GITHUB_REPO post-derive shape assertion #8): 偵測 skill 的固定替換檔路徑、idd-issue 的 edit body、依項目編號採納別人的 comment。
  5. 「(AI 判斷)」(docs: explicit plugin-presence trust model (#41) #42): 砍掉自動更正後,每條 --correct 路徑都是人決定的,這幾個字的前提已不在。

Findings

# Severity Finding Source
1 MEDIUM --correct note-line cleanup deletes any replacement line starting with the note prefix, including body text and code-fence examples — Codex (blind cross-model reviewer, rated P2/medium) flagged the replacement-text cleanup block added to run_start_subcmd(): lines = [l for l in s… scripts/idd-edit-helper.py codex
2 MEDIUM idd-reorganize still claims the post-implementation design change that decision 6617788666 #3 sends to in-place write-back — Decision 6617788666 #3 says a design change decided after implementation is written back in place when the same pull request carries it. idd-reorganiz… skills/idd-reorganize/SKILL.md:27 requirements
3 MEDIUM Diagnosis target rule picks your own older, superseded Diagnosis when someone else posted the newest one — Rule L32 (and spec issue-write-back, Requirement 1: "the Diagnosis being the newest comment that starts with ## Diagnosis and was written by the inv… rules/issue-write-back.md:32 logic
4 MEDIUM After-implementation routing leaves a case with no route: a change no PR carries that keeps the built work — L86 and spec issue-write-back (Requirement 5: "The AI SHALL invoke idd-reorganize instead only when what was built is to be discarded or redone and … rules/issue-write-back.md:86 logic
5 MEDIUM append-vs-modify §8 lists what holds a --correct back but leaves out credentials — §8 Scope boundary (a) says the no-question --correct is held back by "a hit at enforce or warn, newly added third-party verbatim text at light, … rules/append-vs-modify.md:129 logic
6 MEDIUM Run-now replacement file is a fixed, shared path that is never cleaned up, and the run-now path no longer gets a second look — In all three detecting skills (idd-verify L1229, idd-diagnose L782, idd-reorganize L88), the replacement goes to $HOME/.cache/idd/corrections/correct… skills/idd-verify/SKILL.md:1229` security
7 MEDIUM Adopting someone else's comment by item number writes that comment's current, possibly edited text with no question — The rule at L15 and the spec ('what is written SHALL be what the user decided rather than the comment's current text') say the text written comes from… rules/issue-write-back.md:15 security
8 MEDIUM idd-issue's "edit body" rows reach the no-ask --correct without --repo, --note, or the replacement text in the question — In 3.6.0 the preview and the default-NO confirmation inside /idd-edit were the only checks on this caller. This change made the detecting skills' "run… skills/idd-issue/SKILL.md:1559 regression
9 MEDIUM 前提攻擊:第 2 類與第 3 類只能擇一,#424 自己跑了六輪就重現 #399(更正 requirements/regression 的 LOW) — requirements 與 regression 都把「#424 自己的 Diagnosis、Current Status 沒寫回」列為 LOW。這件事其實是本 change 前提唯一一次真實運行的結果,而且它失敗了,所以應升為 MEDIUM。 證據:verify 第 1 到第 5 輪之後,維護… rules/issue-write-back.md:32 devils-advocate
10 LOW tasks.md section 9 does not mark the earlier checked items that the round-5 cut invalidated — Section 8 now opens with a list of earlier items that 'no longer hold'. Section 9 withdraws D1b, D2, the private-path gate and the unattended branch, … openspec/changes/issue-write-back/tasks.md:54 requirements
11 LOW Design, CHANGELOG and rule still say only a trailing earlier visible line is removed; the round-6 helper removes every one — Round 6 (task 9.3) changed run-start to drop every replacement line that starts with '_更正於 ', anywhere in the text ('Every such line, not only a trail… openspec/changes/issue-write-back/design.md:79 requirements
12 LOW append-vs-modify §8 says other skills reach --correct only by proposing it, and its hold list omits credentials — The Scope boundary now ends 'other skills reach it by proposing the command, and the user's "run now" is the confirmation (#424)', and test L96 locks … rules/append-vs-modify.md:129 requirements
13 LOW idd-issue 'edit body' reaches no-ask --correct without the run-now safeguards; only the CHANGELOG covers it — Round 5 #38 is handled only by a CHANGELOG sentence: "idd-issue's multi-finding 'edit body' rows that go to --correct also write after the preview… skills/idd-issue/SKILL.md:1559 requirements
14 LOW idd-edit says AI-written replacement text always lives in a mktemp -d directory; the detecting skills use ~/.cache/idd/corrections — The new 鐵律 bullet reads '--correct 不設 IDD_EDIT_HELPER_ALLOW_UNSAFE_BODY_FILE(#424,它不問):… AI 寫回的替換文字一律放在 mktemp -d 建的目錄。' The run-now path of idd… skills/idd-edit/SKILL.md:299 requirements
15 LOW #424's own Diagnosis and Current Status still describe the cut design, contrary to the rule this PR adds — This is round-5 #22. The implementer defers it to 'before close'. Diagnosis comment 6388200931 still has R1 ('GitHub 上任何人的 comment,都會觸發寫回'), R3 (verif… rules/issue-write-back.md:35 requirements
16 LOW Rule's 為什麼 section says the privacy review stops at every level, contradicting its own L73 — L98 reads '定案門檻、可見文字、隱私自審在任何等級都停,是這四輪留下來的。' L73 of the same file (and the spec, idd-edit Step 3 and design D6) says only 'enforce、warn 命中就停;light… rules/issue-write-back.md:98` requirements
17 LOW Spec makes every write-back carry --note, including kind 3, where /idd-comment has no --note — The requirement 'Decided discussion changes SHALL be written back by kind' ends 'Replacement text SHALL be passed through --body-file …, and every w… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:9 requirements
18 LOW Marker-only refusal moved to run-start with a wrong message and no CHANGELOG line, and it changes idd-comment errata's routing — Round 6 changed what main did with a replacement that holds only IDD markers. Main had prepare refuse it as REASON=empty (exit 4). Now run-start exits… scripts/idd-edit-helper.py:2224 requirements
19 LOW A helper comment and a test comment still describe the cut parts — Round-5 #43 is only partly fixed. archive-read-guard.py went back to main, but the _correct_note_line docstring still says 'since #424 nobody confirms… scripts/idd-edit-helper.py:1606 requirements
20 LOW The new run-now behaviour is stated only in a scenario; the requirement text is unchanged from main — The MODIFIED requirement 'Skills that detect errors SHALL propose corrections, not apply them' has the same body as the canonical spec on main. The be… openspec/changes/issue-write-back/specs/in-place-correction/spec.md:136 requirements
21 LOW Removal of earlier visible lines ignores code fences and silently deletes example text (reproduced) — run-start drops every replacement line that starts with _更正於 , inside a fenced block too (lines = [l for l in ... if not l.startswith(NOTE_LINE_PRE… scripts/idd-edit-helper.py:2215` logic
22 LOW idd-edit Step 3 privacy branches: no action for a credential at light on an asked target, and the redact path ignores --note — Point 4 says credentials 「在任何等級都算命中」. Its "要問的 target" bullet (L185) defines actions only for an enforce hit (redaction diff) and a warn hit (one-… skills/idd-edit/SKILL.md:185 logic
23 LOW idd-edit Next Step cascades to the Implementation Plan after any Diagnosis correction, which contradicts idd-diagnose Stage 1 — idd-edit Next Step (L344): 「改的是 Diagnosis 時,照 rules/issue-write-back.md「診斷更正後,連帶更新」處理 Implementation Plan」. idd-diagnose Stage 1 (L797) calls /idd-edi… skills/idd-edit/SKILL.md:344 logic
24 LOW Docs and change artifacts still describe the round-5 helper and the withdrawn D1b/D2/unattended parts — These places no longer match f9a7322: (1) design.md L79 says 「先移除尾端舊的可見文字與標記」, rule L42 says 「替換文字尾端舊的那行…會被換掉」, and CHANGELOG L30 says "An earlier lin… openspec/changes/issue-write-back/design.md:79 logic
25 LOW After an R5 refusal, the helper tells the agent to gh auth switch and retry; nothing stops this on paths that write without asking — Still open from round 5 #34. When --correct refuses with R5, stderr says 'If you wrote it under another GitHub account, switch to it (gh auth switc… scripts/idd-edit-helper.py:751` security
26 LOW idd-issue multi-finding 'edit body' now writes text taken from an external document that the user never sees — Still open from round 5 #38. Step 2d 'edit body' sends the change to /idd-edit issue:<N> --correct --section .... The user approves only a one-line … skills/idd-issue/SKILL.md:1559 security
27 LOW Write-back comments (the rule's new-comment kind) still pass AI-written text through --body and a shell variable — Still open from round 5 #31. For --correct, the rule forbids pasting the text into a command (L39: 「不把文字貼進指令」). For the new-comment kind, it prescri… rules/issue-write-back.md:27 security
28 LOW The session path requires --repo but does not say where the value comes from; a wrong repo leads to writes without a question — L40 says 一律帶 --repo <owner/repo>, but not where the value comes from when no skill is running. The detecting skills say 「本 skill 解析出的」. If the value… rules/issue-write-back.md:40 security
29 LOW 'Credentials are a hit at every level' rests only on the same AI's review, on paths no human checks — Decision 6617788666 item 2 and rule L73 make credentials a hit at every level. On --correct and on new comments, nobody now looks at the text before… rules/issue-write-back.md:73 security
30 LOW The SessionStart heredoc is now unquoted, so its whole text is shell-expanded at every session start — Still open from round 5 #36. cat <<'RULES' became cat <<RULES so that ${ROOT} expands. Every line of the text is now subject to command substitu… hooks/session-start-commit-rule.sh:14 security
31 LOW #N --last --correct --scope whole-comment now rewrites a comment the user never named, with no question — run-start resolves #N --last to .[-1].id, the newest comment on #N by any author (L2244-2256), and parse-args accepts --last with --correct. T… scripts/idd-edit-helper.py:2244 regression
32 LOW tasks.md and design.md still describe the D12-removed parts as done — Section 8's note (L49) lists the items D11 voided. Section 9 (L54) adds no such list for D12, so these items stay [x] and describe parts that are go… openspec/changes/issue-write-back/tasks.md:15 regression
33 LOW Helper docstring and idd-edit iron rule still describe the old confirmation model — (1) _correct_note_line's docstring gives the visible line's reason as "since #424 nobody confirms a correction (verify round 1)". After D11 every re… scripts/idd-edit-helper.py:1607 regression
34 LOW Rule and CHANGELOG say only the trailing old visible line is replaced; round 6 removes every one — Round 6 changed run-start (idd-edit-helper.py L2215-2216) to drop every line that starts with _更正於 anywhere in the replacement, not only a trailing… rules/issue-write-back.md:42 regression
35 LOW append-vs-modify §8 restates the hold conditions without credentials; its new table is a fourth copy of the routing — §8 Scope boundary (a) lists what holds a no-ask --correct back: enforce, a warn hit, new third-party text at light, an unconfirmed #272 questi… rules/append-vs-modify.md:129 regression
36 LOW Marker-only replacements are now refused by run-start with a message that names the wrong cause; idd-comment errata behaves differently — I ran run-start at f9a7322 on three bodies: - A body of only <!-- idd:comment type=decision ... -->. - A body of only an earlier _更正於 ..._ line. -… scripts/idd-edit-helper.py:2224 regression
37 LOW SessionStart hook keeps the unquoted heredoc; a smaller form keeps lines 1-4 literal — cat <<'RULES' became cat <<RULES so that ${ROOT} expands (round 5 #36, still open). I checked that a $(...) or backtick inside CLAUDE_PLUGIN_R… hooks/session-start-commit-rule.sh:14 regression
38 LOW New idd-edit iron rule says AI replacement text always goes in a mktemp dir; the run-now proposals use ~/.cache/idd/corrections — The added bullet says: 「--correct 不設 IDD_EDIT_HELPER_ALLOW_UNSAFE_BODY_FILE(#424,它不問):…AI 寫回的替換文字一律放在 mktemp -d 建的目錄」. The three detecting skil… skills/idd-edit/SKILL.md:298 regression
39 LOW The rule picks a different "Diagnosis" than the gate and idd-close read — Kind 2 targets 「最新一則以 ## Diagnosis 開頭、作者是你自己的 comment」. The readers choose differently: - idd-close Step 3.6 reads the newest Diagnosis by any autho… rules/issue-write-back.md:32 regression
40 LOW #424 itself has not had its decided cuts written back, though the kept rule says to write back at once — The rule says 「定案之後就寫回,不等討論結束才一次補」 (issue-write-back.md L37). In issue_424.json, #424's own body still has: - Clarity Surface row 1 resolved as 「兩者都要」… regression
41 LOW issue-write-back test asserts the absence of names and phrases that never shipped on main — Several refutes guard intermediate-round artifacts that do not exist on main (fe11459) and will mean nothing to a reader after merge: - writeback-can… scripts/tests/issue-write-back/test.sh:136` regression
42 LOW 「(AI 判斷)」:第 5 輪四個 finding 既沒修也沒記為保留,spec 同一條 requirement 自相矛盾 — 第 5 輪 #23、#27、#43、#48 都指出:可見文字寫死「(AI 判斷)」,但被砍的 D4 一拿掉,剩下的每條 --correct 路徑都是人決定的。這些路徑是:session 寫回(規則 L11「只有使用者明確定案才算」)、idd-diagnose Stage 1(使用者要求調整)、偵… openspec/changes/issue-write-back/specs/append-vs-modify-discipline/spec.md:13 devils-advocate
43 LOW 規則指定的 mktemp 寫回檔,在兩個呼叫的 TMPDIR 不同時被 run-start 以 exit 5 拒絕,錯誤訊息還建議規則禁止的逃生口 — 已重現(在 /tmp 的 scratch 目錄跑,fake gh,沒有動到 clone)。用 mktemp -d "${TMPDIR:-/tmp}/idd-writeback-XXXXXX" 在 macOS 預設 TMPDIR(/var/folders/…/T)建檔,再用不同的 TMPDIR 跑… rules/issue-write-back.md:39 devils-advocate
44 LOW 每一行舊可見文字都刪:whole-comment 更正會抹掉其他段落的更正紀錄、留下孤立標記;維護者會改成 fail-closed — 已重現(fake gh,只讀 run 目錄的 body.md)。被更正的 comment 先前已對 ### Root Cause 做過一次 --section 更正(帶可見文字與 idd:edit mode="correct" 標記)。現在對它做 --scope whole-comme… scripts/idd-edit-helper.py:2216` devils-advocate
45 LOW 同一件事問兩次:沒有寫入權的 repo、隱私命中,規則先問一次,/idd-edit 再問一次 — 規則 L70(spec 同句)規定沒有寫入權或查不到權限時「先問」。但同一種 repo 會讓 run-start 判為 SCRUB=enforce,idd-edit Step 3 第 3、6 點對 --correct 會再問一次(預設 NO)。這種情況可以真實發生:使用者在別人的 repo … rules/issue-write-back.md:70 devils-advocate
46 LOW 更正 security 的 MEDIUM(run-now 替換檔是固定共用路徑、從不清除):高估,應為 LOW — $HOME/.cache/idd/corrections/correction-<N>-<k>.md 這個路徑與不清除的做法都是 main(3.6.0)原樣,本 diff 對三個偵測 skill 只改了 attended 那一句。 內容依 L1227 是「執行時寫進」:使用者選「現在執行」後才… skills/idd-verify/SKILL.md:1227 devils-advocate
47 LOW 更正 logic 的 MEDIUM(append-vs-modify §8 沒列 credential):應為 LOW — 會真的擋下寫入的地方都已經寫了 credential 在任何等級都算命中:idd-edit Step 3 第 4 點、規則 L73、spec〈Write-back SHALL NOT ask…〉、design D6。issue-write-back 測試 L134、L135 也同時斷言規則與 i… rules/append-vs-modify.md:130 devils-advocate
48 INFO The decisions otherwise hold; suites pass at f9a7322 — Checked at f9a7322 against main (fe11459), with the clone left unmodified (git status clean). validate_body_file_path is byte-equal to main (only one … requirements
49 INFO Checked and holding at f9a7322 (clone not modified, nothing posted) — Suites run in the clone: edit-run 230/230, in-place-correction 233/233, correct-flow 120/120, idd-edit-contract 17/17, issue-write-back 88/88, session… logic
50 INFO Checked and holding in f9a7322 — Author gate: for --correct, the author must be the current gh login (login == me). Bots and the OWNER do not pass unless they are me. An ADMIN acc… scripts/idd-edit-helper.py:733 security
51 INFO Checked and holding: restored files, callers, suites; no prompt injection found — Checked at f9a7322 against fe11459. The clone was left unmodified. Files restored to main: - git diff fe11459 f9a7322 is empty for hooks/archive-re… regression
52 INFO 已嘗試反駁、仍成立的項目(f9a7322,clone 未修改、未貼文) — 已在 clone 跑過 edit-run、issue-write-back、in-place-correction、session-start-commit-rule、correct-flow 五個 suite,FAIL 都是 0;跑完後 git status 是乾淨的。 以下幾項嘗試反駁,都… devils-advocate

Verify round 6 passed with no blocking finding. The Devil's Advocate showed
#424 itself reproduced #399: six rounds of strategy decisions went only to
decision comments, and the Diagnosis stayed at round 1. The maintainer
decided two points (comment 6619279709):

- A decision that changes the diagnosis is written to both places: a
  decision comment with the user's words, and the Diagnosis section with
  --correct.
- The visible line drops (AI 判斷): _更正於 YYYY-MM-DD:<note>_.

From the round 6 findings:

- run-start replaces only the trailing group of an earlier visible line and
  correct marker (other IDD markers kept) and refuses an earlier line or
  correct marker elsewhere outside a code fence; look-alike prose and code
  examples are kept.
- Write-back and run-now replacement files go to a new directory under
  ~/.cache/idd/writeback, not TMPDIR (sandboxed calls see another TMPDIR).
- The Diagnosis target is the newest Diagnosis; someone else's gets errata.
  The Plan target is the newest Plan.
- After implementation, a change no pull request carries is written back
  and idd-reorganize rolls the phase back.
- Text taken from someone else's comment is shown and asked before writing.
- idd-reorganize's entry text and table send a same-PR change to
  write-back; idd-issue's edit-body rows show the replacement and carry
  --repo and --note; --last with a whole-comment correction asks.
- The rule leaves the permission and privacy questions of kinds 1 and 2 to
  /idd-edit, so nothing is asked twice; §8 lists credentials; the hook
  keeps lines 1-4 literal.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 7 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus

Aggregate

PASS(有 findings) — 0 CRITICAL、0 HIGH、10 MEDIUM、39 LOW、7 INFO

審的是本機 commit 3c630c4(PR head 仍是 844e8ea)。全套測試 67 個 suite 全過。連續第二輪沒有阻擋級發現;照慣例在同一個 PR 修完再合併。

主題

  1. 第 7 輪自己加的路由沒有經過決定(idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5、idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6、idd-all Examples: 跨 repo invocation 段重複描述,合併 #10)。 「沒有 PR 會帶這個改變就寫回後走 idd-reorganize」超出 comment 6617788666 的範圍;direct-commit 的 repo 沒有 PR,verify-fix 期間的改變會被誤送去 idd-reorganize。這條還被寫進 feat: 討論中持續更新 issue:問題變了改正文、診斷變了改 Diagnosis 留言、補充才新增 comment #424 自己的 Diagnosis 與 Current Status,當成現狀。
  2. 兩處都寫沒有落到 idd-diagnose Stage 1(idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4、idd-all Phase 5: PR body heredoc 改 quoted (預防未來 RCE) #7)。 Stage 1 改策略只改 Diagnosis,spec 的情境也寫「不貼新 comment」,與 D13 相反。
  3. _更正於 前綴的處理仍不一致(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1、idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2、idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9)。 prepare 的空內容檢查與 idd-close 的 Residue 讀取仍用前綴比對,會吃掉只是開頭相同的正文;第 7 輪的中段拒絕擋住 main 本來接受的整則更正。
  4. 其他: append-vs-modify 的 spec delta 還寫可見文字要說「AI 決定的」(idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3);第 3 類 comment 新加入提及(mention)的帳號時不會先問(idd-all Phase 0.2: GITHUB_REPO post-derive shape assertion #8)。

Findings

# Severity Finding Source
1 MEDIUM Whole-comment correction rejects body text that starts with the _更正於 prefix — Codex reported this as P2. Lines 1757–1758: the new kept filter in _correct_prepare() drops every line that matches l.startswith(NOTE_LINE_PREFIX… scripts/idd-edit-helper.py:1757` codex
2 MEDIUM idd-close Residue filter drops any line starting with _更正於 , which can hide real residue — Codex reported this as P2. Line 691: the new grep -vE '^(<!-- idd:edit |_更正於 )' removes any line that starts with _更正於 , not just the date notes … skills/idd-close/SKILL.md:691 codex
3 MEDIUM Spec delta still requires the visible line to say "an AI decided it" (D13 #2 does not hold) — Decision 6619279709 #2 drops (AI 判斷): the line is now _更正於 YYYY-MM-DD:<note>_. The helper, rule, issue-write-back spec, design D7, CHANGELOG and idd… openspec/changes/issue-write-back/specs/append-vs-modify-discipline/spec.md:13 requirements
4 MEDIUM idd-diagnose Stage 1 and its spec scenario forbid the decision comment that D13 requires — Decision 6619279709 #1: a decision that changes the diagnosis is written in two places, a decision comment with the user's words and a --correct of th… skills/idd-diagnose/SKILL.md:797 requirements
5 MEDIUM Round 7 sends a change no PR carries to idd-reorganize, beyond what decision 6617788666 #3 allows; proposal and design D8 still state the decision — Decision 6617788666 #3: 「只有已建好的東西要作廢、這次不跟著改時,才走 idd-reorganize」. To fix round-6 #4, round 7 added a second trigger: 「沒有 PR 會帶這個改變(例如 PR 已合併後才擴大範圍),或已建… rules/issue-write-back.md:91 requirements
6 MEDIUM "No PR carries the change" sends ordinary verify-fix changes in direct-commit repos to idd-reorganize — Round 7 widened the after-implementation route. It now reads 「沒有 PR 會帶這個改變(例如 PR 已合併後才擴大範圍),或已建好的東西要作廢、重做:照上面寫回之後,呼叫 idd-reorganize」. The spec says … rules/issue-write-back.md:91 logic
7 MEDIUM idd-diagnose Stage 1 strategy adjustments skip the decision comment that D13 requires — Decision 6619279709 #1 and the new spec sentence ("A decision that changes the diagnosis SHALL be written both as kind 2 and as a decision comment of … skills/idd-diagnose/SKILL.md:797 logic
8 MEDIUM Kind-3 write-back comments can mention a third party with no question; only the --correct path blocks new mentions — Rule L72 lets the AI write all three kinds without asking. L13 sends hypotheses and questions to a question comment (L27 lists question among the … rules/issue-write-back.md:72 security
9 MEDIUM Round 7's mid-text refusal blocks whole-comment and parent-section corrections that main accepts, and the only way past it deletes earlier correction records — run-start now refuses (exit 2) any earlier visible line or <!-- idd:edit mode="correct" marker outside a fence that is not in the trailing group. Ev… scripts/idd-edit-helper.py:2247 regression
10 MEDIUM #424 第一次真實寫回,把沒有人定案的路由寫成「現在的診斷」,Current Status 也把它列成 Key Decision — 其他 reviewer 只說規則 L91 與 spec 讓「沒有 PR 會帶這個改變」走 idd-reorganize,超出 decision 6617788666 第 3 點。沒有人指出:第一次真實寫回(ew-block.md)已經把這個越權的版本發到 GitHub 上。 證據: - decis… rules/issue-write-back.md:91 devils-advocate
11 LOW tasks.md (and #424 Current Status Tasks) still list D12-cut parts and reversed round-6 behaviour as done, with no 'no longer holds' note — Section 8 (L49) lists the items D11 voided. Sections 9 and 10 add no such list for D12 or for round 7. These items stay [x] and describe parts that … openspec/changes/issue-write-back/tasks.md:54 requirements
12 LOW design.md: decision list stops at round 5, a withdrawn decision is cited as a live mitigation, and the Implementation Contract omits D13 — (1) L8: 「五輪 verify 之後的維護者決定(comment 6600258374、6611450882、6615341615、6616229678、6617788666)」 leaves out 6619279709 (D13), which the same file adds at … openspec/changes/issue-write-back/design.md:101 requirements
13 LOW The spec mandates 'exactly one of three kinds', the 擇一 wording D13 names as the root cause — Requirement 1 still reads 'A decided change SHALL be classified into exactly one of three kinds (closed list ...)'. Later sentences in the same requir… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:9 requirements
14 LOW README, plugin.json and marketplace rows and the SessionStart line do not reflect D13 — Round 7 did not touch the README v3.7.0 row, the plugin.json and marketplace 3.7.0 descriptions, or the wording of the SessionStart write-back line. A… README.md:162 requirements
15 LOW New '#N --last + --scope whole-comment asks' exception exists only in idd-edit Step 3 — Round 7 added a second exception to D1 in idd-edit Step 3 point 3 (L182): --correct asks when the target came from #N --last with --scope whole-com… skills/idd-edit/SKILL.md:133` requirements
16 LOW Detecting skills' Step 3.5 still tells the skill to write the replacement to the fixed corrections path — In idd-verify (L1229), idd-diagnose (L782) and idd-reorganize (L89), the first bullet still says 「替換內容附在表下 <details>,執行時寫進 $HOME/.cache/idd/correct… skills/idd-verify/SKILL.md:1229` requirements
17 LOW Rule claims its Diagnosis target is the one idd-plan and idd-close read; their selectors differ — Rule L32: 「目標是最新一則 Diagnosis(以 ## Diagnosis 開頭,與 idd-plan、idd-close 讀的同一則)」. idd-plan (SKILL.md L80-86) keeps only OWNER/MEMBER/COLLABORATOR com… rules/issue-write-back.md:32 requirements
18 LOW Round-6 findings neither fixed nor recorded as left; #424's issue body still states the overturned scope — The round-7 commit message lists only fixes, and the Current Status does not record any round-6 finding as knowingly left. Still open: #10 and #32 (ta… requirements
19 LOW Fence tracking in run-start differs from Markdown; an earlier visible line gets through (reproduced) — _outside_fences opens a fence on any line matching \s*({3,}|~{3,}), with any indentation. It closes on any line whose stripped text starts with … scripts/idd-edit-helper.py:1620` logic
20 LOW Detecting skills give two different places for the run-now replacement file — In idd-verify (L1229), idd-diagnose (L782) and idd-reorganize (L89), the Proposed Corrections bullet still says the replacement 「執行時寫進 $HOME/.cache/i… skills/idd-verify/SKILL.md:1229` logic
21 LOW Both-places write plus a refused --correct posts two kind-3 comments for one decision — Rule L33 posts /idd-comment --type decision --quote and runs --correct on the Diagnosis section for the same decision. L76 says that when /idd-e… rules/issue-write-back.md:76` logic
22 LOW Diagnosis target text says it matches idd-plan and idd-close, but their selectors differ — L32 now reads 「目標是最新一則 Diagnosis(以 ## Diagnosis 開頭,與 idd-plan、idd-close 讀的同一則)」. The two readers select differently: - idd-plan (SKILL.md L8… rules/issue-write-back.md:32 logic
23 LOW Hook line and README still send decisions to a new comment only — The SessionStart line is the only channel that reaches discussion outside skills, which rules-layering gives as the reason the hook exists. It still s… hooks/session-start-commit-rule.sh:20 logic
24 LOW Spec contradictions: "exactly one kind" vs both-places, "no ask" vs list-and-wait, and the --last ask exception — (1) The requirement says a change "SHALL be classified into exactly one of three kinds". The same paragraph then requires kinds 1 and 2 "at once" to g… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:9 logic
25 LOW tasks.md section 10 does not mark which parts of 9.3 round 7 reversed — 9.3 stays [x] and still describes the helper as 「每一行舊可見文字都移除」 and the rule as 「Diagnosis 是最新一則你自己寫的」. Round 7 reversed both. The helper now strips onl… openspec/changes/issue-write-back/tasks.md:58 logic
26 LOW idd-issue "edit body" promise has no matching Stage 3 or file-location change — The added sentence says that for --correct rows "the Stage 3 preview shows the full replacement text" and that the command carries --repo and --n… skills/idd-issue/SKILL.md:1559` logic
27 LOW Hand-rolled fence parser lets an earlier visible line and a forged correct marker through the mid-text refusal (reproduced) — _outside_fences (used at L2247) treats any line matching \s* followed by three or more backticks as a fence opener, at any indent. It does not see… scripts/idd-edit-helper.py:1620 security
28 LOW Detecting skills still tell the agent to write the run-now replacement to the fixed, shared ~/.cache/idd/corrections path — Round 7 changed only the attended bullet: write the replacement into a new mktemp -d "$HOME/.cache/idd/writeback/XXXXXX" directory and "不沿用表上的固定檔名".… skills/idd-verify/SKILL.md:1229 security
29 LOW idd-diagnose's allowed-tools gains unrestricted Write (and Skill) while it reads untrusted issue bodies and comments — On main (fe11459), idd-diagnose's allowed-tools had no Write. This diff adds Write with no path pattern at L17, Skill at L20 and Bash(mktemp:*)… skills/idd-diagnose/SKILL.md:17` security
30 LOW "Own content" means the creator; a write-access collaborator can edit your Diagnosis or issue body, and the no-question path then treats that text as yours — validate-target (helper L697–736) reads .user.login, the creator, and passes when it equals the current login. On GitHub, anyone with write access… rules/issue-write-back.md:68 security
31 LOW R5 refusal still tells the agent to gh auth switch and retry (round 6 #25 still open) — On --correct, the R5 message says "If you wrote it under another GitHub account, switch to it (gh auth switch) and run again". idd-edit SKILL L285… scripts/idd-edit-helper.py:751 security
32 LOW Rule and spec examples double-quote --section, while L42 requires single quotes for values that come from GitHub — L42 says each value goes in single quotes, with '\'' for an embedded quote, because headings come from GitHub. Collaborators with write access can e… rules/issue-write-back.md:50 security
33 LOW Detecting skills give two contradicting instructions for where the run-now replacement goes — In each detecting skill, the main bullet (idd-verify L1229, idd-diagnose L782, idd-reorganize L89) still says 「替換內容…執行時寫進 $HOME/.cache/idd/correction… skills/idd-verify/SKILL.md:1229` regression
34 LOW prepare's whole-comment empty check still drops lines by prefix and is redundant with run-start — round 7 made run-start count only an exact NOTE_LINE_RE line as an earlier visible line ("prose that merely starts with the prefix is the user's tex… scripts/idd-edit-helper.py:1757 regression
35 LOW D13 (both places) does not hold on the idd-diagnose Stage 1 path — Decision 6619279709 says a decision that changes the diagnosis is written to both places: a decision comment with the user's words, plus --correct o… skills/idd-diagnose/SKILL.md:797 regression
36 LOW The 'write back, then idd-reorganize' handoff is not reflected in idd-reorganize — Round 7 routes a change that no PR carries, and built work that is discarded, to "write back first, then call idd-reorganize". idd-reorganize still … rules/issue-write-back.md:91 regression
37 LOW The idd-issue edit-body fix lives only in the Step 2d option text — Round 6 #8 asked that these rows show the replacement text and carry --repo/--note. Round 7 adds one sentence to the Step 2d option comment ("the … skills/idd-issue/SKILL.md:1559 regression
38 LOW The --last whole-comment ask is not in the spec or the task list, and its reason also covers --section — Step 3 point 3 now asks when the target comes from #N --last with --scope whole-comment. Other places do not record this: - The spec requirement s… skills/idd-edit/SKILL.md:133 regression
39 LOW Change artifacts, #424's Current Status, and an idd-edit sentence still describe removed parts as current — Still open from round 6 #10, #11, #32 and #40: - tasks.md: section 8 lists the items D11 voided. Sections 9 and 10 add no such list, so these stay [x… openspec/changes/issue-write-back/tasks.md:54` regression
40 LOW Minimal form: a compatibility branch and test refutes for formats and names that never shipped — - NOTE_LINE_RE accepts the unreleased (AI 判斷) variant. The edit-run and issue-write-back fixtures exercise it. 3.7.0 is unreleased, and the only r… scripts/idd-edit-helper.py:1608 regression
41 LOW The hook fix is correct but has no regression lock — cat <<'RULES' is quoted again. Lines 1–4 are literal, and only ${ROOT} on line 5 expands, inside a double-quoted printf argument, so a $(...) in… hooks/session-start-commit-rule.sh:14 regression
42 LOW CHANGELOG, README and proposal still say naming the items is enough to adopt someone else's comment — Round 7 changed the rule (L15) and the spec: even when the user names the items ("採納 X 的第 2、3 點"), text that comes from someone else's comment is list… CHANGELOG.md:15 regression
43 LOW The run-now question shows the replacement but not the --note that is also published — In all three detecting skills, the run-now question is now the only confirmation: 「問句裡附上該項替換內容的全文」. The rebuilt command also carries an AI-written --… skills/idd-verify/SKILL.md:1233` regression
44 LOW 第一次寫回:「不重述錯的值」套在決策紀錄段落上,產生自相矛盾的條目;選哪些段落要改也沒有人檢查 — comment-6388200931.md 的 ### 決策 段落被改成: 「D2(2026-11-04 撤回,comment 6617788666):verify 報告不改、不加註記;Implementation Plan 依新診斷改寫。」 問題有兩個: - 標籤寫「撤回」,後面接… rules/issue-write-back.md:43 devils-advocate
45 LOW 第 1 類遇到 Clarity Surface 沒有可走的路:規則要人貼 comment,helper 的拒絕訊息要人改用 idd-clarify — #424 有兩則決定縮小了問題的範圍,照規則屬於第 1 類: - 6616229678:別人的 comment 不再觸發寫回。 - 6617788666 第 1 點:verify 報告不改。 正文裡記著這兩件事的只有 ### Clarity Surface 第 1 列(「兩者都要」)與第 4 … rules/issue-write-back.md:76 devils-advocate
46 LOW 第 7 輪新加的跨 repo 條款,讓不問的寫入落到沒有人檢查 IDD 設定的 repo — 第 7 輪在規則 L41 加了:「--repo ……跨 repo 討論時是那一張 issue 的 repo」。 適用範圍(規則 L3、spec L62)是「有 IDD 設定的 repo」。但 IDD 設定是本機 checkout 裡的檔案(.claude/.idd/local.json),… rules/issue-write-back.md:41 devils-advocate
47 LOW 第 3 類「每個定案一則」:spec 的寫法、規則的理由與 #424 自己的做法三者不一致 — 三處說法不一致: - spec issue-write-back L9 要第 3 類「one per decided item」。 - 規則 L17 寫「一個定案貼一則,不是一個回合貼一則:comment 會寄通知」,理由是減少通知。 - 維護者實際接受的 decision comment 是一輪一… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:9 devils-advocate
48 LOW 更正 regression 的 MEDIUM(中段拒絕擋住 whole-comment 與上層段落的更正):高估,應為 LOW — regression 說第 7 輪的中段拒絕擋住了 main 可以做的 whole-comment 與上層段落更正,而且唯一的繞法會刪掉更正紀錄。技術上成立(main 的 prepare 對中段標記不設防),但實際範圍很窄: (1) 沒有任何呼叫端會以上層段落為目標。規則、idd-diagnose… scripts/idd-edit-helper.py:2249 devils-advocate
49 LOW 更正 logic/requirements 的 MEDIUM(idd-diagnose Stage 1 禁止或略過 D13 的 decision comment):矛盾只在 spec 的情境 — idd-diagnose SKILL Stage 1 寫的是「就地改寫 Diagnosis 受影響的段落……不追加修正 comment(#424,見 rules/issue-write-back.md)」。 它禁止的是「修正 comment」,不是 decision comment。而它連… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:129 devils-advocate
50 INFO Checked and holding at 3c630c4; one test-fixture note — Checked with the clone unmodified (git status clean after the runs): issue-write-back 98/98, in-place-correction 236/236, session-start-commit-rule 36… scripts/tests/issue-write-back/test.sh:166 requirements
51 INFO idd-close's Residue reader and the helper define the visible line differently — Round 7 made the helper count only an exact-shape line (NOTE_LINE_RE) as an earlier visible line. Text that only starts like one, such as _更正於 後來又改… skills/idd-close/SKILL.md:691` logic
52 INFO What was checked and holds at 3c630c4 (clone not modified, nothing posted) — Suites run in the clone, all with 0 FAIL: edit-run 234, issue-write-back 98, in-place-correction 236, session-start-commit-rule 36, idd-edit 37, idd-e… logic
53 INFO Checked and holding at 3c630c4 (clone unmodified, nothing posted) — Checked against the clone at 3c630c4; git status stayed clean and nothing was posted. Suites: edit-run 234/234, issue-write-back 98/98 and session-… scripts/idd-edit-helper.py:733 security
54 INFO Checked and holding at 3c630c4 (clone not modified, nothing posted) — Checked against main (fe11459): - Files restored to main are byte-equal: hooks/archive-read-guard.py, hooks.json, idd-plan, idd-implement and idd-upda… scripts/idd-edit-helper.py regression
55 INFO 跨 issue 的耦合:#392 的 close gate 把任何 Decision comment 當成對 Proposed Corrections 的回應,而 D13 讓 decision comment 成為不問就貼的副產品 — #392 分支的 idd-all SKILL(clone 768fe00f/idd-392,c853975)L1211 與 L1288 寫明:unattended 的 verify 報告列了 Proposed Corrections,只要之後有「任何」Decision comment,就不再擋 me… devils-advocate
56 INFO 嘗試反駁後仍成立的項目(3c630c4,clone 未修改、未對外發布) — - 在 clone 跑了 issue-write-back、edit-run、session-start-commit-rule、in-place-correction 四個 suite,結果分別是 98、234、36、236 全過。跑完後 git status --short 為空。 - 規則… devils-advocate

Verify round 7 passed with no blocking finding. Its heaviest point: round 7
had added, without a decision, "a change no PR carries is written back and
then idd-reorganize runs". In a direct-commit repository that sent ordinary
verify-fix changes to idd-reorganize, which posts a new Diagnosis. The
maintainer decided (comment 6620544269): a change after implementation
that no PR will carry, while the built work stays valid, is new work and
goes to a new issue with a link comment; idd-reorganize is only for built
work that is thrown away; in a direct-commit repository the same branch
before close counts as the same PR.

From the other round 7 findings:

- run-start replaces only the trailing group; everything before it is kept
  as it is (round 7 refused it and blocked corrections main accepts).
  prepare and idd-close's Residue reader now recognise only the exact
  visible line, so prose that starts the same way is kept.
- idd-diagnose Stage 1 also posts a decision comment when the adjustment
  changes the strategy or the root cause (both places).
- The detecting skills write the run-now replacement only to a new
  directory under ~/.cache/idd/writeback; the question shows the --note.
- --last always asks; a new mention in a kind-3 comment is asked first;
  the Diagnosis target is the newest Diagnosis comment, without the claim
  that idd-plan and idd-close read the same one.
- The append-vs-modify spec delta no longer says an AI decided the line;
  the issue-write-back spec no longer says exactly one kind; examples
  quote --section with single quotes; the hook line mentions both places.

Refs #424
Writing back #424's own Strategy a second time showed the earlier correct
marker carried next to the new one. That is #351's design (the first
backup stays reachable); the spec scenario said one marker. The scenario
now says one visible line, the earlier marker once and the new one, and
edit-run corrects one section twice to lock it.

Refs #424
Round 8 keeps everything before the trailing group, but rule line 43 still
told the AI that the helper refuses such lines and to remove them first, so
a whole-comment correction could lose another section's record. Reworded,
with a negative assertion; design D13 now says round 8 changed this.

Refs #424
@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #469(第 8 輪)

Engine

pai-ensemble 2.25.1 (canonical) — 4 IDD lenses + DA + Codex (gpt-6.1-sol, effort medium), model: opus。第一次跑時五個 reviewer 撞到用量上限,只有 Codex 完成;修掉它抓到的規則第 43 行之後,在 05f077c 上整輪重跑。

Aggregate

PASS(有 findings) — 0 CRITICAL、0 HIGH、11 MEDIUM、43 LOW、5 INFO

審的是本機 commit 05f077c(PR head 仍是 844e8ea)。全套測試最後一次是 6c67125,66/67(mention-markdown 負載下逾時,單獨跑通過)。連續第三輪沒有阻擋級發現。

主題

  1. bug: idd-close Step 1.55 flags squash-merged commits whose lines a later branch commit rewrote #399 的兩條實際路徑沒有被這個 change 涵蓋(idd-all Examples: 跨 repo invocation 段重複描述,合併 #10,Devil's Advocate)。 五份更正稿是 unattended verify 只列不做的 Proposed Corrections;最後上線的設計是實作者自己換的,使用者沒有定案。規則與 proposal 仍把 bug: idd-close Step 1.55 flags squash-merged commits whose lines a later branch commit rewrote #399 寫成已解決的案例。
  2. 實作之後的封閉列舉太寬(idd-all SKILL.md: pseudocode quality (goto bash / branch-exists no-op / stale Failure Modes table) #3、idd-all Phase 4: ${MAX_ROUND} substitution missing in abort message #4、idd-all Phase 5: PR body heredoc 改 quoted (預防未來 RCE) #7)。 不需要動 code 的更正也會被歸到「開新 issue」;未限定時機的「範圍也要包含 Y」情境與 D14 相反;同一個 PR 重做已建好的東西同時符合兩條。
  3. 第 8 輪自己加的 /idd-clarify --status 分支(idd-all Phase 0.2: GITHUB_REPO post-derive shape assertion #8、[SOP] umbrella split flow should mandate commit log scan before filing sub-issues #11)。 沒有隱私閘、沒有 gh-egress,還會丟掉舊答案。
  4. 規則與 spec 不同步(idd-all Phase 0.5: fork detection 改 fail-closed (gh repo view 失敗時預設 PR mode) #5、idd-all SLUG derivation: BSD/GNU sed alternation (\| not portable) #6);只有 /idd-edit 帶 --repo(idd-issue Step 2: 強制 sanitize incoming title (length cap / strip control chars) #9)。 跨 repo 時,兩處都寫的 decision comment 可能貼到別的 repo。
  5. helper 的邊界(idd-all: 增加 HITL(attended)模式 — direct-commit + 允許 sub-skill AskUserQuestion #1、idd-all: direct-commit mode 加 passive warning (dirty tree / on default branch) #2)。 標記比對會跨過第一個 -->,單獨的 CR 換行不會被尾端清理處理。

Findings

# Severity Finding Source
1 MEDIUM 更正標記的比對過於寬鬆,可能連同同一行的正文一起刪除 — Codex 回報(P2,依 diff 靜態審閱,未執行測試)。 位置:新增的 IDD_MARKER_RE,以及 run_start_subcmd() 中尾端群組的辨識與過濾: ```python IDD_MARKER_RE = re.compile(r"\s*<!--\sidd:.-… scripts/idd-edit-helper.py codex
2 MEDIUM 尾端清理未處理單獨的 CR 換行,重複更正會留下過期註記 — Codex 回報(P2,依 diff 靜態審閱,未執行測試)。 位置:run_start_subcmd() 新增的: ```python lines = state["body_input"].replace("\r\n", "\n").rstrip("\n").split("\n") ``… scripts/idd-edit-helper.py codex
3 MEDIUM The after-implementation closed list misses the spec's own scenario and overlaps itself — Rule L88 and spec issue-write-back L100 say every change decided after implementation falls into a closed list of three cases. The list does not fit c… rules/issue-write-back.md:88 requirements
4 MEDIUM Scenario 'Scope widened in a session' and the rule's example row contradict decision 6620544269 — Spec L13-14: WHEN the user settles that #N must also cover Y, the issue is open and the user opened it, THEN the AI SHALL run /idd-edit issue:N --cor… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:13` requirements
5 MEDIUM design.md's Implementation Contract contradicts D13, and round 7 #12 was not fixed — - L80: Stage 1 用 /idd-edit ... --correct 改寫,「不追加 comment」. idd-diagnose Stage 1 and the spec (L124, L129) now post a decision comment when the strat… openspec/changes/issue-write-back/design.md:80 requirements
6 MEDIUM Two round 7 fixes landed only in the rule; the spec's SHALL still says the opposite — - Refused write-back. Rule L76 now says a both-places decision does not post a second comment (「不另貼」) and that protected on ### Clarity Surface go… openspec/changes/issue-write-back/specs/issue-write-back/spec.md:62 requirements
7 MEDIUM The after-implementation closed list sends a change that needs no work to a new issue, against the spec's own scenario — Rule L88 says changes after implementation are a closed list of three cases, and the rule forbids inferring a fourth. L91 reads 「沒有 PR 會帶這個改變,而已建好的東西照… rules/issue-write-back.md:91 logic
8 MEDIUM Round 8's new protected fallback sends a no-question write to the issue body through /idd-clarify --status, which has no privacy review and no gh-egress — L76 (new in round 8, not in 3c630c4) says: 「protected 落在 ### Clarity Surface 時,改用 /idd-clarify --status」. This sits in the section titled 不先問, s… rules/issue-write-back.md:76 security
9 MEDIUM Only /idd-edit is told to carry --repo; kind-3 comments, errata fallbacks and idd-update go to the config repo, and round 8 keeps cross-repo discussion in scope — L41 (rewritten in round 8) keeps the cross-repo case: 「討論的是別的 repo 的 issue 時,那個 repo 也要有 IDD 設定與寫入權,否則先問」. But the bullet sits under 「/idd-edit --cor… rules/issue-write-back.md:41` security
10 MEDIUM 前提攻擊:#399 的兩條實際路徑在 05f077c 上都不會觸發,規則與 proposal 仍把它當成已解決的案例 — 其他 reviewer 都沒有回頭查 #399 當時實際走的路。我讀了 #399 與 PR #418 的 comment(唯讀)。 (1) 五份更正稿全是 idd-verify 偵測列出的 Proposed Corrections,不是討論定案的改變。PR #418 comment 6316254… rules/issue-write-back.md:102 devils-advocate
11 MEDIUM 補強 security:第 8 輪的 /idd-clarify --status 分支不只沒有隱私閘,還會丟掉舊答案;這一句應該整段砍掉 — security 指出這條路沒有隱私自審與 gh-egress,屬實(idd-clarify Step 6 直接 gh issue edit --body)。還有兩件事沒人提到。 (1) 舊版不保留。我用 idd-clarify Step 5b 的分支邏輯跑 #424 第 1 列(reprod… rules/issue-write-back.md:76 devils-advocate
12 LOW The --last question exists only in idd-edit Step 3; spec and TaskCreate say otherwise (round 7 #15, #38) — idd-edit SKILL L182 asks when the target came from #N --last, and the commit message says '--last always asks'. Spec L19 says the skill SHALL apply … openspec/changes/issue-write-back/specs/in-place-correction/spec.md:19 requirements
13 LOW #424's Diagnosis omits the newest decision and still lists the old file set — comment-6388200931.md: - ### 決策: 「之後的維護者決定(verify 各輪之後,依序)」 ends at 6619279709. 6620544269 is missing, and the visible line says 「列出之後六則維護者決定」. The … requirements
14 LOW #424's Current Status stops at 437e36a; the reviewed head is 05f077c — issue_424.json Current Status: Blocking says 「verify 第 8 輪待跑(本機 437e36a)」, Commits starts at 437e36a, and Tasks ends at 11.2. Commit 05f077c and tas… requirements
15 LOW #424's issue body still states two overturned scopes in the Clarity Surface (round 7 #18, #45) — Row 1 reads 「兩者都要:session 裡的討論與 GitHub 上任何人的 comment 都觸發寫回」, overturned by 6616229678. Row 4 reads 「引用舊診斷的 Implementation Plan 與 verify 報告一起改」, overtu… requirements
16 LOW tasks.md still lists cut parts as done, with no 'no longer holds' note for D12 (round 7 #11, #25, #39) — The section 8 note (L49) covers D11 only and misses part of D11 itself. Section 9 has no such note. Section 11's note covers only 10.2. Still [x] a… openspec/changes/issue-write-back/tasks.md:54 requirements
17 LOW Replacement-file steps need Write and mkdir, but round 8 removed Write from idd-diagnose and tasks still say it was added — Rule L40 says to write the replacement 「用 Write 工具」 into a directory made with mkdir -p and mktemp -d. idd-diagnose's run-now bullet and Stage 1 … skills/idd-diagnose/SKILL.md:15` requirements
18 LOW The direct-commit part of decision 6620544269 is missing from idd-reorganize's entry and from the summaries — The decision counts the same branch before close as the same PR. Rule L90, design D8, spec L100, CHANGELOG 3.7.0 and the Diagnosis Strategy say so. id… skills/idd-reorganize/SKILL.md:28 requirements
19 LOW CHANGELOG's idd-issue claim has no dispatch path (round 7 #26, #37) — CHANGELOG 3.7.0 says multi-finding 'edit body' rows that go to --correct' write after the preview, the batch confirmation in Stage 3 being the one qu… skills/idd-issue/SKILL.md:1605` requirements
20 LOW Proposal and design scope lists leave out files this change edits — Proposal 'Affected code' omits plugins/issue-driven-dev/skills/idd-issue/SKILL.md (no occurrence in the file) and the canonical openspec/specs/in-p… openspec/changes/issue-write-back/proposal.md` requirements
21 LOW Remaining round 7 LOWs are open with no record that they were knowingly left — Commit 6c67125 and tasks 11.2 list fixes only; the Current Status and decision 6620544269 name nothing as left. Still open as of 05f077c: - #30: 'own … requirements
22 LOW The --last question exists only in idd-edit Step 3; the spec and the Step 0 task still say enforce is the only exception — Round 8 widened Step 3 point 3 to ask for any target from #N --last. Two places did not change. - The Step 0 task at L133 still reads 「--correct 不問(… skills/idd-edit/SKILL.md:133 logic
23 LOW Rule and CHANGELOG still say the earlier marker is replaced; it is carried, as spec commit 437e36a corrected — Rule L43 says 「替換文字結尾那一組舊的可見文字與更正標記會被換掉」. CHANGELOG L33 says 'The earlier line and correct marker at the end of the replacement are replaced'. I ran … rules/issue-write-back.md:43 logic
24 LOW The new link and decision commands omit required flags, adding a question at a step that should not ask — idd-comment Step 2 requires --target and --body for link, and --quote and --body for decision; a missing field goes to AskUserQuestion. - … rules/issue-write-back.md:91 logic
25 LOW Both-places writes have no order, and only one order makes the refusal fallback work — L76 says that when --correct is refused and the decision comment already exists, 「就把更正寫進它,不另貼」. L33 and the table row list the decision comment firs… rules/issue-write-back.md:76 logic
26 LOW idd-diagnose Stage 1 narrows both-places to strategy or root cause; routing is also kind 2 — Stage 1 posts the decision comment only when 「調整改了策略或 root cause」, and the spec requirement for idd-diagnose has the same wording. Kind 2 is defined a… skills/idd-diagnose/SKILL.md:796 logic
27 LOW Round 8 removed Write from idd-diagnose while the rule requires the Write tool on the path that does not ask — Stage 1 and the run-now step both need --body-file, and rule L40 says 「替換文字用 Write 工具寫進這次專用的新目錄」. Round 8 removed Write from idd-diagnose's allowe… skills/idd-diagnose/SKILL.md:14 logic
28 LOW The rule's Diagnosis selector still differs from idd-close and idd-plan; round 8 removed the claim, not the difference — The rule targets the newest comment that starts with ## Diagnosis. idd-close reads the newest whose first line matches ^ {0,3}#{1,6}[^\p{L}\p{N}]*d… rules/issue-write-back.md:32` logic
29 LOW idd-issue's Stage 3 promises a --correct dispatch that the Stage 4 table does not have — Round 8 added a Stage 3 bullet saying an [EDIT] row sent to /idd-edit --correct shows the replacement and the note, because 「這一題是唯一的確認」. Stage 4'… skills/idd-issue/SKILL.md:1613 logic
30 LOW The trailing-group match deletes an indented code example at the end of a replacement (reproduced) — The tail loop tests NOTE_LINE_RE.fullmatch(lines[-1].strip()), so indentation is ignored. Reproduced with a replacement ending the format is:\n\n … scripts/idd-edit-helper.py:2228` logic
31 LOW --note '' on another mode exits 0; the spec says any other mode given --note exits 2 (reproduced) — The check is if state["note"] and state["mode"] != "--correct", so an empty value passes. run-start ... --append --reason r --note '' returned 0, … scripts/idd-edit-helper.py:2208 logic
32 LOW A login inside an HTML comment counts as already mentioned, so --correct writes a new live mention without a question (reproduced) — _existing_mentions scans the old body with mention_scan_text.py, which drops code but keeps HTML comments. The logins it finds are passed as --mention… scripts/idd-edit-helper.py:1516 security
33 LOW The new mention question covers only kind-3 comments and disagrees with the protocol it cites — Round 8 added: 「第 3 類 comment 新加入 @ 提及時,照 tagging-collaborators.md 先問」. Three gaps remain: 1. tagging-collaborators.md Step 3 asks only on zero or s… rules/issue-write-back.md:75 security
34 LOW The Diagnosis target has no author filter: any account in a public repo can redirect the write-back, and round 8 only removed the claim — Round 7 #17 and #22 reported that the rule's selector differs from idd-plan's. Round 8 deleted 「與 idd-plan、idd-close 讀的同一則」 and kept the selector: 「最新… rules/issue-write-back.md:32 security
35 LOW Rule L86 runs /idd-update after a write-back, and its rebuild reads every comment and trusts an errata marker from anyone (path predates this PR) — The spec says someone else's comment SHALL NOT trigger a write-back by itself. Rule L86 tells the AI to run /idd-update #N after a Diagnosis write-b… skills/idd-update/SKILL.md:158 security
36 LOW The --last question exists only in Step 3 item 3; the task list and the spec still say only SCRUB=enforce asks — Round 8 changed Step 3 item 3 (L182) so any #N --last target asks. The TaskCreate at L133, the agent's step list, still reads 「--correct 不問(SCRUB=en… skills/idd-edit/SKILL.md:133 security
37 LOW Round 7 #30 and #31 are unchanged: the gate checks the creator, not the last editor, and the R5 message still suggests gh auth switch — Rechecked at 05f077c. validate-target compares .user.login, the creator. Rule L68 says the no-question path lands only on 「確定是自己的」 content. On GitH… scripts/idd-edit-helper.py:750 security
38 LOW idd-edit still calls the preview the last line of defence, which is no longer true for --correct — L299 ends: 「Preview gate 仍是最後一道防線」. For --correct the preview no longer stops anything: it is shown and applied, and the semantic privacy review is th… skills/idd-edit/SKILL.md:299 security
39 LOW 「不把文字貼進指令」 covers only --correct; kind-3 bodies pass through a shell variable in idd-comment — Rule L40 keeps replacement text out of commands for --correct. idd-comment Step 3.5 reads : "${COMMENT_BODY:?...}"; printf '%s' "$COMMENT_BODY" > ...… skills/idd-comment/SKILL.md:497` security
40 LOW Read-as-data and list-and-wait name only comments; other text by someone else is not covered — L15 and the spec say 「別人的 comment」 and 「寫進去的內容來自別人的 comment 時」. An issue body opened by someone else, a PR description or a commit message carries the… rules/issue-write-back.md:15 security
41 LOW run-start's trailing-group rewrite changes text main leaves alone: a duplicated marker and a dropped indented line (reproduced) — Round 8 limited the rewrite to the trailing group, but that group still alters text in three ways. Reproduced with the repo's fake gh. (a) Duplicated… scripts/idd-edit-helper.py:2228 regression
42 LOW Three lines still differ from main with no behaviour behind them, one of which tasks.md says went back to main — (1) kept = [...] at L1740 cannot affect the run path. run-start always appends the note line and refuses a replacement with no non-marker text, so… scripts/idd-edit-helper.py:1740 regression
43 LOW idd-diagnose Stage 1 can lose an adjustment outside a git work tree, where main's gh issue comment worked (reproduced) — On main, Stage 1 appended a comment, which needs only gh. It now goes through /idd-edit --correct, whose prepare needs a git work tree for the arc… skills/idd-diagnose/SKILL.md:796 regression
44 LOW idd-issue's edit-body promise still has no dispatch: Stage 4 has no --correct row — Round 8 added a Stage 3 bullet: [EDIT] rows sent to /idd-edit --correct show the full replacement and --note, and 「這一題是唯一的確認」. CHANGELOG repeats… skills/idd-issue/SKILL.md:1586 regression
45 LOW idd-diagnose's allowed-tools additions no longer serve the flow: Write was removed, Skill and mktemp stayed — Commit 6c67125 removed Write from idd-diagnose's frontmatter after round 7 #29, leaving the additions Bash(mktemp:*) and Skill. The rule still r… skills/idd-diagnose/SKILL.md:15 regression
46 LOW Remaining text that describes removed or changed parts as current — Still open from round 7 #11, #12, #25 and #39, plus new items: - design.md L8: 「五輪 verify 之後的維護者決定」 lists decisions through 6617788666 and omits 6619… openspec/changes/issue-write-back/design.md:105 regression
47 LOW #N --last 問句本身沒有決定紀錄:三位 reviewer 要求補文件,方向應該相反 — requirements、logic、security 都說這個例外只在 Step 3,要補進 spec 與 TaskCreate。但這個例外不是決定,是 reviewer 發現長出來的:第 6 輪 #31 提出,第 7 輪加上 whole-comment,第 8 輪擴大到所有 --last。D… skills/idd-edit/SKILL.md:182 devils-advocate
48 LOW 規則 L41 的「那個 repo 也要有 IDD 設定」查不了;一句話可同時收掉 cross-repo 的問題 — 第 7 輪 #46 指出 IDD 設定是本機 checkout 裡的檔案(.claude/.idd/local.json)。第 8 輪留下「討論的是別的 repo 的 issue 時,那個 repo 也要有 IDD 設定與寫入權,否則先問」,但沒有 clone 就無從檢查,AI 只能猜。L72 … rules/issue-write-back.md:41 devils-advocate
49 LOW 更正 logic/requirements/regression:allowed-tools 少了 Write 不會讓流程壞掉,這三項與第 7 輪 #29 在互相來回 — 官方文件(code.claude.com/docs/en/skills)對 allowed-tools 的定義是「Tools Claude can use without asking permission during the turn that invokes this skill. The… skills/idd-diagnose/SKILL.md:10 devils-advocate
50 LOW 規則 L75 說新提及的問題「由 /idd-edit Step 3 做」,但 Step 3 沒有這一題,實際是 prepare 拒絕後不貼 — L75:「第 1、2 類的自審與這一題由 /idd-edit Step 3 做,同一個命中不問兩次」。skills/idd-edit/SKILL.md 裡完全沒有「提及」或「mention」。實際行為是 _correct_prepare 的 egress 預檢對新加入的 login 回 R… rules/issue-write-back.md:75` devils-advocate
51 LOW spec 把「假設與提問」寫成必須貼 comment 或發問,比規則與決定都嚴 — spec:「A hypothesis, a question, or agreement without a stated change SHALL NOT change the issue body or the Diagnosis; the AI SHALL post a comment or … openspec/changes/issue-write-back/specs/issue-write-back/spec.md:9 devils-advocate
52 LOW diff 之外仍寫 Diagnosis 與 ### Complexity 不可改,與第 2 類的「分流」相反 — reviewer 掃的是已砍部件的殘留,沒掃 diff 外的反向敘述。references/actionability-gate.md L17 寫「Diagnosis comments are append-only」,並說這類值「could never be corrected in pl… references/actionability-gate.md:17 devils-advocate
53 LOW #424 自己的寫回:第 2 類與兩處都寫跑通了,第 1 類一次都沒跑過 — ew-block.md 記錄的寫回只有 Diagnosis 段落、Current Status 重建與 decision comment。沒有任何一次 --correct issue:424,正文裡也沒有這類更正標記。三類分流裡,動機最強的「問題變了就改正文」沒有真實實例。 而 #424 其實… rules/issue-write-back.md:34 devils-advocate
54 LOW 維護者還能砍的:test refute、SessionStart 行長、規則的歷史段、未決定的 list-and-wait — (1) 第 7 輪 #40 要求清掉只為未發布格式存在的東西。第 8 輪拿掉了 regex 分支,卻新增 test 反向斷言:issue-write-back 的 refute 從 3c630c4 的 22 條增為 27 條,L97 與 L103 把 (AI 判斷) 永遠寫進測試,L83、L93… scripts/tests/issue-write-back/test.sh:97 devils-advocate
55 INFO Checked and holding at 05f077c (clone unmodified, nothing posted) — Suites run: issue-write-back 110/110, session-start-commit-rule 36/36, in-place-correction 236/236, edit-run 239/239, docs-catalog-sync 21/21. `git st… requirements
56 INFO Checked and holding at 05f077c (clone unmodified, nothing posted, no prompt injection found) — Suites: edit-run 239, issue-write-back 110, in-place-correction 236, session-start-commit-rule 36, all 0 FAIL. git status is clean. A scratch harnes… logic
57 INFO Checked and holding at 05f077c; no prompt injection in the inputs — Clone unmodified (git status empty after the runs), nothing posted. Suites: edit-run 239/239, issue-write-back 110/110, session-start-commit-rule 36… security
58 INFO Checked and holding at 05f077c (clone unmodified, nothing posted, no prompt injection found) — Clone status stayed clean after the runs; scratch files in /tmp were removed. Nothing in the inputs or the diff read as an instruction to me. Suites … regression
59 INFO 嘗試反駁後仍成立的項目(05f077c,clone 未修改、未對外發布,輸入中無 prompt injection) — - 我先懷疑 --section '## Expected' 在 Expected 是 Clarity Surface 之前最後一段時會被判 protected,規則的主要例子就走不通。實測不成立:_section_end 停在受管標題前,check-correction 回 0,c… devils-advocate

…ed (#424)

Verify round 8 passed with no blocking finding (0 HIGH, 11 MEDIUM). The
maintainer decided (comment 6680124222):

- Only changes the user decides are written back. Corrections listed by an
  unattended verify and an approach the implementer changed on their own
  are out of scope, stated in the rule and proposal, tracked in #474.
- Two questions added while fixing findings, never decided, are gone: text
  from someone else's comment shown and asked before writing, and --last
  always asking. Items the user names count as decided.

From the other findings: a change that needs no further work is written back
as usual, and the three cases after implementation apply in order to work
that remains; --correct runs before the decision comment, and a refused
correction joins that comment instead of a second one; every command in the
rule carries --repo; the idd-clarify branch is gone; IDD_MARKER_RE stops at
the first -->, a lone CR ends a line, and indented lines are not part of the
trailing group. idd-issue and idd-diagnose's allowed-tools are back to main.

Refs #424
spectra archive applied the four delta specs to the main specs (added 10,
modified 5, removed 3) and moved the change to
openspec/changes/archive/2026-11-06-issue-write-back.

The move left two paths in the issue-write-back test stale: the header
comment, and an assertion that read the delta spec. The assertion now reads
the main spec, which holds the same text.

Refs #424
main gained #392 (dc7eb2c, archive 90054e2) and #405 since this branch
was cut. One conflict, in CHANGELOG.md: the branch had a dated [3.7.0]
section, main an [Unreleased] one for #392. They are now one
[Unreleased] section holding both sets of entries.

The version bump moves out of this PR. The marketplace serves the plugin
from main, so merging a PR that sets 3.7.0 would ship it to users at the
merge. plugin.json, marketplace.json, the root README row and the plugin
README's v3.7.0 row are back to main's 3.6.0 values; the release commit
sets 3.7.0, the date and the descriptions for #392 and #424 together, as
the 3.6.0 release did.

Refs #424
@kiki830621
kiki830621 marked this pull request as ready for review November 10, 2026 15:16
@kiki830621
kiki830621 merged commit 8b34251 into main Nov 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant