From e9fb4938e51a2d504cfb6e8e9571c88f2fc1fa9d Mon Sep 17 00:00:00 2001 From: che cheng Date: Fri, 14 Aug 2026 05:44:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20/idd-list=20--parked=20=E5=9B=9E?= =?UTF-8?q?=E8=A8=AA=E6=A8=A1=E5=BC=8F=E3=80=81idd-all-chain=20=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E7=B4=8D=E5=85=A5=20bundle=20children=20(#310,=20#81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #310 IDD 有三個機制把 issue 移出視線,沒有任何機制把它移回來。ic-r011 叫 groomer 去 grep blocker:infeasible / blocker:waiting —— 實測這兩個 label 在本 repo 從來 沒有被建立過,而且沒有任何 periodic grooming 存在。parked 的 trigger 全是關於未來 世界狀態的散文命題,成立時不會發出任何事件,唯一路徑是人回頭讀。--parked 把所有 parked issue 連同各自的 trigger 原文列出(不摘要 —— 判斷 trigger 是否成立要看原話), 且絕不自動 unpark 或關閉。ic-r011 的那句宣稱改成實話而非願望。 #81 使用者視角裡 bundle child 與 chain spawn 沒有差別,差別只存在於實作歷史 (children 建立時已知、spawns 執行中冒出)。要求使用者為此切換 mental model 是把 內部差異外洩成介面負擔。ordered bundle 保留宣告順序,epic 本身不跑 implement/verify。 45/45 suites 綠。 --- .../.claude-plugin/plugin.json | 2 +- plugins/issue-driven-dev/CHANGELOG.md | 23 ++++++++++++++ .../references/ic-r011-checkpoint.md | 8 ++++- .../skills/idd-all-chain/SKILL.md | 20 ++++++++++++ .../issue-driven-dev/skills/idd-list/SKILL.md | 31 +++++++++++++++++++ 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/plugins/issue-driven-dev/.claude-plugin/plugin.json b/plugins/issue-driven-dev/.claude-plugin/plugin.json index 31e51a5..610fdef 100644 --- a/plugins/issue-driven-dev/.claude-plugin/plugin.json +++ b/plugins/issue-driven-dev/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "issue-driven-dev", "description": "v2.102.2: Deep Research light integration (#277, ruling b). idd-diagnose gains a non-binding pointer (the #111 superpowers hand-off shape: pure suggestion, no presence check, no dependency) fired when the diagnosis's quality depends on facts OUTSIDE the repo — with trigger examples AND counter-examples (the overly-broad-signal risk). Output flows back via '/idd-comment --type note' as summary + link, never full text (#116) — that is what keeps external research inside the audit trail. Both real-user misconceptions get canonical answers where they lived: research attaches AT diagnose (not after plan), and research vs implement are different phases' work, not substitutes. usecase-routing scenario 32 + a three-row internal-corpus vs external-world boundary table (idd-find / idd-ask / Deep Research). Deep integration stays a recorded residue until a plugin-dependable primitive exists.", - "version": "2.105.0", + "version": "2.106.0", "author": { "name": "Che Cheng" }, diff --git a/plugins/issue-driven-dev/CHANGELOG.md b/plugins/issue-driven-dev/CHANGELOG.md index 17cd3c4..cbf1d20 100644 --- a/plugins/issue-driven-dev/CHANGELOG.md +++ b/plugins/issue-driven-dev/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.106.0] - 2026-08-14 + +### Added + +- **`/idd-list --parked` — the revisit mechanism ic-r011 said already existed (#310)** — IDD has three ways to move an + issue out of sight (`parking-lot` label, `### Blocking`, the `when triggered` qualifier on `### Complexity`) and had + **none** to move it back. `references/ic-r011-checkpoint.md` told groomers to grep `blocker:infeasible` / + `blocker:waiting`; measured on this repo, **neither label has ever been created**, and no periodic grooming exists — + no schedule, no CI, no skill that looks back. That matters because a parked issue's trigger is always a prose + proposition about a future world state ("≥3 instances", "the first trace-stale incident"), and such conditions **emit + no event when they come true**. The only path is a human re-reading them. `--parked` lists every parked issue + **with its trigger condition verbatim** — not summarised, because judging whether a trigger fired requires the + original wording. It never unparks or closes anything: deciding whether that future arrived needs knowledge from + outside the repo. The claim in ic-r011 has been corrected rather than left as an aspiration. + +- **`/idd-all-chain` enqueues bundle children automatically (#81)** — user's observation: + 「bundle 處理到最後理論上是 idd-all-chain 的事情,chain 其實只是代表衍生的 issue 都要解玩」. From the user's side a + bundle child and a chain spawn are the same thing — a sub-issue waiting to be solved; the difference is purely an + implementation accident (children are known at filing time, spawns appear during execution). Making the user switch + mental models because of that accident leaks an internal distinction into the interface. Ordered bundles keep their + declared order (children have dependencies; issue-number sort would break them), and the epic itself still runs no + implement/verify — consistent with `milestone-first-tracking.md` on why epics have no diff to verify. + ## [2.105.0] - 2026-08-14 ### Added diff --git a/plugins/issue-driven-dev/references/ic-r011-checkpoint.md b/plugins/issue-driven-dev/references/ic-r011-checkpoint.md index 404fc62..293bd3c 100644 --- a/plugins/issue-driven-dev/references/ic-r011-checkpoint.md +++ b/plugins/issue-driven-dev/references/ic-r011-checkpoint.md @@ -71,7 +71,13 @@ When the user requests to skip one or more candidates, the skill SHALL present a | **(b) infeasible but understood** | Technically infeasible at this point but understood (e.g. "Need 100x budget to reproduce") | **Still files** as P3 with `blocker:infeasible` label. Audit: `Skipped: (b) infeasible — filed as #NNN with blocker:infeasible label` | | **(c) blocked on external state** | Waiting on external state that will likely change (e.g. "Wait for GitHub Actions API to add X") | **Still files** as P3 with `blocker:waiting` label. Audit: `Skipped: (c) blocked-on-external — filed as #NNN with blocker:waiting label` | -**Net effect**: only (a) avoids filing. (b) and (c) preserve the parking lot — periodic backlog grooming can grep `blocker:infeasible` or `blocker:waiting` to revisit when conditions change. +**Net effect**: only (a) avoids filing. (b) and (c) preserve the parking lot. + +> **關於「periodic backlog grooming」(#310,2026-08-14 更正)**:本段原本寫著 grooming「可以 grep `blocker:infeasible` / `blocker:waiting` 來回訪」。實測本 repo:**這兩個 label 一次都沒有被建立過**,而且**沒有任何 periodic grooming 機制存在** —— 沒有排程、沒有 CI、沒有任何 skill 會主動回頭看 parked issue。 +> +> 這件事重要,因為 parked issue 的 trigger 條件全是**關於未來世界狀態的散文命題**(「等 ≥3 instances」「首次 trace-stale 實害事故」)。這類條件成立時**不會發出事件** —— 沒有 webhook、沒有訊號、沒有任何東西會通知 repo。唯一能發現「trigger 已成立」的路徑是**人主動回頭讀**。 +> +> 現在提供的是 `/idd-list --parked`(見 idd-list SKILL):它把所有 parked issue 連同**各自的 trigger 條件原文**列出來,讓一次人工回訪變得可行且便宜。它**不是**自動化 —— 它只是把回訪從「要先想起有這回事、再自己拼出清單」降成「跑一個指令」。若之後真的要自動化,那需要先讓 trigger 條件變成機器可判定的東西,那是另一個題目。 ### 1.5 Skip taxonomy AskUserQuestion structure (per-candidate) diff --git a/plugins/issue-driven-dev/skills/idd-all-chain/SKILL.md b/plugins/issue-driven-dev/skills/idd-all-chain/SKILL.md index 9c4f973..e802146 100644 --- a/plugins/issue-driven-dev/skills/idd-all-chain/SKILL.md +++ b/plugins/issue-driven-dev/skills/idd-all-chain/SKILL.md @@ -43,6 +43,26 @@ allowed-tools: Take 1 root issue, recursively solve any chain-eligible spawned issues (from sub-skill sister sweeps / verify follow-ups / mid-plan tangentials / sister concerns), all on **ONE cluster branch** and reviewed via **ONE PR**. +## Bundle epic 的 children 自動入列(#81) + +`idd-all-chain #ROOT` 若偵測到 ROOT 是 **bundle epic**(由 `idd-issue --bundle-mode` 建出、body 帶 children 清單),**自動把它的 children 全部 enqueue**,與 chain 自己 spawn 出來的 issue 同等對待。 + +使用者原話(2026-05-12): + +> 「bundle 處理到最後理論上是 idd-all-chain 的事情,chain 其實只是代表衍生的 issue 都要解玩」 + +**為什麼**:在使用者的視角,bundle children 與 chain spawns **沒有差別** —— 都是「為了主任務而衍生、等著被解掉的 sub-issue」。差別只存在於實作歷史:children 是**建立時**就知道的,spawns 是**執行中**才冒出來的。要求使用者因為這個實作細節切換 mental model(從 `/idd-all-chain #epic` 改打 `/idd-all #epic #c1 #c2 #c3 --pr`),是把內部差異外洩成介面負擔。 + +**偵測**:ROOT 的 body 含 bundle children 區塊(`idd-issue --bundle-mode` 的產出格式),或 ROOT 帶 `epic` label 且有 sub-issue 關聯。偵測不到就照現行行為跑,**不猜**。 + +**入列後的行為與 chain spawn 完全相同**:同一條 cluster branch、同一個 review PR、每張各自跑完整 lifecycle、停在 verified 不 auto-close。 + +**兩個邊界**: + +1. **`--bundle-mode ordered` 的順序要保留** —— ordered bundle 的 children 之間有相依性,入列順序必須照 body 的宣告順序,不可依 issue number 排序。 +2. **epic 本身不跑 implement / verify** —— 它是 bundle 的容器,與 `references/milestone-first-tracking.md` 對 Epic 的判斷一致(沒有單一 root cause、沒有 diff)。epic 在所有 children 都 verified 之後才進入可結案狀態。 + + ## 核心原則 > **`/idd-all-chain` is a thin shell over `/idd-all`.** 90% of pipeline logic stays in `/idd-all` (Phase 0-6 unchanged); chain shell only orchestrates the recursion + cluster branch + cluster PR. diff --git a/plugins/issue-driven-dev/skills/idd-list/SKILL.md b/plugins/issue-driven-dev/skills/idd-list/SKILL.md index 7b74fc5..5fd7e20 100644 --- a/plugins/issue-driven-dev/skills/idd-list/SKILL.md +++ b/plugins/issue-driven-dev/skills/idd-list/SKILL.md @@ -67,6 +67,7 @@ TaskCreate(name="audit_closes_marker", description="Step 4 (v2.75.2+, #151; 分 | `--limit` | `20` | 最多顯示筆數 | | `--repo` | _(from config)_ | 覆寫 config 的 repo | | `--audit-closes` | off | 旗標:把 **CLOSED** 的 issue 依其 `## Closing Summary` marker 分類(`compliant` / `casing` / `present` / `missing`,#295)。`missing` = **所有 comment 的原始文字裡都找不到**該 heading,可能是被 commit / PR-body close keyword auto-close 繞過 `/idd-close` gate 的受害者(#151);`present` 未經驗證、同樣帶 ⚠;**只有 `missing` 提 `--retroactive`**。`--state` 仍是預設 `open` 時隱含切到 `closed`。底層 primitive:`scripts/check-closed-without-summary.sh`(standalone / cron 可直接呼叫)| +| `--parked` | off | **回訪模式(#310)**:只列被移出視線的 issue,並把**各自的 trigger 條件原文**一併印出。三個來源:`parking-lot` label、`### Complexity` 的 `when triggered` 限定詞、`### Blocking` 區塊非空。輸出每列為 `#N title` + 縮排一行 `⏸ trigger: <原文>`;`--state` 隱含 `open`。**這不是自動化** —— parked 的 trigger 是關於未來世界狀態的散文命題,成立時不會發出任何事件,所以唯一的路徑是人回頭讀;本 flag 只是把那件事變便宜 | | `--discussions` | off | **Opt-in**(#221):同場 surface GitHub Discussions 的 actionable 項(Q&A/Ideas、未答、未被任何 issue 引用)。契約 + GraphQL 見 [`references/discussions-intake.md`](../../references/discussions-intake.md) | ### Step 2: Fetch Issues @@ -268,6 +269,36 @@ def get_leader(refs_list, body, rule): 抽出 `blocked_reason`(Blocking 區塊首行或 label 名),掛到 issue entry。 +### Step 3.9: Parked review(`--parked`,v2.106+,#310) + +**僅當 `--parked`** 才執行;無 flag 完全 no-op。 + +IDD 有三個機制會把 issue 移出視線,**沒有任何機制會把它移回來**:`parking-lot` label、`### Blocking` 區塊、`### Complexity` 的 `when triggered` 限定詞。`references/ic-r011-checkpoint.md` 原本宣稱 periodic grooming 可以 grep `blocker:*` label 來回訪 —— 實測那兩個 label **從來沒有被建立過**,而且沒有任何 periodic 機制存在(#310)。 + +流程: + +1. 取 open issues(含 `labels`、`body`、最新 Diagnosis comment) +2. 挑出符合任一來源者 +3. **抽出 trigger 條件原文**(不摘要、不改寫 —— 判斷 trigger 是否成立要看原話): + - `parking-lot` → 找 body 或 diagnosis 裡說明 park 理由的句子;找不到就印 `(no trigger recorded)`,那本身就是要修的東西 + - `when triggered` → 印限定詞括號內的全文 + - `### Blocking` → 印該區塊內容 +4. render: + +``` +Parked (3) — 每一項的 trigger 條件是關於未來的散文命題,不會自己發出訊號: + + #144 codify 'AI design 階段過抽象' as plugin-level principle + ⏸ trigger: ≥3 instances(目前 #1) + + #157 spec.md @trace blocks lack auto-update + ⏸ trigger: ≥1 次 trace-stale 實害事故 +``` + +5. footer 印 `(parked: N — 上次回訪日期不可知,IDD 不記錄)`。**不要**宣稱「已檢查過 trigger」—— 這個 flag 只負責把條件攤開給人看。 + +**鐵律**:本 step **絕不自動 unpark、也絕不自動關閉** parked issue。判斷「那個未來狀態是否已經發生」需要 repo 之外的知識;工具把條件列出來,人來判斷。 + ### Step 4: Format Output ```