Skip to content

plugin-update: Phase 0.3 與 Phase 0.5 可對同一次執行給出互相矛盾的裁決 #19

Description

@kiki830621

現象

同一次執行裡,Phase 0.3 判定「有東西要同步、繼續」,Phase 0.5 隨即判定「沒東西可推、exit 0」。兩者條件可同時成立,且沒有任何一方知道對方的存在。

證據

plugins/harness-devtools/skills/plugin-update/SKILL.md

  • L246 Case C當 MP_DRIFT=yes OR SHELL_RECENT_TOUCHES 非空:正常 sync use case,print 簡短摘要後進入 Phase 0.5
  • L349 Case Adivergence 0 0 AND git status --short 空echo "✗ Nothing to push…"; exit 0

SHELL_RECENT_TOUCHES 問的是「過去 30 天有沒有 commit 碰過這個 plugin」,Case A 問的是「此刻有沒有未推送或未提交的東西」。一個看歷史、一個看當下,兩者正交 —— 所以「30 天內改過 ∧ 現在乾淨」是完全正常的狀態,而它同時滿足兩個互斥的裁決。

根本原因:0.5 假設了一個 0.3 不成立的前提

Phase 0.5 的設計前提是「使用者已自行改好並 commit,來這裡決定要不要 push」。但 Phase 2 的編輯(bump plugin.json、鏡像 marketplace.json)是 skill 自己要做的,在 0.5 執行的當下還沒發生。

於是最乾淨的起始狀態 —— 剛 pull 完、樹是乾淨的、正要來跑一次正常的版本同步 —— 反而觸發 exit 0gate 在它最該放行的情況下擋住

實例

2026-08-31 對 che-apple-mail-mcp 出貨 v3.0.0:

Phase 0.3 → Case C(plugin/ 30 天內 8+ 檔變動)→ 繼續
Phase 0.5 → 0 0 divergence + 乾淨樹 → Case A → exit 0

當時是判斷「gate 的目的(別推不相干或做到一半的東西)在 clean tree 下已最大程度滿足」而繼續執行,但那是繞過規則,不是遵守規則。

額外的不一致

Case A 的訊息建議「bypass plugin-update 並直接跑 claude plugin marketplace update」。這在此情境下是錯的指引 —— marketplace.json 的版本此刻還沒 bump,直接刷 cache 只會把舊版本再拉一次。

方向(不指定作法)

問題在「0.5 用『現在有沒有待推送的東西』代理『這次執行結束後會不會有東西要推』」。skill 自己會產生變更這件事,讓這個代理失效。

可能的方向(擇一或其他):

  1. 讓 0.5 知道 0.3 的裁決 —— Case C 通過時,clean+0 unpushed 應視為合法的起始狀態而非 abort 條件。
  2. 把 0.5 移到 Phase 2 之後 —— 讓它 gate 的是 skill 已經產生的變更,那才是它文案在講的東西。
  3. 把 Case A 的 abort 收窄成「0.3 也判定 nothing to sync」時才成立。

順帶:Case A 的建議指令在 0.3 判定 Case C 的情況下應該改掉,理由如上。


Current Status

Phase: verified
Last updated: 2026-09-15 by idd-verify (R4 PASS)

Key Decisions

  • R4 PASS(0 CRITICAL/HIGH,16 MEDIUM / 12 LOW / 7 INFO)— 報告:https://github.com/PsychQuant/che-plugin-devtools/issues/19#issuecomment-5674491363;tag idd-19-verified = 937d40e(已 push)
  • R4:Phase 2 Step 4 push 明寫 remote + HEAD:refs/heads/<branch> 並在 push 後驗 @{u} == HEAD;以 @{u}..HEAD 決定是否 push;Phase 0.3 先解 @{u},解不到即 abort
  • R3:Case A fence 自驗 divergence 雙零後 pass-through;E' fence 印新狀態、每次 invocation 最多一次;Phase 5 新增最終 report
  • R2:Phase 0.3 對所有 plugin 執行(binary 信號對純 shell 為空);Phase 0.5 只 gate 樹上既有的未提交 / 未推送;Case A 的 bypass 建議改為條件式
  • 採 issue 方向 1+3、不採 2:0.5 的價值在動手前攔既有髒東西,不搬到 Phase 2 之後

Scope Changes

Blocking

  • (none) — 等使用者 /idd-close #19(idd-all 永不 auto-close)

Commits

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions