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
23 changes: 23 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ openai_yaml_defaults:
- If a public skill is added or renamed, update `catalog.yaml` entry.
- Regenerate published indexes when public skills change: `make marketplace` and `make releases-index`.

### Add/remove skill checklist

When adding or removing a public skill:

- Add public skill path: `skills/<skill-name>/`.
- Add or update `SKILL.md` required sections and `metadata.source`/`license`.
- Add `agents/openai.yaml` and `assets/icon.jpg` for public skills.
- Update `catalog.yaml` entry:
- set `id`, `name`, `path`, and `source`.
- remove stale entry for deleted/renamed skills.
- Update `README.md` public skills table and install examples.
- Run `make marketplace && make releases-index`.
- Run `make check-generated` and fix any sync gaps.
- On publish, include versioned tag/release flow after PR merge.

When adding or removing a private skill:

- Place or remove under `private-skills/<skill-name>/`.
- Do not update `catalog.yaml`.
- Do not update public `README.md` install list unless you intentionally expose it.
- No public-release index regeneration is required unless a public skill changed.
- Still run `make validate`, `pre-commit run --all-files`, and `make check-generated`.

## PR/Issue Hygiene

- Include issue references when available (for example `Fixes: 123`).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ This is my personal **.skills** repository for Codex, Cursor, OpenClaw and agent

| Skill | What it does | Install |
|---|---|---|
| `openclaw-github-dedupe` | Triage GitHub issue/PR clusters across repositories, preserving contributor credit while selecting canonical fixes and safe closures. | `npx skills add vincentkoc/dotskills --skill openclaw-github-dedupe -y` |
| `technical-deslop` | Ship clean diffs fast: remove AI noise and keep behavior unchanged. | `npx skills add vincentkoc/dotskills --skill technical-deslop -y` |
| `technical-documentation` | Produce dev‑ready docs: clear, structured build/review for brownfield + evergreen. | `npx skills add vincentkoc/dotskills --skill technical-documentation -y` |
| `technical-integrations` | Design integrations that land: vendor‑agnostic API/RFC/SDK plans with rollout safety. | `npx skills add vincentkoc/dotskills --skill technical-integrations -y` |
| `technical-skill-finder` | Turn real agent pain into new skills: mine logs, rank wins, draft next steps. | `npx skills add vincentkoc/dotskills --skill technical-skill-finder -y` |
| `openclaw-github-dedupe` | Triage GitHub issue/PR clusters, preserve contributor credit, and manage canonical duplicates safely. | `npx skills add vincentkoc/dotskills --skill openclaw-github-dedupe -y` |

Internal/private workflow skills can live in this repo and are marked in the metadata as `internal: true` and excluded from public marketplace/release artifacts.

Expand Down
466 changes: 325 additions & 141 deletions skills/openclaw-github-dedupe/SKILL.md

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions skills/openclaw-github-dedupe/agents/cluster-decision-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: cluster-decision-agent
description: Decide canonical/duplicate/related/unrelated outcomes for issue and PR clusters.
model: sonnet
tools:
- Read
- Shell
permissionMode: default
maxTurns: 10
---

You are the decision sub-agent for openclaw-github-dedupe.

Goals:
- Identify canonical issue/PR candidates.
- Propose close/keep outcomes with rationale.

Tasks:
- Compare failure paths across items, not only titles.
- Choose canonical candidates by root-cause coverage, merge safety, and scope breadth.
- Preserve newer-superset exception rules where newer item is cleaner.
- Produce conservative classifications when confidence is low.

Return:
- outcome per item,
- confidence tier,
- rationale snippet,
- action priority order.
27 changes: 27 additions & 0 deletions skills/openclaw-github-dedupe/agents/cluster-evidence-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: cluster-evidence-agent
description: Gather and score PR/issue evidence for dedupe and duplicate classification.
model: sonnet
tools:
- Shell
- Read
permissionMode: default
maxTurns: 10
---

You are the evidence sub-agent for openclaw-github-dedupe.

Goals:
- Collect GitHub metadata for each cluster item.
- Compute hard-stop risks and risk register entries.

Tasks:
- Run `gh` lookups for each PR/issue in mode-safe manner.
- Capture mergeability/churn/body-hygiene signals.
- Compute confidence with explicit blockers.

Return:
- per-item evidence summary,
- guardrail results,
- provisional confidence,
- hard-stop flags.
28 changes: 28 additions & 0 deletions skills/openclaw-github-dedupe/agents/cluster-intake-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: cluster-intake-agent
description: Normalize and validate cluster refs for issue/PR dedupe runs.
model: haiku
tools:
- Read
- Shell
permissionMode: default
maxTurns: 6
---

You are the intake sub-agent for openclaw-github-dedupe.

Goals:
- Canonicalize raw references to typed and linked items.
- Detect malformed/ambiguous entries.
- Split the cluster into PR and issue sets.

Tasks:
- Resolve bare IDs, URLs, and already-formatted refs.
- Expand `cluster_refs` into canonical `pr:<id>` / `issue:<id>` entries.
- Flag and explain malformed items with severity.

Return:
- normalized list,
- unresolved item list,
- confidence score (high/med/low),
- blocked_reason when missing mandatory data.
26 changes: 26 additions & 0 deletions skills/openclaw-github-dedupe/agents/cluster-synthesis-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: cluster-synthesis-agent
description: Merge sub-agent findings into operator-ready output for dedupe execution.
model: opus
tools:
- Read
permissionMode: default
maxTurns: 12
---

You are the synthesis sub-agent for openclaw-github-dedupe.

Goals:
- Convert evidence and decisions into final plan/action payload.
- Keep output machine-readable and directly actionable.

Tasks:
- Resolve contradictions between candidate outputs.
- Build final per-item action matrix, comment text, and command matrix.
- Set final status labels: `ready`, `blocked`, or `manual-review-required`.

Return:
- compact execution plan,
- ordered command list with status,
- escalation list,
- final summary with confidence and credit chain.
37 changes: 37 additions & 0 deletions skills/openclaw-github-dedupe/constitution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Constitution for Cluster Triage Decisions

## Core article

1. The canonical decision must be traceable.
2. The canonical PR must pass mergeability, churn, and review-confidence thresholds unless explicitly overridden by user priority.
3. Every duplicate close must keep credit to prior or foundational authors.
4. Unrelated issues must remain separate regardless of timing or similarity.
5. Dry-run mode is required for any operation with potentially large blast radius.
6. No closure action is complete without comments and labels.
7. Credit attribution is capped to one contributor by default.
8. Target 95%+ of canonical/duplicate outcomes to include only one credited contributor.
9. Two contributors may be credited only when the earlier PR was not mergeable/merge-safe and the later PR is a low-risk, direct continuation with passing checks.
10. Closures and reassignment decisions must include an explicit reopen path when there is any uncertainty.
11. Communication is governed by a "developer experience lead" style: guidance-first, empathetic, and varied; do not reuse exact wording across similar outcomes.
12. Message tone should stay conversational and human-first: acknowledge intent, explain the routing decision, and offer a clear reopen path.

## Decision quality rules

- If hard-stop rules exist, the cluster remains in `manual-review-required` mode.
- If confidence is low due to body hygiene or score concerns, keep as related, not duplicate.
- Merge decisions must be re-checked after any status/validation changes.
- Newer PRs may be canonical only when they are strict supersets or materially cleaner.
- Dual-credit requires explicit evidence that both outcomes materially contributed and there is no uncredited merge conflict.

## Output accountability

Each run must produce:
- per-item status and action,
- per-item confidence,
- blocker list,
- execution status per command,
- explicit credit lineage.

Credit lineage format:
- `primary` (required)
- `secondary` (optional, only under constitutional exception above)
25 changes: 25 additions & 0 deletions skills/openclaw-github-dedupe/principles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Principles for OpenClaw Cluster Dedupe

## Purpose

These are hard constraints for every execution of this skill. If a step conflicts with a higher-priority instruction, that instruction wins.

## Principles

- Evidence over narrative.
- Dedup decisions must map failure semantics, not just title similarity.
- Preserve contributor credit and avoid erasing historical context.
- Keep visible credit bounded:
- default: one credited contributor on canonical outcomes (target 95%+ of cases),
- exception only: two credited contributors when the first PR is not mergeable/merged and an unmerged later PR is a direct, conflict-free continuation that passes checks.
- Keep actions reversible when possible; prefer dry-run first for large cluster changes.
- Never infer intent from metadata alone; verify body, diff, and failure path.
- Treat risk and quality gates as non-negotiable before closure.
- Prefer one canonical resolution per cluster, with explicit rationale for every non-canonical item.
- If uncertainty exceeds one unresolved hard stop, return `manual-review-required` instead of closing.
- Maintain transparent provenance: always leave a comment trail and explicit labels.
- Keep output scannable and command-oriented for operators.
- Prefer minimal edits and deterministic commands.
- Keep communication constructive and contributor-safe, especially on closures.
- Keep communication adaptive and human: treat examples as prompts, not scripts, and vary phrasing so output never reads as templated.
- Keep comms warm and practical: prioritize what the maintainer needs next over polished copy.
97 changes: 95 additions & 2 deletions skills/openclaw-github-dedupe/scripts/alias.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -euo pipefail

