@@ -34,6 +34,16 @@ opened issues get stronger duplicate and adjacent-report context. Set repository
3434variable ` CLAWSWEEPER_RELATED_GITHUB_SEARCH=0 ` on ` openclaw/clawsweeper ` to turn
3535that enrichment off without editing the target dispatcher.
3636
37+ Before enabling the workflow:
38+
39+ 1 . Install the ` clawsweeper ` GitHub App on the target repository.
40+ 2 . Add the App private key as the target repository Actions secret
41+ ` CLAWSWEEPER_APP_PRIVATE_KEY ` .
42+ 3 . Install exactly one target dispatcher. Do not add separate comment, spam, and
43+ generic-activity dispatch workflows that forward the same event twice.
44+ 4 . Keep the target write token limited to the comment acknowledgement path.
45+ Issue/PR review dispatch only needs the ClawSweeper installation token.
46+
3747``` yaml
3848name : ClawSweeper Dispatch
3949
7686 repositories : clawsweeper
7787 permission-contents : write
7888
89+ - name : Pre-filter ClawSweeper comment
90+ id : comment_filter
91+ if : ${{ github.event_name == 'issue_comment' }}
92+ env :
93+ COMMENT_BODY : ${{ github.event.comment.body }}
94+ run : |
95+ set -euo pipefail
96+ if grep -Eiq '(^|[[:space:]])@(clawsweeper|openclaw-clawsweeper)\b(\[bot\])?|(^|[[:space:]])/(clawsweeper|review|re-review|rerun[ -]?review|status|explain|fix|build|implement|create[ -]?pr|fix[ -]?issue|autofix|auto[ -]?fix|automerge|auto[ -]?merge|approve|stop|autoclose)\b' <<< "$COMMENT_BODY"; then
97+ echo "is_command=true" >> "$GITHUB_OUTPUT"
98+ else
99+ echo "is_command=false" >> "$GITHUB_OUTPUT"
100+ fi
101+
79102 - name : Create target comment token
80103 id : target_token
81- if : ${{ github.event_name == 'issue_comment' && env.HAS_CLAWSWEEPER_APP_PRIVATE_KEY == 'true' }}
104+ if : >-
105+ ${{
106+ github.event_name == 'issue_comment' &&
107+ steps.comment_filter.outputs.is_command == 'true' &&
108+ env.HAS_CLAWSWEEPER_APP_PRIVATE_KEY == 'true'
109+ }}
82110 uses : actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
83111 with :
84112 client-id : ${{ env.CLAWSWEEPER_APP_CLIENT_ID }}
@@ -115,7 +143,11 @@ jobs:
115143 --input - <<< "$payload"
116144
117145 - name : Acknowledge and dispatch ClawSweeper comment
118- if : ${{ github.event_name == 'issue_comment' }}
146+ if : >-
147+ ${{
148+ github.event_name == 'issue_comment' &&
149+ steps.comment_filter.outputs.is_command == 'true'
150+ }}
119151 env :
120152 DISPATCH_TOKEN : ${{ steps.token.outputs.token }}
121153 TARGET_TOKEN : ${{ steps.target_token.outputs.token }}
@@ -136,10 +168,6 @@ jobs:
136168 echo "Ignoring ClawSweeper proof-nudge comment."
137169 exit 0
138170 fi
139- if ! grep -Eiq '(^|[[:space:]])@clawsweeper\b|(^|[[:space:]])/(clawsweeper|review|re-review|rerun[ -]?review|status|explain|fix|build|implement|create[ -]?pr|fix[ -]?issue|autofix|auto[ -]?fix|automerge|auto[ -]?merge|approve|stop|autoclose)\b' "$body_file"; then
140- echo "No ClawSweeper command found in comment."
141- exit 0
142- fi
143171 if [ -n "$TARGET_TOKEN" ]; then
144172 GH_TOKEN="$TARGET_TOKEN" gh api -X POST \
145173 -H "Accept: application/vnd.github+json" \
@@ -237,9 +265,8 @@ Install one dispatcher workflow per target repository. Keep the event fanout
237265inside that workflow; do not add separate comment, spam, or generic-activity
238266dispatch workflows in the target repository.
239267
240- The snippet below is only the trigger, permission, and concurrency fragment.
241- It is not a complete workflow; use the full dispatcher example above as the
242- copy-pasteable job definition.
268+ The full dispatcher example above is the copy-pasteable job definition. Its
269+ important rate-limit properties are :
243270
244271` ` ` yaml
245272name: ClawSweeper Dispatch
@@ -260,11 +287,20 @@ concurrency:
260287 cancel-in-progress: ${{ github.event.action == 'edited' || github.event.action == 'synchronize' || github.event.action == 'ready_for_review' }}
261288` ` `
262289
263- The job should mint one short-lived `clawsweeper` App token scoped to
264- ` openclaw/clawsweeper` , then send one `clawsweeper_item` or
265- ` clawsweeper_comment` ` repository_dispatch` . For comments, check the command
266- syntax before minting a target write token. Do not use a PAT or dispatch the
267- same comment through both the exact router and a second spam/generic workflow.
290+ The job mints one short-lived `clawsweeper` App token scoped to
291+ ` openclaw/clawsweeper` , then sends one `clawsweeper_item` or
292+ ` clawsweeper_comment` ` repository_dispatch` . For comments, the
293+ ` Pre-filter ClawSweeper comment` step runs before the target write token is
294+ minted, so ordinary comments consume neither a target installation token nor a
295+ dispatch. Do not use a PAT or dispatch the same comment through both the exact
296+ router and a second spam/generic workflow.
297+
298+ To verify a target installation, open a pull request or issue and confirm one
299+ ` ClawSweeper Dispatch` run. Add a maintainer comment containing `@clawsweeper`
300+ or a supported slash command and confirm one `clawsweeper_comment` dispatch.
301+ An ordinary comment should produce no ClawSweeper comment dispatch and no
302+ target-token step. If the target app secret is absent, the workflow should
303+ finish with a notice rather than fall back to a maintainer PAT.
268304
269305The ClawSweeper `github-activity` workflow performs spam-candidate
270306classification in-process and only dispatches the scanner for an accepted
0 commit comments