From 090a92ecbb43e835b340ed6a27286ebcad664826 Mon Sep 17 00:00:00 2001 From: che cheng Date: Sat, 11 Jul 2026 10:28:28 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20IDD=5FCALLER=20registry=20=E2=80=94=20c?= =?UTF-8?q?odify=20values=20+=20reader=20contract=20(#161)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Central registry (references/idd-caller-registry.md) for the IDD_CALLER env-var convention: 5 current values (4 skill callers of process-attachments.sh + the idd-comment-errata sub-mode), the reader contract (manifest fetched_by, unset fallback idd-skill), value-shape convention, and the deliberately-informal validation stance. Drift-guard does a dynamic tree sweep — any future IDD_CALLER value added without a registry row turns the suite RED (the missing review surface from #154). Refs #161 --- .../references/idd-caller-registry.md | 48 +++++++++++++++++ .../scripts/process-attachments.sh | 3 +- .../scripts/tests/idd-caller-registry/test.sh | 52 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 plugins/issue-driven-dev/references/idd-caller-registry.md create mode 100755 plugins/issue-driven-dev/scripts/tests/idd-caller-registry/test.sh diff --git a/plugins/issue-driven-dev/references/idd-caller-registry.md b/plugins/issue-driven-dev/references/idd-caller-registry.md new file mode 100644 index 0000000..94277ff --- /dev/null +++ b/plugins/issue-driven-dev/references/idd-caller-registry.md @@ -0,0 +1,48 @@ +# IDD_CALLER Registry(#161) + +`IDD_CALLER=` 是 IDD skills 呼叫 helper scripts 時的 **caller 身分慣例**。本檔是唯一的 +中央註冊表 — 新值加入時**必須**同步登記一列(drift-guard `scripts/tests/idd-caller-registry/` +以動態 grep 對照樹上實值與本表,漏登記即 RED)。 + +## 語意(semantic intent) + +**Audit trail** — 記錄「哪個 skill 觸發了這次 helper 呼叫」,寫入產物供事後考古。 +目前**沒有** conditional behavior(helper 不依 caller 改變行為);若未來某 helper 需要 +對特定 caller 差異化,先在本檔把該 value 的語意升級為 behavioral contract 再實作。 + +## 值域慣例 + +- 基本形:**skill name**(`idd-`)— 例 `idd-diagnose` +- 子 mode 形:**skill name + `-` 後綴** — 例 `idd-comment-errata`(idd-comment 的 errata flow) +- charset:`[a-z-]`(小寫 + dash) + +## Registry + +| Value | Emitted by | Reads it | Semantic intent | +|-------|-----------|----------|-----------------| +| `idd-diagnose` | `skills/idd-diagnose/SKILL.md` Step 1.5(attachments `download`)| `scripts/process-attachments.sh` | manifest `fetched_by` audit trail | +| `idd-implement` | `skills/idd-implement/SKILL.md` Step 1.2(attachments `check`)| 同上 | 同上 | +| `idd-verify` | `skills/idd-verify/SKILL.md` Step 0(attachments `check`)| 同上 | 同上 | +| `idd-close` | `skills/idd-close/SKILL.md` Step 1.4(attachments `verify`)| 同上 | 同上 | +| `idd-comment-errata` | `skills/idd-comment/SKILL.md` errata flow(#154,經 `/idd-edit` 委派)| 同上 | errata 委派鏈的 caller 身分(子 mode 形式首例)| + +## Reader contract + +**`scripts/process-attachments.sh`** 是目前唯一 reader:把 `$IDD_CALLER` 記入 +`_manifest.json` 的 **`fetched_by`** 欄位。**Unset 時 fallback `idd-skill`** +(`${IDD_CALLER:-idd-skill}`)— 代表「非 skill 直呼」(手動 CLI / 測試)。 +manifest 消費端(下游 skills)把 `fetched_by` 當純 audit 資訊,不得據以分流。 + +## 新值加入 checklist + +1. 本表加一列(value / emitter / reader / intent) +2. 跑 `bash scripts/tests/idd-caller-registry/test.sh` 確認綠 +3. 若新值需要 reader 端差異化行為 → 先在本檔升級語意宣告,再改 helper + +## Validation 姿態 + +**Informal(刻意)** — helper **不**驗證 value 在 allowed list(無 warn/reject)。 +理由:現無 drift 事故,runtime validation 是未觸發的複雜度;anti-drift 由本表 + +drift-guard 的**編輯時**對照承擔。若未來出現「未知 caller 造成實害」再升級。 + +Refs #161(成案)、#154(第 6 值 `idd-comment-errata` 的 silent 加入即本表動機)。 diff --git a/plugins/issue-driven-dev/scripts/process-attachments.sh b/plugins/issue-driven-dev/scripts/process-attachments.sh index 30f25fd..70c957d 100755 --- a/plugins/issue-driven-dev/scripts/process-attachments.sh +++ b/plugins/issue-driven-dev/scripts/process-attachments.sh @@ -15,7 +15,8 @@ # process-attachments.sh verify [--repo owner/repo] # # Env: -# IDD_CALLER — name of calling skill (recorded in manifest fetched_by) +# IDD_CALLER — name of calling skill (recorded in manifest fetched_by); +# allowed values + semantics: references/idd-caller-registry.md (#161) # # Exit codes: # 0 — success / no attachments / up-to-date diff --git a/plugins/issue-driven-dev/scripts/tests/idd-caller-registry/test.sh b/plugins/issue-driven-dev/scripts/tests/idd-caller-registry/test.sh new file mode 100755 index 0000000..c2c1471 --- /dev/null +++ b/plugins/issue-driven-dev/scripts/tests/idd-caller-registry/test.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# test.sh — drift-guard for the #161 IDD_CALLER registry. +# +# #161: the IDD_CALLER env-var convention spans 5+ SKILL.md emitters and the +# process-attachments.sh reader (manifest `fetched_by`) with no central +# registry — new values get added silently (PR #159 added the 6th with zero +# review surface). The registry (references/idd-caller-registry.md) is the +# review surface; THIS suite is the anti-drift lock: any IDD_CALLER= +# in the tree MUST appear in the registry, so a future silent addition turns +# this suite RED instead of drifting. +# +# Usage: bash test.sh (exit 0 = all pass, 1 = any fail) + +set -u + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PLUGIN_ROOT="$HERE/../../.." +REGISTRY="$PLUGIN_ROOT/references/idd-caller-registry.md" +READER="$PLUGIN_ROOT/scripts/process-attachments.sh" + +HELPERS="$HERE/../../lib/assert-helpers.sh" +[ -f "$HELPERS" ] || { echo "✗ missing $HELPERS — cannot run suite" >&2; exit 1; } +. "$HELPERS" + +assert_file_exists "registry exists" "$REGISTRY" + +# ── ANTI-DRIFT CORE: every IDD_CALLER= in the tree is registered ── +# Dynamic sweep (not a static list) so a silently-added 7th value fails here. +TREE_VALUES=$(grep -rhoE 'IDD_CALLER=[a-z][a-z-]*' "$PLUGIN_ROOT/skills" "$PLUGIN_ROOT/scripts" 2>/dev/null \ + | sed 's/^IDD_CALLER=//' | sort -u) +if [ -z "$TREE_VALUES" ]; then + fail "tree sweep found no IDD_CALLER values" "grep returned empty — sweep broken?" +else + for v in $TREE_VALUES; do + if grep -qF "\`$v\`" "$REGISTRY" 2>/dev/null; then + pass "registry covers tree value: $v" + else + fail "registry missing tree value: $v" "add a row to $REGISTRY (this is the #161 review surface)" + fi + done +fi + +# ── registry documents the reader contract ── +assert_output_grep "registry names the reader (process-attachments.sh)" "process-attachments.sh" "$REGISTRY" +assert_output_grep "registry documents manifest fetched_by field" "fetched_by" "$REGISTRY" +assert_output_grep "registry documents the unset default" "idd-skill" "$REGISTRY" +assert_output_grep "registry states the semantic intent (audit trail)" "audit trail" "$REGISTRY" + +# ── cross-links: reader script points back at the registry ── +assert_output_grep "reader script cross-links the registry" "idd-caller-registry" "$READER" + +print_summary "idd-caller-registry (#161)"