Skip to content

idd-issue: Step 3.6 baseline tag 未檢查 issue 號非空,建立失敗時會推出 idd--baseline #412

Open

Description

@kiki830621

Problem

idd-issue Step 3.6 的 baseline tag 範例(skills/idd-issue/SKILL.md 約第 1042 行 TAG="${BASELINE_FMT/\{N\}/$NUMBER}")沒有檢查 $NUMBER 是否為非空數字。Step 3 的建立步驟失敗時(例如 --label 指定了不存在的 label,gh issue create 回 could not add label: 'P0' not found 且不輸出 URL),$NUMBER 是空字串,結果會建立並推送 idd--baseline。

實測(2026-10-17,v3.4.0):照範例組指令、建立失敗後,remote 上出現 idd--baseline,需要手動 git push origin :refs/tags/idd--baseline 清掉。

Type

bug

Expected

issue 沒建成功時,Step 3.6 不打 tag(graceful-skip,印出原因)。

Actual

打出並推送 idd--baseline;之後每次失敗都會因 idempotent 檢查而「skip」,掩蓋問題。

Suggested fix

Step 3.6 開頭加:

case "$NUMBER" in ''|*[!0-9]*) echo "⚠ no issue number — skipping baseline tag" >&2;; *) ...;; esac

另外 Step 3.A 的建立範例應在 URL 為空時停止,不往下走 Step 3.6 以後的步驟。


Current Status

Phase: verified
Last updated: 2026-10-26 by idd-verify(Claude-only,cloud session;body 經 REST 更新)

Key Decisions

Scope Changes

Blocking

  • (none)

Commits


Generated by Claude Code