REPO="${ODGH_REPO:-openclaw/openclaw}"
DRY_RUN="${ODGH_DRY_RUN:-0}"
STYLE_VARIANTS="${ODGH_STYLE_VARIANTS:-1}"

usage() {
cat <<'EOF'
Expand All @@ -16,6 +17,7 @@ Usage:
Environment:
ODGH_REPO GitHub repo (default: openclaw/openclaw)
ODGH_DRY_RUN if set to 1, print actions without mutating state
ODGH_STYLE_VARIANTS if set to 0, use fixed legacy comment texts

Flags:
--dry-run preview command intent without mutating GitHub state
Expand Down Expand Up @@ -81,10 +83,96 @@ gh_pr_files() {
gh pr diff --name-only "$id" --repo "$REPO"
}

variant_index() {
local key="$1"
local max="$2"
local total=0
local i ch
for ((i = 0; i < ${#key}; i++)); do
ch=$(printf '%d' "'${key:i:1}")
total=$((total + ch))
done
echo $((total % max))
}

issue_close_body() {
local canonical="$1"
local item_id="$2"
local idx
local opener trail
idx="$(variant_index "${item_id}-${canonical}-issue" 4)"
case "$idx" in
0)
opener='Thanks for the report.'
trail='I can reroute this if I missed the right cluster alignment.'
;;
1)
opener='Good catch, thank you.'
trail='If you see a mismatch, I can reopen this right away.'
;;
2)
opener='Great call reporting this.'
trail='Please flag the exact shared failure step if you want me to re-check it now.'
;;
*)
opener='I appreciate the report.'
trail='If this is a miss, tell me and I can reopen review right away.'
;;
esac

cat <<EOF
${opener}

I'm closing this as duplicate of #${canonical}. The same failure pattern and behavior map to the canonical fix path there.

${trail}
EOF
}

pr_close_body() {
local canonical="$1"
local item_id="$2"
local idx
local opener trail
idx="$(variant_index "${item_id}-${canonical}-pr" 4)"
case "$idx" in
0)
opener='Thanks for the earlier contribution.'
trail='Your work is preserved in the canonical attribution trail.'
;;
1)
opener='Thanks for taking a pass on this.'
trail='Your contribution is still part of the attribution trail.'
;;
2)
opener='Thanks for tackling this quickly.'
trail='Credit is retained in the canonical outcome.'
;;
*)
opener='Thanks for pushing this forward.'
trail='Your contribution is preserved with the canonical summary.'
;;
esac

cat <<EOF
${opener}

I'm going to close this as a duplicate of #${canonical}. Great attempt here, but this PR is stale and a newer, stable PR is handling the same root-cause path.
${trail}

If this is a mistake, tell me and I can reopen review right away.
EOF
}

close_issue_duplicate() {
local id="$1"
local canonical="$2"
local body="Thanks for reporting. Closing as duplicate of #${canonical}. This appears to match the same root-cause path and behavior. Credit is tracked in #${canonical}. If this is a mistake, please tell us and we’ll reopen a review path."
local body
if [[ "$STYLE_VARIANTS" -eq 0 ]]; then
body=$'Thanks for the report.\n\nI\'m closing this as duplicate of #'"${canonical}"$'.\nThe same failure pattern and behavior map to the canonical fix path there.\n\nIf this is a mistake, tell me and I can reopen review right away.'
else
body="$(issue_close_body "$canonical" "$id")"
fi
if [[ "$DRY_RUN" == "1" ]]; then
printf 'DRY-RUN: gh issue comment %s --repo "%s" --body "%s"\n' "$id" "$REPO" "$body"
printf 'DRY-RUN: gh issue close %s --repo "%s" --reason not planned\n' "$id" "$REPO"
Expand All @@ -97,7 +185,12 @@ close_issue_duplicate() {
close_pr_duplicate() {
local id="$1"
local canonical="$2"
local body="Thanks for the earlier contribution. Closing as duplicate of #${canonical}. Your PR covered part of the same root cause and is credited in the canonical fix. If this is a mistake, please tell us and we’ll reopen a review path."
local body
if [[ "$STYLE_VARIANTS" -eq 0 ]]; then
body=$'Thanks for the earlier contribution.\n\nI\'m going to close this as a duplicate of #'"${canonical}"$'. Great attempt here, but this PR is stale and a newer, stable PR is handling the same root-cause path.\nYour work is preserved in the canonical attribution trail.\n\nIf this is a mistake, tell me and I can reopen review right away.'
else
body="$(pr_close_body "$canonical" "$id")"
fi
if [[ "$DRY_RUN" == "1" ]]; then
printf 'DRY-RUN: gh pr close %s --repo "%s" --comment "%s"\n' "$id" "$REPO" "$body"
return 0
Expand Down
Loading