Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions plugins/issue-driven-dev/scripts/tests/idd-edit/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,30 @@ for fixture in "$FIXTURES_DIR"/*/; do
fi
done

# ── Fixture 14 (#158): batch × R5 per-comment-refuse SKILL contract ──────────
# The batch/R5 semantics live in SKILL.md prose (the per-target outer loop is
# AI-executed bash); the falsifiable form is a prose-contract check integrated
# into this suite's counters. Decided 2026-07-11: (i) per-comment refuse +
# continue; override = all-targets + shared reason; exit 4 iff any refused.
SKILL_MD="$REPO_ROOT/plugins/issue-driven-dev/skills/idd-edit/SKILL.md"
f14() { # name mode(assert|refute) needle
local name="$1" mode="$2" needle="$3" hit=0
grep -qF -- "$needle" "$SKILL_MD" && hit=1
if { [ "$mode" = assert ] && [ "$hit" = 1 ]; } || { [ "$mode" = refute ] && [ "$hit" = 0 ]; }; then
PASS=$((PASS + 1)); echo "PASS: $name"
else
FAIL=$((FAIL + 1)); FAILED_TESTS+=("$name"); echo "FAIL: $name (needle: $needle)"
fi
}
f14 "f14a: R5 refuse records + continues (no batch kill)" assert 'REFUSED_TARGETS+=("$COMMENT_ID")'
f14 "f14a2: refuse branch continues the loop" assert '不中斷 batch(#158 語意 (i))'
f14 "f14b: batch outcome report format present" assert 'edited: $EDITED_COUNT / refused: ${#REFUSED_TARGETS[@]}'
f14 "f14b2: refused rows highlighted" assert '✗ REFUSED comment:'
f14 "f14c: override semantics = all-targets + shared reason" assert 'all-targets + reason 共用'
f14 "f14d: deferred-to-158 note removed (decision landed)" refute '設計 deferred to **[#158]'
f14 "f14e: single-target degenerate equivalence documented" assert '單 target 退化等價'
f14 "f14f: exit contract — 4 iff any refused" assert 'M>0 → exit 4'

echo ""
echo "================================"
echo "Results: $PASS passed, $FAIL failed"
Expand Down
28 changes: 25 additions & 3 deletions plugins/issue-driven-dev/skills/idd-edit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ allowed-tools:

**v2.81.0+ R4/R5 在 batch mode 下 per-target 評估**:
- R4 (`--replace` 必要 scope) 一次套用全 batch
- R5 (author check) **per-target**:N 個 targets 若 mixed OWNER + non-OWNER,目前 single-target 邏輯 refuse 第一個 non-OWNER target 並印 hint;`--override-user-content` 套用所有 targets(全 batch 啟用 override)
- 完整 batch + R5 semantics (per-comment refuse vs transactional abort vs pre-flight scan) 設計 deferred to **[#158](https://github.com/PsychQuant/issue-driven-development/issues/158)** follow-up
- R5 (author check) **per-target**:mixed OWNER + non-OWNER 批次採**語意 (i) per-comment refuse + 繼續**(#158 拍板 2026-07-11)— OWNER 的照做、non-OWNER 的逐條 refuse 記錄後 `continue`,絕不因單一 refuse 殺整批;`--override-user-content` 語意為 **all-targets + reason 共用**(全 batch 啟用 override,一個 reason 進所有 audit markers)
- 批次結束輸出 outcome report(`edited / refused` + 顯著標記,見 Step 7.5);exit contract:全數成功 → 0,任一 refused(M>0 → exit 4,單 target 退化等價 — 契約鎖於 tests/idd-edit fixture 14)

完整契約見 [batch-and-cluster.md](../../references/batch-and-cluster.md)。罕見場景:跨 issue 的 typo 統一修、補同一段 errata note、把多個 stale comment 統一標 deprecated。

Expand Down Expand Up @@ -183,13 +183,32 @@ done
**v2.81.0+ (#154 R3 fix for H7)**: Each resolved comment ID runs through the full pipeline (validate → fetch → preview → confirm → PATCH → verify) independently. Batch mode = N iterations of the same sequence, per-comment confirmation discipline preserved.

```bash
EDITED_COUNT=0 # incremented after each successful per-target Step 7 verify
REFUSED_TARGETS=() # R5-refused comment ids (#158 semantics (i) — recorded, not fatal)
for COMMENT_ID in "${RESOLVED_COMMENT_IDS[@]}"; do
# === Steps 1.5 through 7 run here, per-target ===
# The bash blocks below show single-target templates; in batch mode
# they execute N times, once per resolved COMMENT_ID.
# ...
done
```

#### Step 7.5: Batch outcome report(#158,語意 (i) 落地)

批次(含退化的單 target)跑完後**必須**輸出 outcome report — 部分成功絕不偽裝成全成功:

```bash
echo "── idd-edit batch outcome ──"
echo "edited: $EDITED_COUNT / refused: ${#REFUSED_TARGETS[@]}"
for rid in ${REFUSED_TARGETS[@]+"${REFUSED_TARGETS[@]}"}; do
echo " ✗ REFUSED comment:$rid — non-OWNER(override: --override-user-content --reason='...')"
done
# Exit contract(fixture 14):M=0 → exit 0;M>0 → exit 4。
# 單 target refuse 走同一路徑 = 現行可觀察行為不變。idd-edit 沿用自身碼空間
# (R5 refuse=4)— 不套 #227 的 gh-egress 碼帶(那是 egress wrapper 專屬)。
[ "${#REFUSED_TARGETS[@]}" -gt 0 ] && exit 4 # M>0 → exit 4
exit 0
```
```

### Step 1.5: Validate target (R5 author gate)
Expand All @@ -210,7 +229,10 @@ case $VALIDATE_EXIT in
echo "Hint: errata target was user-authored; manually run:" >&2
echo " /idd-edit comment:$COMMENT_ID --prepend-note --override-user-content --reason='errata clarification per IDD discipline'" >&2
fi
exit 4
# #158 語意 (i):記錄後 continue,不中斷 batch(#158 語意 (i))— 本 target 跳過
# Steps 2-7,其餘 targets 照常;單 target 退化等價(記錄 → loop 自然結束 → report → exit 4)。
REFUSED_TARGETS+=("$COMMENT_ID")
continue
;;
*) exit $VALIDATE_EXIT ;;
esac
Expand Down
Loading