Problem
#19 verify Round 4 通過(0 HIGH),但留下 16 MEDIUM / 12 LOW,其中多條是 #19 R2–R4 自己帶進來、落在「gate 印出它沒量過的事實」這條線上的:
MEDIUM(R4 #1 –#16 )
Phase 2 Step 4 以第一個 / 拆 @{u} 顯示名推導 push remote (codex / security / DA):remote 名含 /、或 upstream 是本地分支(branch.<name>.remote=.)時拆錯,DA 實測在錯的 remote 上開出新分支;事後 @{u} == HEAD 驗證只能在資料已送出後報錯。改用 git for-each-ref --format='%(upstream:remotename) %(upstream:remoteref)' "$(git symbolic-ref -q HEAD)"(或 git config branch.<name>.remote / .merge),upstream 是本地分支時 abort;補「remote 名含 /」「本地 upstream」fence 測試。
Phase 0.3 只看 $UPSTREAM..HEAD(ahead),不看 behind :純 shell、沉睡、乾淨、版本一致、upstream 已前進(已 fetch 未 ff)→ Case A exit 0,Phase 0.5 的 E' 不可達。加 git rev-list --count HEAD..$UPSTREAM,非 0 進 Phase 0.5。
Phase 2 Step 4「無需 push」分支只量 ahead :Phase 0.5 之後 upstream 前進時仍印「upstream 已包含 HEAD」(字面為真)而 Phase 3 拉到的是別的版本;加 behind 檢查並明說。
Phase 2.5「更新 README」fence 仍是裸 git push + 宣告式成功 (與 Phase 0.5 push fence 同):比照 Phase 2 Step 4(明寫 remote/refspec + 事後驗證);Step 3 前言「Case A 路徑上唯一的 push」措辭錯(attended 下 Phase 2.5 是第二個 push)。
Phase 5 Step 3 report 宣稱收錄 Phase 1.5 的 AUDIT 行 ,但該路徑 abort、走不到 Phase 5;模板裡 Phase 0.3 Case A/B、Phase 0.5 abort、Phase 2 abort 都是不可達取值。收斂成只收 Phase 2.5、abort 路徑的痕跡由 exit 75 structured error 交給 idd-all,或 abort 前印縮減版 report。
沒有測試綁住 plugin-update: Phase 0.3 與 Phase 0.5 可對同一次執行給出互相矛盾的裁決 #19 的實際重現狀態 (0.3 Case C ∧ 0.5 Case A 同時成立:recent_touches>0 ∧ 樹乾淨 ∧ 0 unpushed ∧ drift=no):pure 全部 backdate 到 2024,永遠 Case A。補一個當下時間的 commit 並 push,斷言 0.3 印 Case C 且 0.5 Case A fence 印 verified。
Phase 0.5 前言封閉列舉第 (1) 項把 push 條件寫窄 :實際由 @{u}..HEAD 決定,與 marketplace.json 有沒有變無關;改寫。
smoke test「Case A keeps the context file」是空斷言 (緊接的 prep01 已重寫 ctx);改為在 Case A fence 之後、下一個 prep 之前斷言。
E' 的「每次 invocation 最多一次」與 Case A 自驗失敗的重測只有散文、沒有狀態記錄 (shell 變數不跨 fence):在 context 檔加一個 RETEST=1 欄位或以 marker 檔記錄。
Phase 2 Step 4 印 push 前的 commit subject 未消毒 (第三方 commit 訊息可偽造控制行):經 clean() 或 printf '%s'。
Case E' 在髒樹上仍會被選中(優先序 2 > 3/4) :unattended 首次會在有未提交工作的樹上跑 git pull --ff-only;fence 的失敗訊息把 ff-only 對髒樹的行為寫反(ff-only 對不衝突的髒檔會成功)。決定:E' 只在樹乾淨時走 ff-only,髒樹 + behind 歸 Case C/D 或 abort。
Phase 0.3 / Phase 0.5 新增的 abort(無 upstream、Case A 自驗失敗、Edit 沒落地)不清 context ,與 Step 3 的封閉列舉不一致;exit 75 同時代表「gate abort」與「回去重新分類」,外部消費端無從區分(Case A 自驗失敗改用另一個退出碼,如 76)。
CHANGELOG R4 條目「計數不再被 head -10 截斷」與 diff 不符 :SHELL_RECENT_TOUCHES 仍 head -10,recent_touches 實測 16 個檔案只印 10;修 fence 或修 CHANGELOG。
新測試區塊永久改動共用 fixture(push.default + branch 改名未還原)→ 還原或獨立 fixture。
.claude-plugin/marketplace.json 算進 SHELL_DIRTY / SHELL_UNPUSHED 讓 gate 從 plugin-scoped 變 repo-scoped(多 plugin marketplace 下別的 plugin 的鏡像也會觸發 Case C)——記為刻意(marketplace.json 是本 skill 要寫的檔),或收窄為「該 entry 的 diff」。
Phase 2 Step 4 的 clean() 就地重定義(截 80 vs 共用 200):抽到 resolver 成 sanitize_for_echo 共用。
LOW
Type
bug
Expected
上列 MEDIUM 全部修掉、LOW 至少處理測試斷言;test-plugin-update-fences.sh 對「remote 名含 /」「本地 upstream」「behind-only 進 Phase 0.5」「#19 重現狀態(Case C ∧ Case A verified)」有覆蓋;Phase 2.5 與 Phase 0.5 的 push fence 與 Phase 2 Step 4 同一套 refspec + 事後驗證。
Actual
見上。
Impact
plugin-update 的 push / gate 判準面。Conflict Class C(與 #22 / #24 同一份 skills/plugin-update/SKILL.md),建議與 #24 一起排在 #22 之前或之後由使用者決定。
Refs #19 (verify R4 findings;PASS 判準 0 HIGH 已達,本 issue 收 MEDIUM/LOW)、#24 (Step 5 / commit fence 同族)。
Source : surfaced during /idd-verify #19 round 4(codex / requirements / logic / security / regression / devils-advocate lenses)
Problem
#19 verify Round 4 通過(0 HIGH),但留下 16 MEDIUM / 12 LOW,其中多條是 #19 R2–R4 自己帶進來、落在「gate 印出它沒量過的事實」這條線上的:
MEDIUM(R4 #1–#16)
/拆@{u}顯示名推導 push remote(codex / security / DA):remote 名含/、或 upstream 是本地分支(branch.<name>.remote=.)時拆錯,DA 實測在錯的 remote 上開出新分支;事後@{u} == HEAD驗證只能在資料已送出後報錯。改用git for-each-ref --format='%(upstream:remotename) %(upstream:remoteref)' "$(git symbolic-ref -q HEAD)"(或git config branch.<name>.remote/.merge),upstream 是本地分支時 abort;補「remote 名含/」「本地 upstream」fence 測試。$UPSTREAM..HEAD(ahead),不看 behind:純 shell、沉睡、乾淨、版本一致、upstream 已前進(已 fetch 未 ff)→ Case Aexit 0,Phase 0.5 的 E' 不可達。加git rev-list --count HEAD..$UPSTREAM,非 0 進 Phase 0.5。git push+ 宣告式成功(與 Phase 0.5 push fence 同):比照 Phase 2 Step 4(明寫 remote/refspec + 事後驗證);Step 3 前言「Case A 路徑上唯一的 push」措辭錯(attended 下 Phase 2.5 是第二個 push)。pure全部 backdate 到 2024,永遠 Case A。補一個當下時間的 commit 並 push,斷言 0.3 印 Case C 且 0.5 Case A fence 印 verified。@{u}..HEAD決定,與 marketplace.json 有沒有變無關;改寫。prep01已重寫 ctx);改為在 Case A fence 之後、下一個 prep 之前斷言。RETEST=1欄位或以 marker 檔記錄。clean()或printf '%s'。git pull --ff-only;fence 的失敗訊息把 ff-only 對髒樹的行為寫反(ff-only 對不衝突的髒檔會成功)。決定:E' 只在樹乾淨時走 ff-only,髒樹 + behind 歸 Case C/D 或 abort。SHELL_RECENT_TOUCHES仍head -10,recent_touches 實測 16 個檔案只印 10;修 fence 或修 CHANGELOG。push.default+ branch 改名未還原)→ 還原或獨立 fixture。.claude-plugin/marketplace.json算進SHELL_DIRTY/SHELL_UNPUSHED讓 gate 從 plugin-scoped 變 repo-scoped(多 plugin marketplace 下別的 plugin 的鏡像也會觸發 Case C)——記為刻意(marketplace.json 是本 skill 要寫的檔),或收窄為「該 entry 的 diff」。clean()就地重定義(截 80 vs 共用 200):抽到 resolver 成sanitize_for_echo共用。LOW
did not resolve行數、名稱被丟掉(同 plugin-update: #18 R10 遺留 — Step 5 unresolved 語意、commit fence pathspec / 退出碼、Phase 2.5 信號 4 與 SKIPPED 消毒 #24 的 Step 5 重整一併)。Type
bug
Expected
上列 MEDIUM 全部修掉、LOW 至少處理測試斷言;
test-plugin-update-fences.sh對「remote 名含/」「本地 upstream」「behind-only 進 Phase 0.5」「#19 重現狀態(Case C ∧ Case A verified)」有覆蓋;Phase 2.5 與 Phase 0.5 的 push fence 與 Phase 2 Step 4 同一套 refspec + 事後驗證。Actual
見上。
Impact
plugin-update的 push / gate 判準面。Conflict Class C(與 #22 / #24 同一份skills/plugin-update/SKILL.md),建議與 #24 一起排在 #22 之前或之後由使用者決定。Refs #19(verify R4 findings;PASS 判準 0 HIGH 已達,本 issue 收 MEDIUM/LOW)、#24(Step 5 / commit fence 同族)。
Source: surfaced during /idd-verify #19 round 4(codex / requirements / logic / security / regression / devils-advocate lenses)