cluster-PR mode 強制 PR 與 direct-commit path 衝突:override 未文件化且 --no-pr 行為未定義#99
Conversation
…Refs #96) cluster-PR mode 強制 PR path 的規則原本散落在 idd-implement SKILL.md:49 + batch-and-cluster.md:133,canonical 演算法表 pr-flow.md 沒提此 carve-out — 三檔互相矛盾;`--no-pr` 撞 cluster 時 flag 被無聲吃掉、行為亦未指定 (abort / warn / silent ignore)。 採用方案 A (issue body 列的 3 案,user 於 idd-all 對話選 A): 維持強制,但明示 + 一致。 pr-flow.md: - Resolution algorithm 表上方加註 cluster mode 是 precondition, pre-empts 整張表 (見新節) - 新增 `### Cluster mode override` subsection,規格 cluster pre-emption + explicit override notice 格式 (mirror fork detection 的 pattern): → cluster mode (N issues) → PR path enforced (overriding ...) 並寫明「no abort, no silent ignore」、single-issue 行為不變 batch-and-cluster.md: - line 133 cross-reference 從規則陳述改為指向 pr-flow.md 新節 的 pointer,rationale (cluster on direct-commit = stacked half-isolated changes) 整段搬到 pr-flow.md 新節為 source of truth idd-implement SKILL.md: - line 49「不接受 --no-pr」stub 升格為 spec'd behavior 描述, 指向 pr-flow.md 新節 Backward compat: single-issue invocation 行為完全不變 (cluster carve-out 只在 ≥2 #N 觸發);既有 cluster --pr explicit caller 不受影響。 Diagnose: see issue #96 comment 4483898985 Implementation Plan: see issue #96 comment 4483913507
Requirements review (PR #99 / #96)Verdict: CONDITIONAL PASS Coverage matrix
Findings
RecommendationCONDITIONAL PASS. The PR closes the documentation-contract part of #96 cleanly (L1 ✅, L3 ✅, L2 spec ✅), which is what Option A explicitly bought. The bash implementation of the override notice is the one piece of #96's Expected section that doesn't ship in this PR. Two acceptable paths:
Option 1 is reasonable given the explicit Plan-stage scope agreement and trivial echo cost; recommend Option 1 + immediate filing of the follow-up issue so the L2 runtime gap doesn't drift. |
Logic reviewer verdict (independent of other AIs)Verdict: Findings🔴 HIGH — Code/doc divergence un-flagged (Q4) 🟠 MEDIUM — Two pre-emptions, no precedence (Q1) 🟠 MEDIUM — Override notice format is not parallel (Q2) 🟡 LOW — Cluster detection trigger ambiguity (Q3) 🟡 LOW — 🟢 LOW (verified clean) — Anchor slug (Q5) 🟢 LOW (verified clean) — Single-issue backward compat (Q6) Logical consistency summary
RecommendationMerge eligible after addressing HIGH (add Implementation Status disclaimer or file follow-up issue tracking the Phase 0.5 bash update). The MEDIUM findings are spec-clarity polish — fix-in-place is cheap (≤5 lines added to the new subsection) and improves the "single source of truth" claim. LOW findings can be deferred to follow-up issues. The core logic — making cluster a documented pre-emption parallel to fork — is sound and resolves the #96 three-way doc contradiction. The remaining gaps are about completeness of spec coverage, not about logical contradictions in what was added. |
Security Review — PR #99Reviewer: Security (IDD verify ensemble) What I checkedPR #99 is doc-only ( Five-lens evaluation:
Findings
RecommendationAPPROVE from security perspective. Doc-only PR, override notice mirrors a pattern (fork detection) already exercised in production, no new attack surface introduced. The cluster precedence was already enforced in code (see issue #96 root cause: behaviour was correct but undocumented); this PR aligns documentation with reality. Merge is safe pending other reviewers' verdicts and the standard Step 0.8 auto-close trap scan on the final squash-merge commit body. |
Devil's Advocate review (PR #99 / #96)Verdict: CONDITIONAL PASS — but only because Option A's own scope contract excuses the worst flaw. If you take the PR at face value as "fixes #96", it is closer to FAIL. Pick one of those framings honestly before merging. Objection 1 (STRONG) — the spec/code gap is the L2 defect re-laundered as a feature
That is arguably worse than the status quo. Before: 3 files contradicted, but at least the silent override was consistent with the canonical table. After: 3 files agree, all promise a runtime notice, and the runtime emits nothing. A user who reads The Implementation Plan's defense ("改動 trivial,留作下游 follow-up") makes this a deliberate gap. Trivial cost (≈ 5-line Objection 2 (STRONG) — Option A cements the design tension instead of resolving itThe diagnosis observed (verbatim) that That means three months from now, the next user who runs cluster from a feature branch hits the same surprise, reads the new override notice, and asks "why is it doing this to me? I'm not on default." The notice doesn't answer that question — it just makes the override less invisible. The Diagnosis even said "「強制 PR」的理由部分成立(default branch 場景)、但被誇大(feature branch 場景理由不適用)". Option A perpetuates the exaggerated rationale. This isn't a blocker for this PR, but it is a flag that #96 will likely reopen. Option B (cluster accepts Objection 3 (MEDIUM) — override notice is too quiet to count as recourse
Fork detection gets away with the same one-liner because fork-PR is a technical necessity (can't push to upstream). Cluster-PR is a design preference — and the diagnosis admits the preference is exaggerated on feature branches. A discretionary override deserves louder signaling than a forced one. Either AskUserQuestion (Option C, attended) or abort-with- Objection 4 (LOW) — anchoring drift not actually reduced#96's grievance was "3 files contradicting". After this PR there are still 3 places referencing cluster behavior: RecommendationCONDITIONAL PASS with one hard condition: add the 5-line cluster branch to Step 0.5 bash in the same PR. Otherwise L2 is shipped as broken-by-design. If user insists on Option A's "smallest change" framing and refuses the bash addition, downgrade to PASS-with-debt and file the follow-up issue before merge (not after) — the doc-ahead-of-code window must be < 1 day, not "someday". Objections 2/3/4 are deferred to a future re-open of #96 if the design tension surfaces again, which the diagnosis itself predicted. Be honest about which framing you're choosing. |
Regression review — PR #99Reviewer: Regression (1 of 6-AI verify pool) Verdict: PASS WITH FINDINGSThe doc-only diff is clean on stale-quote sweep and anchor-stable, but introduces a documentation/code divergence in Findings[HIGH] Doc claims behavior the code does not implement — [MEDIUM] Step 0.5 numbered algorithm summary is now stale — [LOW] No regression in idd-verify / idd-close docs even though pr-flow.md scope includes them — [INFO] Anchor slug verified stable — GitHub auto-slugs [INFO] No stale verbatim quotes — Grep sweep for [INFO] Algorithm-table preface wording is surgical — The new preface at [INFO] Branch naming and PR title prefix preserved — [INFO] Single-issue invocation unchanged — RecommendationMerge as doc-only, then immediately file a follow-up issue to wire the cluster carve-out into Alternative: expand this PR before merge to add the bash + summary updates, closing #96 in one shot. Regression review · 1 of 6-AI verify pool · doc + cross-file consistency lens |
Codex review (PR #99 / #96)Verdict: CONDITIONAL PASS
Findings
RecommendationCONDITIONAL PASS. Before merging:
The anchor cross-references are correct; the rationale-preservation concern is minor and does not block merge. |
/idd-verify --pr 99 — Round 1 (#96)Aggregate verdict: 🟡 CONDITIONAL PASS — 5/6 reviewers; 1 explicit APPROVE (Security). 4 of 5 substantive reviewers converged on the same HIGH finding (doc/code gap); fix path depends on whether R2 extends scope to add bash impl or files follow-up. 6-AI verdict
Convergence map
R1 — R2 decision requiredThe HIGH finding (5/6 convergent) is genuinely blocking by IDD standards: the spec describes Phase 0.5 behavior that the bash doesn't honor, so #96's stated "Expected" (observable parity with fork detection) is not yet met. Three R2 paths:
User-facing decision dispatched in main thread. Secondary findings (R2 will address regardless of path)
Per-reviewer comments
Next: R2 path selection (a/b/c above). |
…0.5 bash (Refs #96) R1 6-AI verify (5/6 convergent HIGH): R1 doc-only spec'd a Phase 0.5 cluster override notice that the actual bash had no capability to emit (lines 108-144 had zero cluster detection). The L2 symptom #96 was filed to fix (silent override) survived byte-for-byte while the canonical doc started promising a notice — arguably worse than the original 3-file contradiction. R2 closes the gap by extending PR scope (Implementation Plan listed bash impl as out-of-scope "if necessary"; verify made it necessary). User opt-in via AskUserQuestion (option a: extend scope + R2 verify). idd-implement/SKILL.md Step 0.5 (~24 new lines): - Parse #N tokens in $@, set ISSUE_COUNT, derive CLUSTER_MODE=true if ≥2 - Pre-empt the resolution table: if CLUSTER_MODE → PATH_CHOICE="pr" unconditionally; on --no-pr or pr_policy=never collision, print `→ cluster mode (N issues) → PR path enforced (overriding ...)` - If fork ALSO detected (independent pre-emption), print fork notice too — both pre-emptions reach same destination (PR), each announces its own reason - Local algorithm summary (lines 99-106) gets new row 0 noting cluster pre-emption (closes Regression MED finding about stale local summary vs canonical pr-flow.md preface) pr-flow.md § Cluster mode override: - Inline rationale phrase "stacked half-isolated changes on default branch" verbatim (closes Codex MED about downstream-grep stability) - Add explicit "Fork + cluster co-occurrence" paragraph: both pre-emptions independently force PR; both notices print; no precedence question (closes Logic MED 1) Behavioral verification (8-case dry-run with mocked gh/jq): - T1: single issue, no flag → ask path (no cluster, backward compat ✓) - T2: cluster (3 #N), no flag → PR path, no notice ✓ - T3: cluster + --no-pr → "...(overriding --no-pr)" + PR ✓ - T4: cluster + --pr → PR, no notice (explicit, no collision) ✓ - T5: cluster + pr_policy=never → "...(overriding pr_policy=never)" ✓ - T6: cluster + --no-pr + never → "...(overriding --no-pr / pr_policy=never)" ✓ - T7: cluster + fork + --no-pr → cluster notice AND fork notice ✓ - T8: single + --no-pr → no-pr path (backward compat ✓) `bash -n` clean. R1 master verify: #99 (comment)
Security review R2 (PR #99 / #96)Verdict: APPROVE R1 factual error — acknowledgedMy R1 review (comment 4483939943) stated cluster override "was already implemented in Phase 0.5; this PR just documents existing reality." That was empirically wrong — the R1 bash (then lines 108–144) had zero cluster detection, as the convergent HIGH from four other reviewers correctly established. R2 ( R2 evaluation (~24 new lines of executable bash, Step 0.5)
|
Requirements review R2 (PR #99 / #96)Verdict: PASS R2 commit R1 → R2 closure table
Evaluation against the 5 R2 checkpoints
Independent verification
Remaining findingsNone blocking. One observation (non-blocking, NIT): the #96's Expected section ("single, documented, behaviorally explicit contract; every override prints an explicit notice; |
Regression review R2 (PR #99 / #96)Reviewer: Regression (1 of 6-AI verify pool) · R2 of commit Verdict: PASS — both R1 findings closed, no regressionR1 → R2 closure table
Verification results1. HIGH closure — Confirmed. Cluster detection ( 2. MED closure — Confirmed. Row 0 present at SKILL.md:100, anchored to 3. Single-issue backward compat — No regression. Trace 4. 5. Cross-reference integrity — Confirmed. 6. Test coverage — 8 cases are well-chosen (single/cluster × flag/policy/fork matrix, both backward-compat anchors T1/T8). One gap, INFO only: Remaining findings[INFO] Cluster + [INFO] SKILL.md retains pre-existing CRLF line terminators (predates R2 — HEAD~1 also CRLF). Not a regression; flagging only as latent hygiene. No blocking findings. R2 closes #96's doc-and-code gap in one shot; single-issue path provably unchanged. Regression review R2 · 1 of 6-AI verify pool · backward-compat + cross-file lens |
Logic review R2 (PR #99 / #96)Verdict: PASS R2 ( R1 → R2 closure table
Walk-through (verifies internal consistency)
New R2 findings (all non-blocking)
RecommendationMerge-eligible. R1 HIGH + both MEDs closed; MED 2 was closed better than the R1 recommendation (conditional accumulation vs. fixed string). The single new LOW is a doc-vs-glob nit deferrable to a follow-up. |
Devil's Advocate review R2 (PR #99 / #96)Verdict: CONDITIONAL PASS — R2 genuinely closes the R1 strongest objection (no longer theater), but Objection 2 from R1 survives untouched and the PR now over-claims one thing it does not deliver. Honest framing: merge-eligible, but the design tension is being papered over a second time. Objection 1 (was STRONG, now WITHDRAWN) — the bash impl is real, not theaterI attacked this hard expecting "moved the spec from one section to another." It is not that. R2 ( Objection 2 (STRONG — UNRESOLVED, this is now my strongest) — Option A still papers over the feature-branch tensionMy R1 objection stands verbatim and R2 added nothing to address it. R2 made the forced behavior more thoroughly enforced (now actually wired) without touching the legitimacy question the diagnosis itself raised: cluster + direct-commit on a feature branch Objection 3 (MEDIUM — UNRESOLVED) — the notice is still too quiet for a discretionary overrideOne line, no color, no separator, same stdout stream. R2 did harmonize the fork notice to Objection 4 (NEW, MEDIUM) —
|
Codex review R2 (PR #99 / #96)Verdict: PASS
R1 → R2 closure
New R2 findings
RecommendationMERGE — R1 HIGH is closed and the logic is functionally correct. The |
…ment only (Refs #96) R2 verify Devil's Advocate (Objection 4, empirically verified): the § Cluster mode override opening sentence claimed cluster mode for `idd-verify` / `idd-close` "pre-empts the Resolution algorithm" — but those skills never run path resolution. `idd-verify` resolves an input source; `idd-close` checks for unmerged PRs. Only `idd-implement` resolves PR-vs-direct-commit path. The original wording was a self-contradicting over-claim (a skill can't pre-empt an algorithm it never runs). Fix: split the sentence — cluster mode is a multi-issue mode for all three skills (shared branch + PR), but **path resolution is idd-implement's job**. idd-verify / idd-close are cluster-aware yet operate on the cluster's already-existing PR — they consume the path decision, they don't make it. Doc-only wording clarification; no logic/behavior change. DA pre-specified this exact fix shape ("conditional on a 1-sentence pr-flow.md verify/close clarification") and recommended MERGE. R2 master verify: #99 (Round 2, 6/6)
/idd-verify --pr 99 — Round 2 (#96)Aggregate verdict: ✅ PASS — 6/6 reviewers. R1's convergent HIGH (doc/code gap) closed by R2 commit R2 (commit 6-AI verdict (R2)
R1 → R2 finding closure
R2 new finding → R3 closure
Why R3 has no separate verify roundR3 ( Verify-fix convergence (R1 → R2 → R3)
Same-PR fix per Dogfood-the-fixThe new cluster-detection bash, run against this very PR's invocation history: Per-reviewer R2 comments
Next: human review of PR #99 → merge → |
Refs #96
Summary
Documents
cluster modeas a precondition that pre-empts thepr-flow.mdresolution algorithm, with explicit override notice (mirror fork detection) when--no-pr/pr_policy:"never"collides with cluster mode. Implements Option A from the diagnosis (user-selected inidd-allsession).The cluster-PR-mode-vs-
--no-prrule was previously split across 3 files (pr-flow.mdalgorithm table didn't mention it;idd-implementSKILL line 49 said "doesn't accept --no-pr" without specifying behavior;batch-and-cluster.mdline 133 stated the rule but in cross-references). Three files contradicted; behavior on collision was undefined.Changes (1 commit, 3 files, +23/-3)
references/pr-flow.md— add### Cluster mode overridesubsection + algorithm-table preface notereferences/batch-and-cluster.md— line 133 → pointer to pr-flow.md new sectionskills/idd-implement/SKILL.md— line 49 stub → spec'd behavior with explicit override notice formatDecision: Option A
Diagnosis surfaced 3 candidate approaches; user picked A (maintain forced PR, but explicit + consistent):
#N)Options B (cluster accepts
--no-prand degrades to shared branch) and C (AskUserQuestion on collision) deferred — re-open as follow-up if A proves insufficient in practice.Checklist
cbe6f5dR1 doc +5351116R2 bash +04c51cbR3 doc fix)/idd-close #96after mergeRelated
Generated by IDD
/idd-all 96. Do NOT add a GitHub close trailer (Closes/Fixes/Resolves) — IDD discipline requires manual/idd-closeafter merge to enforce checklist gate + closing summary.