feat(idd-close): Step 6.5 distribution sync chain detection (#45)#67
Conversation
… detection (Refs #45) NEW reference doc covering: - Detection helpers (is_plugin_marketplace_member, has_binary_wrapper, infer_distribution_type) - D3 mixed-type superset rule (chain plugin-update only, contingent on #66 audit) - Skill resolution table - Escape hatch (IDD_DISTRIBUTION_SYNC_PROMPT=false env var) - Extension protocol for unlisted distribution patterns - Smoke matrix fixtures (manual until #62 test infra) Per Plan tier #45 D1-D5 decisions. SKILL.md Step 6.5 in next commit will delegate to this contract.
…45) Inserts Step 6.5 between Step 6 (auto-update phase=closed) and Step 7 (batch close): - Detection delegated to references/distribution-detection.md canonical contract - Silent skip path for non-distribution repos + IDD_DISTRIBUTION_SYNC_PROMPT=false env var - AskUserQuestion 3-option as prose (per #47 P1 finding 2 — agent-level tool, not bash function) - D3 superset table: plugin+mcp/cli → chain plugin-update only (Phase 1.5 cascade) - Audit trail PATCH appends ### Distribution Sync section to closing comment regardless of choice - Failure-mode summary covers gh api / parse / network failures Step 0.5 Bootstrap Task List adds distribution_sync_chain_detection entry between auto_update_body and report_result (per skill bootstrap rule: every step listed in skill body MUST have a TaskCreate entry). Per Plan tier #45 D1-D5 decisions: - D1 walk-up to $HOME (find_idd_config convention) - D2 keywords: gh release download / curl github releases (extension hook in ref doc) - D3 mixed-type → plugin-update only (contingent on #66 audit) - D4 v1 no --source-issue flag (graceful, sister issue tracks caller-side) - D5 IDD_DISTRIBUTION_SYNC_PROMPT=false rollback hatch
…(Refs #45) In-scope dependency caught during Step 5.7 sister bug sweep: Step 6.5 PATCH references $CLOSING_COMMENT_ID expected to be set in Step 4, but Step 4 was a fire-and-forget gh issue comment without URL capture. Without this fix, Step 6.5 audit trail PATCH would fail with empty ID. 3-line addition: capture URL via tail -1 + extract numeric ID via sed regex. No behavior change for non-distribution repos (Step 6.5 silent-skips before PATCH path is reached).
Verify Report — PR #67 (Round 1)EngineCodex CLI (gpt-5.5 xhigh) + Agent Team (regression + devil's advocate completed; requirements/logic/security hit Anthropic API usage limit reset 7:20pm Taipei — degraded mode but 3 independent sources converge) AggregateFAIL — 5 P1 blocking findings, 4 P3 follow-up The 3 reviewers (Codex / regression / devil's advocate) independently converge on the same critical finding: Scope coveragePR refs: #45, #66 Blocking findings (P1) — must fix before merge
P3 follow-up advisories (post-fix)
Devil's Advocate WITHSTOOD
Scope check
Engine degradation note3 of 5 Claude reviewers (requirements / logic / security) hit Anthropic API usage limit (resets 7:20pm Taipei) and produced empty findings files. This verify ran with 3 independent sources instead of 6 (Codex + regression + devil's advocate). The 3 sources nonetheless converge strongly on the same P1 findings — verify discipline preserved despite degraded ensemble. Re-running full 6-AI ensemble after fixes ship is recommended for full Plan tier coverage. Next: in-scope fixes + re-verifyThe 5 P1 findings are all in-scope (correctness fixes for #45's own deliverable, not separate concerns). Fix path:
Re-verify with full 6-AI when usage limit resets. |
Round 1 verify (3-source convergence: Codex + regression + devil's advocate)
flagged 5 P1 blocking findings. All 5 fixed in this round:
F1 — marketplace.json schema mismatch (P0/P1):
Real schema is "source": "./plugins/X" string, not {"git": "..."} object.
Updated is_plugin_marketplace_member to:
- parse plugins[].source as string (with select(type=="string") guard)
- resolve relative to manifest dir + canonicalize via pwd -P
- match if plugin_dir == repo_root OR plugin_dir is inside repo_root tree
Empirically validated 5/5 cases including dogfood (this very repo → plugin).
F2 — wrapper regex misses real-world wrappers (P0/P1):
Real wrappers (che-apple-mail-mcp, agent-cacher) construct GitHub URLs in
variables (API_URL=, asset_url=) and call curl/gh api on a separate line.
Old regex was line-anchored. New pattern matches anywhere in bin/*.sh:
gh release download | gh api .* /releases | api.github.com/.*/releases
| github.com/.*/releases/(download|tags|latest)
Validated against 13 PsychQuant MCP wrappers + agent-cacher CLI wrapper.
F3 — helpers undefined when called (P1):
Step 6.5 SKILL.md called infer_distribution_type and patch_closing_comment_append
but defs lived only in references/distribution-detection.md. Inlined helpers
inside Step 6.5 detection block, BEFORE first call. Removed duplicate def
in audit trail section (now references the inlined version).
F4 — Step 4 closing comment ID capture brittle (P1):
Old: `gh issue comment ... 2>&1 | tail -1` mixed stderr into stdout;
sed without -n returned input unchanged on no-match → silent corruption.
New: capture stdout-only with || abort on gh failure;
use sed -nE '...p' to print only on match;
explicit empty-check with abort.
F5 — D3 superset rule unverified (P1):
Plan/contract claimed "chain plugin-update only" relying on Phase 1.5 cascade
per common-plugins.md (filed #66 to audit empirically). Until #66 confirms,
v1 default is "chain both with explicit ordering" (binary-deploy first, then
plugin-update). Idempotent regardless of cascade behavior. v2 superset rule
pending #66.
Bonus fixes:
- F6 (P3): replaced `exit 0 # proceed to Step 7` literal bash exit (which
would terminate close skill) with agent-level branching prose comment.
- == /Users/che edge case fixed via do-while-style loop.
- Symlink resolution via `pwd -P` for /Users vs /private/var on macOS.
…oc consistency (Refs #45) Round 2 verify caught 2 NEW P1 introduced by round-2 + 2 PARTIAL doc inconsistencies: NEW-P1-1: REPO_ROOT undefined causing infinite loop / false positive on legacy repos - idd-close didn't define REPO_ROOT before Step 6.5 detection invocation - Empty string triggered: cd "" succeeds → resolved_root='', dirname '.' loops forever - Fix: Step 6.5 prelude resolves via 'git rev-parse --show-toplevel' (fallback pwd) - If unresolvable (not in git tree), audit-skip with explicit reason + advance to Step 7 NEW-P1-2: SKILL_NAME / plugin name not mechanically resolved → audit refs undefined var - Old code referenced $SKILL_NAME but never set it from helper output - is_plugin_marketplace_member returned only boolean — no name extraction - Fix: NEW resolve_plugin_name() helper returns matched plugin's .name field - Detection invocation now sets PLUGIN_NAME for plugin/plugin+* types - Composes $CHAIN_DESC table-driven from (DISTRIBUTION_TYPE, PLUGIN_NAME) before AskUserQuestion - If type=plugin* but PLUGIN_NAME unresolvable → demote to n/a (avoid malformed chain) - Replaces $SKILL_NAME with $CHAIN_DESC throughout audit/AskUserQuestion blocks PARTIAL-1: Top-level summary table still said "plugins[].source.git" (object schema) - Fix: row 17 now says "plugins[].source (string \"./plugins/<name>\")" - row 18 'mcp' detection signal updated to enumerate broadened pattern - Mixed types now show explicit ordering chain (D3 v1) instead of plugin-update only PARTIAL-2: Failure-mode summary claimed marketplace.json malformed → audit error - jq 2>/dev/null swallowed parse errors → no error audit fired - Fix: clarify behavior is "demote to n/a + WARN to stderr";simpler audit schema Smoke validated round-3: - resolve_plugin_name correctly returns 'issue-driven-dev' for this repo, 'che-apple-mail-mcp' for plugin dir, empty for che-claude-config (not a plugin), first match for monorepo host - REPO_ROOT git rev-parse works in-tree;pwd fallback for non-git contexts
Verify Report — PR #67 (Round 3)EngineCodex CLI (gpt-5.5 xhigh) standalone — Anthropic Claude reviewers continue to be limit-blocked (resets 7:20pm Taipei). Convergent multi-round trace:
AggregatePASS — 0 P1 blocking, 3 minor doc-drift advisories Round-3 commit Per-fix verdict (round-3)
Round-3 new advisories (non-blocking, P3)
Empirical smoke validation (round-3)Engine note (degraded mode)Anthropic API limit blocked 5-Claude-reviewer team across all 3 verify rounds. Codex CLI (gpt-5.5 xhigh, independent OpenAI infra) carried all 3 rounds. Round 1 also had regression + devil's advocate complete before limit triggered (3 sources convergent on initial findings). Plan tier ideal would re-run full 6-AI after limit resets — but Codex's track record across 3 iterations (caught 5 P1 + 2 NEW P1 + verified all fixes) demonstrates the verification discipline survives degraded engine. Scope check
Next: triage 3 P3 advisories + merge decisionPer Step 5b (mandatory triage):
After triage: PR ready for human review + merge + |
A1 — failure-mode REPO_ROOT row: clarify pwd fallback covers non-git case;
unresolvable branch fires only when both git rev-parse AND pwd fail.
A3 — Extension protocol: removed contradiction ("Don't edit SKILL.md" vs
"edit inline implementation in SKILL.md"). Now correctly states
two-location update is required since skills don't source reference
markdown at runtime.
A2 monorepo host disambiguation filed as #68 follow-up (out-of-scope here).
Refs #45
Summary
/idd-closeStep 6.5 — distribution-aware close-tier checkpoint that surfaces user-facing channel sync (plugin marketplace / MCP binary / CLI binary) at the moment the issue closes. Closes the gap where fixes land in main butmarketplace.jsondoesn't bump, leaving users with stale binary on/plugin update.Per Plan tier issue body Step 4.7 scope clarification: this PR is single-repo (
PsychQuant/issue-driven-development). Cross-repo--source-issueflag inplugin-update/mcp-deploy/cli-deployis deferred to a sister issue inpsychquant-claude-plugins.Changes (2 commits)
0c7431adocs(distribution-detection): add canonical contract for distribution detection (Refs feature: /idd-close should chain to plugin-update / mcp-update / cli-update for distribution-aware close #45)4765092feat(idd-close): add Step 6.5 distribution sync chain detection (Refs feature: /idd-close should chain to plugin-update / mcp-update / cli-update for distribution-aware close #45)Files Changed
plugins/issue-driven-dev/references/distribution-detection.md(+189) — canonical contract foris_plugin_marketplace_member/has_binary_wrapper/infer_distribution_typehelpers + D3 superset rule + extension protocol + smoke fixture matrixplugins/issue-driven-dev/skills/idd-close/SKILL.md(+128) — insert Step 6.5 between Step 6 and Step 7;Step 0.5 Bootstrap Task List addsdistribution_sync_chain_detectionentryPlan tier highlights
$REPO_ROOT→$HOME(find_idd_config convention)gh release download+curl.*github.com.*releases(extension hook in ref doc)plugin-updateonly — superset cascade percommon-plugins.md(audit filed as #66)--source-issueflag (graceful;sister issue tracks caller-side)IDD_DISTRIBUTION_SYNC_PROMPT=falsesilently skips promptTangential filed
common-plugins.mdplugin-updatePhase 1.5 cascade claim (D3 dependency)Checklist
/idd-verify --pr <N>)/idd-close #45after merge🤖 Generated by
/idd-implementon PR path. Do NOT addCloses #45— IDD discipline requires manual/idd-closeafter merge to enforce checklist gate + closing summary.