multi: add issue dedupe command and workflow
What changed, and why it matters
This commit adds a new GitHub automation that uses an AI assistant (Claude Code) to detect and comment on duplicate GitHub issues. It does not change any wallet, networking, or cryptographic code in the Lightning node itself. There is no direct security risk visible in the diff.
No security patch is required. If the project wants to harden the automation, it could restrict workflow permissions further (e.g., remove id-token: write if not needed), pin the anthropics/claude-code-action to a specific SHA, and review the OAuth token scope. These are hygiene improvements, not fixes for a disclosed vulnerability.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit introduces three new files: a Claude Code slash-command definition (.claude/commands/dedupe.md), a GitHub Actions workflow (.github/workflows/claude-dedupe-issues.yml), and a bash helper script (scripts/comment-on-duplicates.sh). The workflow triggers on newly opened issues, runs Claude Code with the /dedupe command, and may post a comment listing up to three candidate duplicate issues. The script validates inputs as numeric issue IDs, verifies each issue exists via gh issue view, and posts a comment via gh issue comment. It uses the built-in GITHUB_TOKEN and an OAuth token for Claude Code. No LND runtime code is modified.
Changed components
GitHub repository automation.github/workflows/claude-dedupe-issues.yml.claude/commands/dedupe.mdscripts/comment-on-duplicates.shInspect captured patch +155 / −0
diff --git a/.claude/commands/dedupe.md b/.claude/commands/dedupe.md
new file mode 100644
index 0000000..2711e98
--- /dev/null
+++ b/.claude/commands/dedupe.md
@@ -0,0 +1,23 @@
+---
+allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(./scripts/comment-on-duplicates.sh:*)
+description: Find duplicate GitHub issues
+---
+
+Find up to 3 likely duplicate issues for a given GitHub issue.
+
+To do this, follow these steps precisely:
+
+1. Use an agent to check if the Github issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicates comment that you made earlier. If so, do not proceed.
+2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue
+3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #2
+4. Next, feed the results from #2 and #3 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.
+5. Finally, use the comment script to post duplicates:
+ ```
+ ./scripts/comment-on-duplicates.sh --base-issue <issue-number> --potential-duplicates <dup1> <dup2> <dup3>
+ ```
+
+Notes (be sure to tell this to your agents, too):
+
+- Use `gh` to interact with Github, rather than web fetch
+- Do not use other tools, beyond `gh` and the comment script (eg. don't use other MCP servers, file edit, etc.)
+- Make a todo list first
diff --git a/.github/workflows/claude-dedupe-issues.yml b/.github/workflows/claude-dedupe-issues.yml
new file mode 100644
index 0000000..25b4696
--- /dev/null
+++ b/.github/workflows/claude-dedupe-issues.yml
@@ -0,0 +1,34 @@
+name: Claude Issue Dedupe
+description: Automatically dedupe GitHub issues using Claude Code
+on:
+ issues:
+ types: [opened]
+ workflow_dispatch:
+ inputs:
+ issue_number:
+ description: 'Issue number to process for duplicate detection'
+ required: true
+ type: string
+
+jobs:
+ claude-dedupe-issues:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+ issues: write
+ id-token: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Run Claude Code slash command
+ uses: anthropics/claude-code-action@v1
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ allowed_non_write_users: "*"
+ prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
diff --git a/scripts/comment-on-duplicates.sh b/scripts/comment-on-duplicates.sh
new file mode 100755
index 0000000..e2f2c2c
--- /dev/null
+++ b/scripts/comment-on-duplicates.sh
@@ -0,0 +1,98 @@
+#!/usr/bin/env bash
+#
+# Comments on a GitHub issue with a list of potential duplicates.
+# Usage: ./comment-on-duplicates.sh --base-issue 123 --potential-duplicates 456 789 101
+#
+
+set -euo pipefail
+
+REPO="${GITHUB_REPOSITORY:-lightningnetwork/lnd}"
+BASE_ISSUE=""
+DUPLICATES=()
+
+# Parse arguments
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --base-issue)
+ BASE_ISSUE="$2"
+ shift 2
+ ;;
+ --potential-duplicates)
+ shift
+ while [[ $# -gt 0 && ! "$1" =~ ^-- ]]; do
+ DUPLICATES+=("$1")
+ shift
+ done
+ ;;
+ *)
+ echo "Unknown option: $1" >&2
+ exit 1
+ ;;
+ esac
+done
+
+# Validate base issue
+if [[ -z "$BASE_ISSUE" ]]; then
+ echo "Error: --base-issue is required" >&2
+ exit 1
+fi
+
+if ! [[ "$BASE_ISSUE" =~ ^[0-9]+$ ]]; then
+ echo "Error: --base-issue must be a number, got: $BASE_ISSUE" >&2
+ exit 1
+fi
+
+# Validate duplicates
+if [[ ${#DUPLICATES[@]} -eq 0 ]]; then
+ echo "Error: --potential-duplicates requires at least one issue number" >&2
+ exit 1
+fi
+
+if [[ ${#DUPLICATES[@]} -gt 3 ]]; then
+ echo "Error: --potential-duplicates accepts at most 3 issues" >&2
+ exit 1
+fi
+
+for dup in "${DUPLICATES[@]}"; do
+ if ! [[ "$dup" =~ ^[0-9]+$ ]]; then
+ echo "Error: duplicate issue must be a number, got: $dup" >&2
+ exit 1
+ fi
+done
+
+# Validate that base issue exists
+if ! gh issue view "$BASE_ISSUE" --repo "$REPO" &>/dev/null; then
+ echo "Error: issue #$BASE_ISSUE does not exist in $REPO" >&2
+ exit 1
+fi
+
+# Validate that all duplicate issues exist
+for dup in "${DUPLICATES[@]}"; do
+ if ! gh issue view "$dup" --repo "$REPO" &>/dev/null; then
+ echo "Error: issue #$dup does not exist in $REPO" >&2
+ exit 1
+ fi
+done
+
+# Build comment body
+COUNT=${#DUPLICATES[@]}
+if [[ $COUNT -eq 1 ]]; then
+ HEADER="Found 1 possible duplicate issue:"
+else
+ HEADER="Found $COUNT possible duplicate issues:"
+fi
+
+BODY="$HEADER"$'\n\n'
+INDEX=1
+for dup in "${DUPLICATES[@]}"; do
+ BODY+="$INDEX. https://github.com/$REPO/issues/$dup"$'\n'
+ ((INDEX++))
+done
+
+BODY+=$'\n'"If this issue is a duplicate, please close it and 👍 the existing issue instead."$'\n\n'
+BODY+="🤖 Generated with [Claude Code](https://claude.ai/code)"
+
+# Post the comment
+gh issue comment "$BASE_ISSUE" --repo "$REPO" --body "$BODY"
+
+echo "Posted duplicate comment on issue #$BASE_ISSUE"
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.