From 6c3e37a02d56df9d83bfa95b337002d180b9fb1a Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 20 Feb 2026 16:43:51 -0800 Subject: [PATCH 1/6] docs: require title and author in dedupe action matrix output --- skills/openclaw-github-dedupe/SKILL.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/skills/openclaw-github-dedupe/SKILL.md b/skills/openclaw-github-dedupe/SKILL.md index 3274c03..c6a06d2 100644 --- a/skills/openclaw-github-dedupe/SKILL.md +++ b/skills/openclaw-github-dedupe/SKILL.md @@ -77,7 +77,7 @@ This workflow is designed for high-velocity maintainers and external contributor ## Outputs -- Per-item action matrix with explicit status (`KEEP_OPEN_CANONICAL`, `CLOSE_DUPLICATE`, `KEEP_OPEN_RELATED`, `KEEP_OPEN_UNRELATED`, `MANUAL_REVIEW_REQUIRED`). +- Per-item action matrix with explicit status (`KEEP_OPEN_CANONICAL`, `CLOSE_DUPLICATE`, `KEEP_OPEN_RELATED`, `KEEP_OPEN_UNRELATED`, `MANUAL_REVIEW_REQUIRED`) and each row showing title + author. - Evidence matrix with root-cause mapping, scope deltas, and risk blockers. - Credit chain and attribution rationale (single-credit default, dual-credit only by exception). - Required command set (dry-run and execution mode): close, comment, label, merge, and changelog actions. @@ -185,16 +185,19 @@ Use `update_plan` at runtime and keep one in-progress step at a time. - Dry run: `` ### Per-item action matrix (required) -- `pr:20988` — `KEEP_OPEN_CANONICAL` — `https://github.com/openclaw/openclaw/pull/20988` — `Streaming recipient-id root-cause fix` -- `issue:19839` — `CLOSE_DUPLICATE` — `https://github.com/openclaw/openclaw/issues/19839` — `->` `https://github.com/openclaw/openclaw/issues/20337` -- `issue:12714` — `KEEP_OPEN_RELATED` — `https://github.com/openclaw/openclaw/issues/12714` — `Block-mode emission behavior mismatch` +- `pr:20988` — `KEEP_OPEN_CANONICAL` — `Streaming recipient-id root-cause fix` by `@canonical_author` — `https://github.com/openclaw/openclaw/pull/20988` — `canonical remediation path` +- `issue:19839` — `CLOSE_DUPLICATE` — `[Security] ...` by `@duplicate_author` — `https://github.com/openclaw/openclaw/issues/19839` — `->` `https://github.com/openclaw/openclaw/issues/20337` +- `issue:12714` — `KEEP_OPEN_RELATED` — `[Security] ...` by `@related_author` — `https://github.com/openclaw/openclaw/issues/12714` — `Block-mode emission behavior mismatch` + +Required matrix row shape: +- ` by @<author> — <url> — <short rationale>` ### Command/result block (required) - `planned`/`executed`/`blocked` status per command. - For each command, include exact command text and resulting state. ### Evidence matrix (required) -- Item-level evidence anchors: PR/issue link, root-cause marker, scope delta, merge risk, and confidence tag. +- Item-level evidence anchors: PR/issue link, title, author, root-cause marker, scope delta, merge risk, and confidence tag. - Blockers must be explicit. ### Credit and closure rationale block (required) From 92ea3d455583b866223e021b9bb8bfe822f23ee4 Mon Sep 17 00:00:00 2001 From: Vincent Koc <vincentkoc@ieee.org> Date: Fri, 20 Feb 2026 16:45:52 -0800 Subject: [PATCH 2/6] docs: refine dedupe skill operator experience --- skills/openclaw-github-dedupe/SKILL.md | 59 ++++++++++++------- skills/openclaw-github-dedupe/principles.md | 2 +- .../openclaw-github-dedupe/scripts/alias.sh | 8 +-- .../scripts/cluster-example.txt | 23 +++----- 4 files changed, 52 insertions(+), 40 deletions(-) diff --git a/skills/openclaw-github-dedupe/SKILL.md b/skills/openclaw-github-dedupe/SKILL.md index c6a06d2..7e4fc4b 100644 --- a/skills/openclaw-github-dedupe/SKILL.md +++ b/skills/openclaw-github-dedupe/SKILL.md @@ -15,6 +15,8 @@ Use this skill when a cluster of GitHub issues and pull requests has been report Provide a consistent, evidence-driven triage pass for issue and PR clusters so duplicate work is folded, contributor credit is preserved, and cleanup actions stay auditable. +Execution is command-led and conservative: drive decisions from `gh` readbacks plus deterministic file/metadata checks only, and avoid speculative local analysis beyond triage logic. + Primary goal: make every run action-ready with explicit per-item actions, links, and command outcomes. ## Vision @@ -185,9 +187,9 @@ Use `update_plan` at runtime and keep one in-progress step at a time. - Dry run: `<on|off>` ### Per-item action matrix (required) -- `pr:20988` — `KEEP_OPEN_CANONICAL` — `Streaming recipient-id root-cause fix` by `@canonical_author` — `https://github.com/openclaw/openclaw/pull/20988` — `canonical remediation path` -- `issue:19839` — `CLOSE_DUPLICATE` — `[Security] ...` by `@duplicate_author` — `https://github.com/openclaw/openclaw/issues/19839` — `->` `https://github.com/openclaw/openclaw/issues/20337` -- `issue:12714` — `KEEP_OPEN_RELATED` — `[Security] ...` by `@related_author` — `https://github.com/openclaw/openclaw/issues/12714` — `Block-mode emission behavior mismatch` +- `pr:xxxxx` — `KEEP_OPEN_CANONICAL` — `Streaming recipient-id root-cause fix` by `@canonical_author` — `https://github.com/openclaw/openclaw/pull/xxxxx` — `canonical remediation path` +- `issue:yyyyy` — `CLOSE_DUPLICATE` — `Slack stream stop race condition` by `@duplicate_author` — `https://github.com/openclaw/openclaw/issues/yyyyy` — `->` `https://github.com/openclaw/openclaw/issues/zzzzz` +- `issue:aaaaa` — `KEEP_OPEN_RELATED` — `Block-mode emission behavior mismatch` by `@related_author` — `https://github.com/openclaw/openclaw/issues/aaaaa` — `adjacent area: block-path semantics` Required matrix row shape: - `<item> — <action> — <title> by @<author> — <url> — <short rationale>` @@ -306,39 +308,52 @@ This appears separate from this cluster and will stay in its own thread. If this looks related, point to the shared failure step and I can rerun dedupe right away.` ### Variation examples -`Nice work circling this one. +Use a starter bank (never replay the same opener twice in one run): + +`Great progress getting this in front of me. Thanks for the context. + +The final fix is tracking in #xxxxx by @canonical_author. +This is the path we’re standardizing on because it best covers the failure family. + +If you think the boundary changed, share the diff and I can reopen the decision right away.` -I reviewed the overlap and confirmed the final fix is tracking in #20988 by @Dithilli. +`Thanks for the clear pass here. -It covers the same failure mode and is the right place for closure path continuity. +I reviewed the overlap and confirmed this as a duplicate of #xxxxx. The newer canonical fix now carries the same core path plus the missing delivery hardening. -If this seems off in your view, tell me what changed and I can reopen the review quickly.` +Your earlier contribution is still credited in the canonical history, and I can reopen review if you see a gap.` -`Thanks for taking the first pass on this. +`Great catch, thank you. -I'm closing this as a duplicate of #20988. A later stable PR carried this forward with the merge-safe completion path. +I reviewed this cluster and this looks related, not duplicate. The vector diverges on routing semantics, so it stays separate for now. -Your contribution is still part of the attribution trail, and I can reopen this review if there is a miss.` +If this looks wrong against your evidence, point me to the exact overlap and I can re-evaluate quickly.` -`Good observation. This is related, but not a duplicate. +`Nice to see this captured with concrete reproduction details. -The failure path diverges at message-route semantics, so this remains in a separate track. +I’m treating this as the canonical path and keeping it open; this one is a direct extension with merge-safe improvements. -If that boundary feels wrong, I can reassess with the extra context right away.` +If needed, I can reopen and reassess the boundary with updated checks in the same flow.` + +`Your report is very useful. + +I’m closing this as a duplicate of #xxxxx. It maps to the same recipient-id streaming path and is now covered by the canonical fix. + +If you think this was a miss, tell me what changed and I can reopen review right away.` ## Messaging examples by situation ### Situation 1: clean duplicate, single-credit result -- Canonical: `pr:20988` -- Duplicate: `issue:19839`, `issue:12714` +- Canonical: `pr:xxxxx` by `@canonical_author` +- Duplicate: `issue:yyyyy` by `@first_author`, `issue:zzzzz` by `@second_author` - Required behavior: - One credited canonical author only (target 95%+ of cases). - Duplicate closure uses single-credit close templates. - Related notes include a specific divergence reason. ### Situation 2: earlier PR non-mergeable, direct follow-up continuation, dual-credit -- Canonical: `pr:20988` -- Earlier groundwork: `pr:20377` (not mergeable, direct continuation proven by diff overlap and clean follow-up checks) +- Canonical: `pr:xxxxx` +- Earlier groundwork: `pr:yyyyy` (not mergeable, direct continuation proven by diff overlap and clean follow-up checks) - Required behavior: - Dual-credit templates are used. - Rationale statement must include: @@ -397,16 +412,18 @@ Supported actions: Example: ```text -pr:20988|inspect| -pr:20377|close-pr-duplicate|20988 -issue:19839|close-issue-duplicate|20337 -issue:12714|noop| +pr:xxxxx|inspect| +pr:yyyyy|close-pr-duplicate|xxxxx +issue:bbbbb|close-issue-duplicate|aaaaa +issue:ccccc|noop| ``` Use placeholder IDs in examples only: `pr:xxxxx|inspect|` +Prefer using `scripts/cluster-example.txt` as your starting template for reusable cluster runs. + ## Git cleanup option - Remove stale branch: `git branch -D <branch>` diff --git a/skills/openclaw-github-dedupe/principles.md b/skills/openclaw-github-dedupe/principles.md index d79464e..7444674 100644 --- a/skills/openclaw-github-dedupe/principles.md +++ b/skills/openclaw-github-dedupe/principles.md @@ -1,4 +1,4 @@ -# Principles for OpenClaw Cluster Dedupe +# Principles for GitHub Cluster Dedupe ## Purpose diff --git a/skills/openclaw-github-dedupe/scripts/alias.sh b/skills/openclaw-github-dedupe/scripts/alias.sh index ae46309..0d17d8f 100755 --- a/skills/openclaw-github-dedupe/scripts/alias.sh +++ b/skills/openclaw-github-dedupe/scripts/alias.sh @@ -32,10 +32,10 @@ Actions: noop - no action Examples: - pr:20988|inspect| - pr:20377|close-pr-duplicate|20988 - issue:19839|close-issue-duplicate|20337 - issue:12714|noop| + pr:xxxxx|inspect| + pr:yyyyy|close-pr-duplicate|xxxxx + issue:zzzzz|close-issue-duplicate|aaaaa + issue:bbbbb|noop| EOF } diff --git a/skills/openclaw-github-dedupe/scripts/cluster-example.txt b/skills/openclaw-github-dedupe/scripts/cluster-example.txt index 2da74b7..992403c 100644 --- a/skills/openclaw-github-dedupe/scripts/cluster-example.txt +++ b/skills/openclaw-github-dedupe/scripts/cluster-example.txt @@ -1,21 +1,16 @@ # Example cluster workflow plan -# Replace placeholder IDs before running. +# Replace placeholder IDs with real issue/pr numbers before running. # # Columns: # <type>:<id>|<action>|<target> +# type: pr | issue +# action: inspect | close-pr-duplicate | close-issue-duplicate | noop # -# Supported <type>: -# - pr -# - issue -# -# Supported <action>: -# - inspect -# - close-pr-duplicate -# - close-issue-duplicate -# - noop +# Canonical IDs used by this sample: +# - canonical PR: xxxxx +# - issue canonical: aaaaa pr:xxxxx|inspect| -pr:aaaaaa|close-pr-duplicate|xxxxx -issue:bbbbb|close-issue-duplicate|ccccc -issue:ddddd|inspect| -issue:eeeee|noop| +pr:yyyyy|close-pr-duplicate|xxxxx +issue:bbbbb|close-issue-duplicate|aaaaa +issue:ccccc|noop| From 303031302b98a5763abd1c316cc8d969ac3b57a9 Mon Sep 17 00:00:00 2001 From: Vincent Koc <vincentkoc@ieee.org> Date: Fri, 20 Feb 2026 16:47:14 -0800 Subject: [PATCH 3/6] docs: switch dedupe action outputs to table format --- skills/openclaw-github-dedupe/SKILL.md | 31 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/skills/openclaw-github-dedupe/SKILL.md b/skills/openclaw-github-dedupe/SKILL.md index 7e4fc4b..d5bafaa 100644 --- a/skills/openclaw-github-dedupe/SKILL.md +++ b/skills/openclaw-github-dedupe/SKILL.md @@ -187,20 +187,33 @@ Use `update_plan` at runtime and keep one in-progress step at a time. - Dry run: `<on|off>` ### Per-item action matrix (required) -- `pr:xxxxx` — `KEEP_OPEN_CANONICAL` — `Streaming recipient-id root-cause fix` by `@canonical_author` — `https://github.com/openclaw/openclaw/pull/xxxxx` — `canonical remediation path` -- `issue:yyyyy` — `CLOSE_DUPLICATE` — `Slack stream stop race condition` by `@duplicate_author` — `https://github.com/openclaw/openclaw/issues/yyyyy` — `->` `https://github.com/openclaw/openclaw/issues/zzzzz` -- `issue:aaaaa` — `KEEP_OPEN_RELATED` — `Block-mode emission behavior mismatch` by `@related_author` — `https://github.com/openclaw/openclaw/issues/aaaaa` — `adjacent area: block-path semantics` +Render this as a table: -Required matrix row shape: -- `<item> — <action> — <title> by @<author> — <url> — <short rationale>` +| item | action | title | author | artifact | rationale | target | +|---|---|---|---|---|---|---| +| `pr:xxxxx` | `KEEP_OPEN_CANONICAL` | `Streaming recipient-id root-cause fix` | `@canonical_author` | `https://github.com/openclaw/openclaw/pull/xxxxx` | `canonical remediation path` | `-` | +| `issue:yyyyy` | `CLOSE_DUPLICATE` | `Slack stream stop race condition` | `@duplicate_author` | `https://github.com/openclaw/openclaw/issues/yyyyy` | `covered by canonical PR` | `#zzzzz` | +| `issue:aaaaa` | `KEEP_OPEN_RELATED` | `Block-mode emission behavior mismatch` | `@related_author` | `https://github.com/openclaw/openclaw/issues/aaaaa` | `adjacent area: block-path semantics` | `-` | + +Required matrix fields: item, action, title, author, artifact link, short rationale, and canonical target/duplicate mapping target where applicable. ### Command/result block (required) -- `planned`/`executed`/`blocked` status per command. -- For each command, include exact command text and resulting state. +Render command outcomes as a table: + +| status | command | state | +|---|---|---| +| `planned`/`executed`/`blocked` | `gh issue view ...` | `passed` / `applied` / `blocked by checks` | + +Include exact command text and resulting state for each operation. ### Evidence matrix (required) -- Item-level evidence anchors: PR/issue link, title, author, root-cause marker, scope delta, merge risk, and confidence tag. -- Blockers must be explicit. +Render evidence per item as a table: + +| item | title | author | root-cause marker | scope delta | merge risk | confidence | +|---|---|---|---|---|---|---| +| `pr:xxxxx` | `Streaming recipient-id root-cause fix` | `@canonical_author` | `recipient IDs + stream pipeline` | `touches stream API + block pipeline` | `low` | `high` | + +Blockers must be explicit. ### Credit and closure rationale block (required) - Explicit credit chain for all merged/closed outcomes with default one credited contributor in 95%+ cases; max two only by explicit exception. From ed5875ab49af96481a0999a67a1731c874ee6d64 Mon Sep 17 00:00:00 2001 From: Vincent Koc <vincentkoc@ieee.org> Date: Fri, 20 Feb 2026 16:48:14 -0800 Subject: [PATCH 4/6] fix: clean variation examples in dedupe messaging --- skills/openclaw-github-dedupe/SKILL.md | 31 +++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/skills/openclaw-github-dedupe/SKILL.md b/skills/openclaw-github-dedupe/SKILL.md index d5bafaa..24045f6 100644 --- a/skills/openclaw-github-dedupe/SKILL.md +++ b/skills/openclaw-github-dedupe/SKILL.md @@ -323,36 +323,35 @@ If this looks related, point to the shared failure step and I can rerun dedupe r ### Variation examples Use a starter bank (never replay the same opener twice in one run): -`Great progress getting this in front of me. Thanks for the context. +`Hey, great catch on this one. -The final fix is tracking in #xxxxx by @canonical_author. -This is the path we’re standardizing on because it best covers the failure family. +I reviewed the cluster and confirmed the final fix is in #xxxxx by @canonical_author. That keeps the same root-cause path while adding the missing hardening. -If you think the boundary changed, share the diff and I can reopen the decision right away.` +If you see a gap in that boundary, tell me and I can reopen review right away.` -`Thanks for the clear pass here. +`Nice work circling this with a concrete repro. -I reviewed the overlap and confirmed this as a duplicate of #xxxxx. The newer canonical fix now carries the same core path plus the missing delivery hardening. +I’m closing this as a duplicate of #xxxxx because this path is now covered by the canonical fix. -Your earlier contribution is still credited in the canonical history, and I can reopen review if you see a gap.` +You’re still part of the attribution trail. If this is a miss, tell me and I can re-run review immediately.` -`Great catch, thank you. +`Thanks for the details here. -I reviewed this cluster and this looks related, not duplicate. The vector diverges on routing semantics, so it stays separate for now. +This is related, not duplicate; it diverges on `{reason}` and should stay on a separate track for now. -If this looks wrong against your evidence, point me to the exact overlap and I can re-evaluate quickly.` +If your evidence says otherwise, point me to the shared failure step and I’ll reassess quickly.` -`Nice to see this captured with concrete reproduction details. +`I appreciate the early pass. -I’m treating this as the canonical path and keeping it open; this one is a direct extension with merge-safe improvements. +I’m treating #xxxxx as canonical since it is the most complete and merge-safe coverage for this cluster. -If needed, I can reopen and reassess the boundary with updated checks in the same flow.` +If I should reopen and revisit this split, say the exact overlap and I’ll rerun it right away.` -`Your report is very useful. +`Great report. -I’m closing this as a duplicate of #xxxxx. It maps to the same recipient-id streaming path and is now covered by the canonical fix. +I’m closing this as duplicate of #xxxxx. The same root-cause surface is already being tracked there, so we can avoid duplicate churn. -If you think this was a miss, tell me what changed and I can reopen review right away.` +If this is not what you expected, tell me and I’ll reopen review right away.` ## Messaging examples by situation From d1e421e5180330c137c0af4e57c3c8f4444f87cb Mon Sep 17 00:00:00 2001 From: Vincent Koc <vincentkoc@ieee.org> Date: Fri, 20 Feb 2026 16:51:03 -0800 Subject: [PATCH 5/6] docs: repair messaging variation bank --- skills/openclaw-github-dedupe/SKILL.md | 30 +++++++++++--------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/skills/openclaw-github-dedupe/SKILL.md b/skills/openclaw-github-dedupe/SKILL.md index 24045f6..e969f1a 100644 --- a/skills/openclaw-github-dedupe/SKILL.md +++ b/skills/openclaw-github-dedupe/SKILL.md @@ -323,35 +323,29 @@ If this looks related, point to the shared failure step and I can rerun dedupe r ### Variation examples Use a starter bank (never replay the same opener twice in one run): -`Hey, great catch on this one. +`Great call on this one. -I reviewed the cluster and confirmed the final fix is in #xxxxx by @canonical_author. That keeps the same root-cause path while adding the missing hardening. +I’m closing this as a duplicate of #xxxxx. The same failure pattern is now covered in the canonical fix, and this path is fully superseded there. -If you see a gap in that boundary, tell me and I can reopen review right away.` +Your earlier work is still part of the attribution trail. If this is a miss, tell me what changed and I can reopen review right away.` -`Nice work circling this with a concrete repro. +`Nice work surfacing this with clear context. -I’m closing this as a duplicate of #xxxxx because this path is now covered by the canonical fix. +I reviewed the overlap and confirmed the final fix is in #xxxxx by @canonical_author. We’re keeping that one because it has the most complete root-cause coverage. -You’re still part of the attribution trail. If this is a miss, tell me and I can re-run review immediately.` +If this looks off in your repro, tell me and I can re-check the boundary quickly.` -`Thanks for the details here. +`Thanks for pushing this. -This is related, not duplicate; it diverges on `{reason}` and should stay on a separate track for now. +This appears related, not a duplicate. It diverges at `{reason}` and belongs in a separate track for now. -If your evidence says otherwise, point me to the shared failure step and I’ll reassess quickly.` +If you think that boundary is wrong, point me to the shared failure step and I’ll reassess it right away.` -`I appreciate the early pass. +`I appreciate the early pass here. -I’m treating #xxxxx as canonical since it is the most complete and merge-safe coverage for this cluster. +I’m treating #xxxxx as canonical because it is the safest and most complete path for this cluster. -If I should reopen and revisit this split, say the exact overlap and I’ll rerun it right away.` - -`Great report. - -I’m closing this as duplicate of #xxxxx. The same root-cause surface is already being tracked there, so we can avoid duplicate churn. - -If this is not what you expected, tell me and I’ll reopen review right away.` +If I should rerun this split, share the exact overlap and I can do that immediately.` ## Messaging examples by situation From 9a9d0be8431ed6520cc50b130c479ef6faed1e78 Mon Sep 17 00:00:00 2001 From: Vincent Koc <vincentkoc@ieee.org> Date: Fri, 20 Feb 2026 16:51:41 -0800 Subject: [PATCH 6/6] feat: add explicit GH similarity sub-agent for cluster discovery --- skills/openclaw-github-dedupe/SKILL.md | 25 +++++++++-- .../agents/cluster-similarity-agent.md | 44 +++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 skills/openclaw-github-dedupe/agents/cluster-similarity-agent.md diff --git a/skills/openclaw-github-dedupe/SKILL.md b/skills/openclaw-github-dedupe/SKILL.md index e969f1a..e55f868 100644 --- a/skills/openclaw-github-dedupe/SKILL.md +++ b/skills/openclaw-github-dedupe/SKILL.md @@ -76,6 +76,9 @@ This workflow is designed for high-velocity maintainers and external contributor - `merge_tool_pref` (optional): `auto`, `gh`, `merge-skill`, or `land-skill`; default `auto`. - `dry_run` (optional): `0|1` to force non-mutating mode. - `output_mode` (optional): `compact|detailed`; default `detailed`. +- `triage_report` (optional): path to a triage report file (like `/Users/vincentkoc/Desktop/triage_report.md`) to seed initial cluster candidates. +- `search_limit` (optional): max similar items per item from GH search; default `12`. +- `search_queries` (optional): explicit query terms (space-separated). ## Outputs @@ -90,21 +93,27 @@ This workflow is designed for high-velocity maintainers and external contributor Use sub-agents in this chain for higher consistency and lower mistakes: - `agents/cluster-intake-agent.md` +- `agents/cluster-similarity-agent.md` - `agents/cluster-evidence-agent.md` - `agents/cluster-decision-agent.md` - `agents/cluster-synthesis-agent.md` Run in sequence and feed each output to the next. -- Intake → Evidence: normalizes items and fetches GH context. -- Evidence → Decision: maps risk and hard-stop states. -- Decision → Synthesis: emits final action matrix and command plan. +- Intake → Similarity → Evidence → Decision → Synthesis. + +1. Intake: normalize cluster refs (required first), including optional `triage_report` expansion. +2. Similarity: find additional related open issues/PRs from GitHub search and attach ranked candidates. +3. Evidence: pull full context for cluster + similar candidates. +4. Decision: maps risk and hard-stop states. +5. Synthesis: emits final action matrix and command plan. If any sub-agent blocks, continue only with explicit `manual-review-required` and keep execution safe. When orchestrator support exists, run them as a chain and pass structured outputs between steps: - Start with `cluster-intake-agent` +- Feed output to `cluster-similarity-agent` - Feed output to `cluster-evidence-agent` - Feed output to `cluster-decision-agent` - Feed output to `cluster-synthesis-agent` @@ -126,7 +135,15 @@ Use `update_plan` at runtime and keep one in-progress step at a time. - Resolve each input to canonical links and types. - Skip malformed entries with a reasoned note for `manual-review-required`. -2. Fetch evidence from GitHub +2. Similarity sweep (required) + - Use the supplied `cluster-intake-agent` summary as the primary seed. + - Expand search surface by running GitHub queries for additional candidates and include likely neighbors in the same root-cause family. + - Pull: + - `gh issue list --search "<query> in:title" --state all --repo <repo> --json number,title,url,state,author,updatedAt,labels` + - `gh pr list --search "<query> in:title" --state all --repo <repo> --json number,title,url,state,author,updatedAt,isDraft,mergeable` + - Keep likely matches when title/body overlap is explicit, not keyword-only. + +3. Fetch evidence from GitHub - For PRs: `gh pr view <ref> --json number,title,body,state,author,labels,createdAt,updatedAt,mergedAt,closedAt,mergeable,mergeStateStatus,isDraft,changedFiles,additions,deletions,statusCheckRollup,commits,url` - For issues: `gh issue view <ref> --json number,title,body,state,labels,author,createdAt,updatedAt,url,comments` - Pull file footprint for PRs when deciding canonical scope: `gh pr diff <ref> --name-only` diff --git a/skills/openclaw-github-dedupe/agents/cluster-similarity-agent.md b/skills/openclaw-github-dedupe/agents/cluster-similarity-agent.md new file mode 100644 index 0000000..20cce93 --- /dev/null +++ b/skills/openclaw-github-dedupe/agents/cluster-similarity-agent.md @@ -0,0 +1,44 @@ +--- +name: cluster-similarity-agent +description: Discover additional similar issues and PRs from GitHub before final dedupe decisions. +model: sonnet +tools: + - Shell + - Read +permissionMode: default +maxTurns: 12 +--- + +You are the similarity discovery sub-agent for `openclaw-github-dedupe`. + +Goal: +- Expand a candidate cluster by finding likely duplicate/related issues and PRs in the repo before decisioning. +- Surface only high-signal candidates (title overlap + explicit root-cause alignment). + +Inputs: +- `repo`: owner/repo for all GH calls. +- `seed_items`: normalized seed `pr:<n>` / `issue:<n>` list from the intake agent. +- `search_queries` (optional): explicit query strings. +- `search_limit`: max results per query, default 12. + +Mandatory command pattern: +- For each seed item and query term, run: + - `gh issue list --search "<query> in:title" --state all --repo <repo> --json number,title,url,state,author,updatedAt,labels` + - `gh pr list --search "<query> in:title" --state all --repo <repo> --json number,title,url,state,author,updatedAt,isDraft,mergeable` +- Prefer exact phrase + core token queries (for example recipient_team_id, recipient_user_id, streaming, block-streaming, thread) over generic terms. + +Output: +- `seed_items`: unchanged normalized list +- `similar_issues`: array of `number, url, title, state, match_reason` +- `similar_prs`: array of `number, url, title, state, match_reason` +- `excluded_items`: seed-matches or obvious non-relevance with reason +- `confidence`: low|med|high on discovery quality + +Decision rules: +- If `match_reason` is only shared tokens and no concrete symptom overlap, mark as `low`. +- Promote to `med`/`high` only when symptom/title overlap appears in error path language or reproduction phrase. +- Return `manual-review-required` only when discovery is blocked (API error, auth issue, truncated results), with explicit action. + +Failure handling: +- On API errors, emit `manual-review-required` and the exact command/state from the failing call. +- Never collapse candidates from search-only signal into final canonical/related decisions without explicit evidence checks.