Activity

  1. kiki830621 commented on Oct 26, 2026

    @kiki830621
    MemberAuthor

    Diagnosis

    Type

    bug

    Root Cause / Analysis

    我認為 root cause 是:idd-issue 從頭到尾沒有任何一步把「建立結果」轉成一個經過驗證的 $NUMBER,而 Step 3.6 又無條件信任 $NUMBER,因為:

    1. Step 3.A 只示範呼叫,不示範擷取與停止(plugins/issue-driven-dev/skills/idd-issue/SKILL.md:660-692)。範例是一個裸的 bash gh-egress.sh create … --label "$TYPE",沒有 URL=$(…)、沒有定義 $NUMBER(Step 4.6 用的 $NEW_ISSUE_NUMBER,:1204,同樣沒有任何地方定義),也沒有「建立失敗就停止」的規則。gh-egress.sh 成功時 exec 真正的 gh(scripts/gh-egress.sh:469、:481),所以 gh 失敗時 stdout 是空的;模型自己補上的 URL=$(…) / NUMBER=${URL##*/} 因此得到空字串,流程照常往下走。
    2. Step 3.6 對 $NUMBER 不做任何驗證(SKILL.md:1026-1056):
      • :1042 TAG="${BASELINE_FMT/\{N\}/$NUMBER}" → $NUMBER 為空時得到 idd--baseline。
      • :1043 DEFAULT_BRANCH 由 $GITHUB_REPO 查得,跟建立成敗無關,所以照樣解析成功。
      • :1046 idempotent 檢查只問 tag 是否存在;:1050 git tag … && git push … 兩個指令都會成功。
      • :1056 的 graceful-skip 只在指令失敗時生效;這條路徑上指令全部成功。
    3. 之後每次失敗都被 idempotent 分支蓋掉:第二次起印「already exists — skip (idempotent)」,看起來像正常行為。

    觸發來源比 issue 描述的更多:除了 label 不存在(gh 失敗、exit 1),gh-egress.sh 自己的拒絕(隱私機械網 exit 10、mention 網 exit 11 等,refusal band ≥ 10)stdout 也是空的。實測:

    gh-egress create(body 含本機 home 路徑)→ rc=10 stdout=''
    gh-egress create(body 含未驗證的 mention)→ rc=11 stdout=''
    

    所以任何一種建立失敗,只要模型繼續往 Step 3.6 走,結果都一樣。

    重現(throwaway probe,stub gh,不連網):stub gh issue create 印 could not add label: 'P0' not found 到 stderr 並 exit 1、gh repo view 回 main;透過 IDD_GH_BIN 走真的 gh-egress.sh;暫存 git repo + bare remote;Step 3.6 的 bash block 從 SKILL.md 原文抽出直接執行:

    could not add label: 'P0' not found
    create rc=1 URL='' NUMBER=''
    --- Step 3.6 run 1 ---
     * [new tag]         idd--baseline -> idd--baseline
    → tagged idd--baseline at main HEAD + pushed to origin
    --- Step 3.6 run 2 ---
    → idd--baseline already exists — skip (idempotent)
    

    加上 issue 建議的 case guard 後:''、abc、整條 URL 三種輸入都 skip 並印原因;42 正常打出 idd-42-baseline。

    PR #426 合併後問題仍在:#426 的 REST transport(scripts/lib/gh_egress_rest.py)對不存在的 label 一樣拒絕(check_labels),而且明文規定失敗時 stdout 為空 —— 失敗形狀不變,Step 3.6 照樣拿到空號碼。

    (本 issue 無附件。)

    Existing work

    (none) — 相關但不重疊:PR #426(in flight)改了 gh-egress.sh 的傳輸層與 idd-issue/SKILL.md 開頭與 Step 0.6 的文字,不處理本問題;本修正需在它之上 rebase。

    Impact

    • 影響的檔案:plugins/issue-driven-dev/skills/idd-issue/SKILL.md(Step 3.A、Step 3.6);測試 plugins/issue-driven-dev/scripts/tests/auto-tag/test.sh(或新的可執行 suite);release 記錄(CHANGELOG.md、plugin.json、marketplace.json)。
    • 影響的使用者流程:任何一次 /idd-issue 建立失敗(label 不存在、gh-egress 拒絕、網路/權限錯誤)且 auto_tag.enabled 為預設 on 時,remote 上會出現 idd--baseline,需要手動刪除;同一個 repo 之後的失敗都被 idempotent skip 掩蓋。/idd-all from-scratch 模式(Phase 1 跑 idd-issue)同樣受影響。

    Strategy

    • 先寫測試(RED):沿用 scripts/tests/blocked-by-mutation/test.sh 的做法 —— 從 SKILL.md 抽出 Step 3.6 block,在 stub gh + 暫存 repo + bare remote 上執行,NUMBER 取 '' / abc / 整條 URL / 42:前三者斷言 remote 沒有任何 tag、stderr 有 skip 原因;42 斷言出現 idd-42-baseline。附 positive control(拿掉 guard 必須 RED)。另加 drift-guard 斷言 Step 3.A 文字含擷取與停止規則。
    • Step 3.A 改成完整範例:擷取 URL=$(bash gh-egress.sh create …) 與 exit code,NUMBER="${URL##*/}",用 case "$NUMBER" in ''|*[!0-9]*) 驗證;不合格就印出 gh/wrapper 的錯誤與「issue 未建立 — 停止,不執行 Step 3.5 之後的步驟」,並在 Step 5 回報失敗後停止。同時設定 NEW_ISSUE_NUMBER="$NUMBER",讓 Step 4.6 用到的變數有定義。
    • Step 3.6 開頭加數字 guard(issue 建議的 case 形式)作為縱深防禦:不合格 → 印原因、graceful-skip,維持「never abort」鐵律;:1028 的「拿到 $NUMBER 之後」改為「拿到經驗證的 $NUMBER 之後」。
    • 更新 auto-tag drift-guard 的 needle;CHANGELOG + 版號(patch,與 3.6.0 的 PR feat: run /idd-all in Claude Code cloud sessions — REST egress and reads, (PR, attended) — 3.6.0 (#416) #426 / feat: 討論中持續更新 issue:問題變了改正文、診斷變了改 Diagnosis 留言、補充才新增 comment #424 協調)。

    Conflict Class

    B_resource_serialize
    共享資源是 plugins/issue-driven-dev/skills/idd-issue/SKILL.md:#363 也要改同一個 Step 3.6 block,#411 改同檔 Step 3.5,PR #426 也動這個檔案;同檔 issue 依 same-file rule 序列化(建議與 #411 綁成一組、先於 #363)。

    Complexity

    Simple — root cause 明確、修正自成一體:同一個 SKILL.md 的兩個相鄰段落 + 一個測試,並沿用既有 pattern(idd-clarify/SKILL.md:111 的 ^[0-9]+$ 驗證、blocked-by-mutation 的抽 block 測試法);Layer 1 不命中(改的是行為)、Layer 2 不命中(無新對外介面);Layer P 不命中:無跨檔順序依賴、Strategy 4 步、唯一碰到的 risk-sensitive 點是 git push,而本修正只在 push 之前多一條 skip 路徑,不新增或改變任何 push。
    Hard-gate: not triggered — 概念改動只在 skills/idd-issue/SKILL.md(Step 3.A + 3.6)與 scripts/tests/auto-tag/test.sh 兩檔(版號/CHANGELOG 屬 release 記錄,不是同一概念);Step 3.6 的 tag 片段沒有被其他檔案引用(idd-verify/SKILL.md:1385-1399 是另一份獨立的 tag 程式碼,用的是已知 issue 清單的 $N)。

    Risks

    Residue

    (none)

    Sister Concerns Filed (mid-diagnose, v2.47.0+ #528)

    Source: surfaced during /idd-diagnose #412 sister concern surfacing (Step 3.6)

    Vagueness Pre-check

    • V1: 2 — issue 指名位置(SKILL.md 約第 1042 行)並附上要加的 case guard 原文;第二項「Step 3.A 在 URL 為空時停止」沒有給出寫法,但要做什麼很明確。
    • V4: 2 — Expected「issue 沒建成功時,Step 3.6 不打 tag(graceful-skip,印出原因)」可直接觀察(remote 上無 tag、有原因訊息);Step 3.A 停止的部分沒有寫出驗收句。
    • Triggered: no — both axes ≤ 3

    Generated by Claude Code

  2. kiki830621 commented on Oct 26, 2026

    @kiki830621
    MemberAuthor

    Implementation Complete

    Branch idd/cluster-411-412-413(cluster with #411, #413; one PR)

    Checklist (synced from TaskList)

    Legend: - [x] done · - [~] skipped (may revisit) · - [-] won't fix (scope)

    Changes

    • 79b8b68: idd-issue stops when the issue was not created, and never tags idd--baseline
    • 9e3efd3: CHANGELOG Unreleased entries for the cluster

    Files Changed

     .../scripts/tests/baseline-tag-guard/test.sh       | 98 ++++++++++++++++++++++
     plugins/issue-driven-dev/skills/idd-issue/SKILL.md | 28 ++++++-
    

    Scope Compliance

    只動 Step 3.A 與 Step 3.6。group mode(Step 3.G)的取號問題在 #438、label 未檢查在 #439,不在本次範圍。

    Next: verification pending


    Generated by Claude Code

  3. kiki830621 commented on Oct 26, 2026

    @kiki830621
    MemberAuthor

    Verify: #412 → see cluster report

    Aggregate: PASS(cluster idd/cluster-411-412-413,與 #411、#412、#413 共用一份報告)

    完整報告(含本 issue 的分段、findings 與處理):#411 (comment)

    Engine: Claude-only(cloud session,Codex leg not run)。


    Generated by Claude Code

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions