From 9195bd55c2a0e61ec10edc68178aeb95f976fbc9 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 8 Aug 2026 05:39:08 +0800 Subject: [PATCH] fix(ci): retire dead ClawSweeper commit dispatch (#120281) * fix(ci): retire dead ClawSweeper commit dispatch * docs(ci): preserve offline ClawSweeper review path --- .agents/skills/clawsweeper/SKILL.md | 64 +++++-------------- .agents/skills/clawsweeper/agents/openai.yaml | 4 +- .github/workflows/clawsweeper-dispatch.yml | 34 ---------- docs/ci.md | 5 +- test/scripts/ci-workflow-guards.test.ts | 33 ++++++++++ 5 files changed, 53 insertions(+), 87 deletions(-) diff --git a/.agents/skills/clawsweeper/SKILL.md b/.agents/skills/clawsweeper/SKILL.md index 58d821a89e7f..2b5fcb751c35 100644 --- a/.agents/skills/clawsweeper/SKILL.md +++ b/.agents/skills/clawsweeper/SKILL.md @@ -1,12 +1,12 @@ --- name: clawsweeper -description: "Use for all ClawSweeper work: OpenClaw issue/PR sweep reports, commit-review reports, repair jobs, cloud fix PRs, @clawsweeper maintainer mention commands, trusted ClawSweeper-reviewed autofix/automerge, GitHub Actions monitoring, permissions, gates, and manual backfills." +description: "Use for all ClawSweeper work: OpenClaw issue/PR sweep reports, repair jobs, cloud fix PRs, @clawsweeper maintainer mention commands, trusted ClawSweeper-reviewed autofix/automerge, GitHub Actions monitoring, permissions, gates, and manual backfills." --- # ClawSweeper ClawSweeper lives at `~/Projects/clawsweeper`. It is the one OpenClaw -maintenance bot for sweeping, commit review, repair jobs, and guarded fix PRs. +maintenance bot for sweeping, repair jobs, and guarded fix PRs. Use this skill whenever asked about reports, findings, dispatch health, repair/cloud PR creation, comment commands, automerge, permissions, or gates. @@ -36,8 +36,7 @@ Required app setup: - Target app permissions: read target scan context; write issues and pull requests; contents write for report commits, repair branches, and workflow inputs; Actions write on `openclaw/clawsweeper` for comment-router - re-review dispatch, workflow dispatch, run cancellation, and self-heal; - optional Checks write for commit Check Runs. + re-review dispatch, workflow dispatch, run cancellation, and self-heal. Token boundary: @@ -47,40 +46,12 @@ Token boundary: closes, and merges through short-lived GitHub App tokens. - Merge and write gates default closed. -## Commit Reports +## Hosted Commit Reviews -Canonical commit reports: - -```text -records//commits/<40-char-sha>.md -``` - -Use the lister: - -```bash -pnpm commit-reports -- --since 6h -pnpm commit-reports -- --since "24 hours ago" --findings -pnpm commit-reports -- --since 7d --non-clean -pnpm commit-reports -- --repo openclaw/openclaw --author steipete --since 7d -pnpm commit-reports -- --since 24h --json -``` - -Results: `nothing_found`, `findings`, `inconclusive`, `failed`, -`skipped_non_code`. One report per SHA; reruns overwrite the SHA-named report. - -Manual rerun/backfill: - -```bash -gh workflow run commit-review.yml --repo openclaw/clawsweeper \ - -f target_repo=openclaw/openclaw \ - -f commit_sha= \ - -f before_sha= \ - -f create_checks=false \ - -f enabled=true -``` - -Use `create_checks=true` only when the requester explicitly wants target commit Check -Runs. Add `-f additional_prompt="..."` for focused one-off review instructions. +Hosted per-commit reports and commit Check Runs are retired. For the retained +offline review of a committed branch, use `pnpm local-review -- --base main`. +`$autoreview --mode commit --commit ` remains a separate general-purpose +review path. ## Sweep Reports @@ -303,11 +274,13 @@ prose. Receiver workflows: ```bash -gh run list --repo openclaw/clawsweeper --workflow "ClawSweeper Commit Review" \ +gh run list --repo openclaw/clawsweeper --workflow sweep.yml \ --limit 12 --json databaseId,displayTitle,event,status,conclusion,createdAt,updatedAt,url -gh run list --repo openclaw/clawsweeper --workflow "repair cluster worker" \ +gh run list --repo openclaw/clawsweeper --workflow repair-cluster-worker.yml \ --limit 12 --json databaseId,displayTitle,event,status,conclusion,createdAt,updatedAt,url -gh run list --repo openclaw/clawsweeper --workflow "repair comment router" \ +gh run list --repo openclaw/clawsweeper --workflow repair-comment-router.yml \ + --limit 12 --json databaseId,displayTitle,event,status,conclusion,createdAt,updatedAt,url +gh run list --repo openclaw/clawsweeper --workflow github-activity.yml \ --limit 12 --json databaseId,displayTitle,event,status,conclusion,createdAt,updatedAt,url ``` @@ -315,21 +288,14 @@ Target dispatcher: ```bash gh run list --repo openclaw/openclaw --workflow "ClawSweeper Dispatch" \ - --event push --limit 8 --json databaseId,displayTitle,event,status,conclusion,headSha,url -``` - -Target commit check: - -```bash -gh api "repos/openclaw/openclaw/commits//check-runs?per_page=100" \ - --jq '.check_runs[] | select(.name=="ClawSweeper Commit Review") | [.status,.conclusion,.details_url] | @tsv' + --limit 8 --json databaseId,displayTitle,event,status,conclusion,headSha,url ``` ## Reading Output For findings or failures, summarize: -- target repo, item/PR/commit, run, report path +- target repo, item/PR, run, report path - result, confidence, severity, and exact blocker - affected files or cluster refs - validation commands and whether they passed diff --git a/.agents/skills/clawsweeper/agents/openai.yaml b/.agents/skills/clawsweeper/agents/openai.yaml index fdde4e3750b5..c8a24ebdfb32 100644 --- a/.agents/skills/clawsweeper/agents/openai.yaml +++ b/.agents/skills/clawsweeper/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "ClawSweeper" - short_description: "Inspect ClawSweeper commit review reports and Actions runs." - default_prompt: "Review recent ClawSweeper commit reports and summarize findings." + short_description: "Inspect ClawSweeper issue/PR reports, queue health, and Actions runs." + default_prompt: "Review recent ClawSweeper issue/PR reports, queue health, and Actions runs." diff --git a/.github/workflows/clawsweeper-dispatch.yml b/.github/workflows/clawsweeper-dispatch.yml index 786a1e3342a7..68c8676b196c 100644 --- a/.github/workflows/clawsweeper-dispatch.yml +++ b/.github/workflows/clawsweeper-dispatch.yml @@ -318,37 +318,3 @@ jobs: else echo "::warning::Skipping ClawSweeper comment dispatch because the configured credential could not dispatch to openclaw/clawsweeper." fi - - - name: Dispatch ClawSweeper commit review - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.event.deleted != true }} - env: - GH_TOKEN: ${{ steps.token.outputs.token }} - TARGET_REPO: ${{ github.repository }} - BEFORE_SHA: ${{ github.event.before }} - AFTER_SHA: ${{ github.sha }} - SOURCE_REF: ${{ github.ref }} - CREATE_CHECKS: ${{ vars.CLAWSWEEPER_COMMIT_REVIEW_CREATE_CHECKS || 'false' }} - run: | - if [ -z "$GH_TOKEN" ]; then - echo "::notice::Skipping ClawSweeper commit dispatch because no ClawSweeper app token is configured. Not falling back to a maintainer token." - exit 0 - fi - . "$RUNNER_TEMP/github-api-backoff.sh" - case "$CREATE_CHECKS" in - true|TRUE|1|yes|YES|on|ON) create_checks=true ;; - *) create_checks=false ;; - esac - payload="$(jq -nc \ - --arg target_repo "$TARGET_REPO" \ - --arg before_sha "$BEFORE_SHA" \ - --arg after_sha "$AFTER_SHA" \ - --arg ref "$SOURCE_REF" \ - --argjson create_checks "$create_checks" \ - '{event_type:"clawsweeper_commit_review",client_payload:{target_repo:$target_repo,before_sha:$before_sha,after_sha:$after_sha,ref:$ref,enabled:true,create_checks:$create_checks}}')" - if gh_api_with_retry repos/openclaw/clawsweeper/dispatches \ - --method POST \ - --input - <<< "$payload"; then - echo "Dispatched ClawSweeper commit review." - else - echo "::warning::Skipping ClawSweeper commit dispatch because the configured credential could not dispatch to openclaw/clawsweeper." - fi diff --git a/docs/ci.md b/docs/ci.md index 1ff042373957..cc1b5687d54a 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -139,15 +139,16 @@ The `check-dependencies` shard runs production Knip dependency, unused-file, and `.github/workflows/clawsweeper-dispatch.yml` is the target-side bridge from OpenClaw repository activity into ClawSweeper. It does not check out or execute untrusted pull request code. The workflow creates a GitHub App token from `CLAWSWEEPER_APP_PRIVATE_KEY`, then dispatches compact `repository_dispatch` payloads to `openclaw/clawsweeper`. -The workflow has four lanes: +The workflow has three lanes: - `clawsweeper_item` for exact issue and pull request review requests; - `clawsweeper_comment` for explicit ClawSweeper commands in issue comments; -- `clawsweeper_commit_review` for commit-level review requests on `main` pushes; - `github_activity` for general GitHub activity that the ClawSweeper agent may inspect. The `github_activity` lane forwards normalized metadata only: event type, action, actor, repository, item number, URL, title, state, and short excerpts for comments or reviews when present. It intentionally avoids forwarding the full webhook body. The receiving workflow in `openclaw/clawsweeper` is `.github/workflows/github-activity.yml`, which posts the normalized event to the OpenClaw Gateway hook for the ClawSweeper agent. +Main pushes remain `github_activity` observations. They do not produce hosted per-commit reports or commit Check Runs. + General activity is observation, not delivery-by-default. The ClawSweeper agent receives the Discord target in its prompt and should post to `#clawsweeper` only when the event is surprising, actionable, risky, or operationally useful. Routine opens, edits, bot churn, duplicate webhook noise, and normal review traffic should result in `NO_REPLY`. Treat GitHub titles, comments, bodies, review text, branch names, and commit messages as untrusted data throughout this path. They are input for summarization and triage, not instructions for the workflow or agent runtime. diff --git a/test/scripts/ci-workflow-guards.test.ts b/test/scripts/ci-workflow-guards.test.ts index 8e42ec87b58c..fc256f986b28 100644 --- a/test/scripts/ci-workflow-guards.test.ts +++ b/test/scripts/ci-workflow-guards.test.ts @@ -1062,6 +1062,39 @@ NODE }); }); + it("keeps ClawSweeper dispatch events aligned with receiver workflows", () => { + const workflowPath = ".github/workflows/clawsweeper-dispatch.yml"; + const source = readFileSync(workflowPath, "utf8"); + const workflow = readWorkflow(workflowPath); + const steps = workflow.jobs.dispatch.steps as WorkflowStep[]; + const receiverDispatchSteps = steps.filter((step) => + step.run?.includes("repos/openclaw/clawsweeper/dispatches"), + ); + const eventTypes = receiverDispatchSteps.map((step) => { + const matches = [...(step.run ?? "").matchAll(/\bevent_type\s*:\s*"([^"]+)"/gu)]; + expect(matches, step.name).toHaveLength(1); + return expectDefined(matches[0]?.[1], step.name ?? "ClawSweeper dispatch event"); + }); + + // This allowlist mirrors the target repository receiver contract; changes require coordinated receiver updates. + expect(eventTypes.toSorted()).toEqual([ + "clawsweeper_comment", + "clawsweeper_item", + "github_activity", + ]); + expect(source).not.toContain("clawsweeper_commit_review"); + expect(source).not.toContain("CLAWSWEEPER_COMMIT_REVIEW_CREATE_CHECKS"); + expect(workflow.on.push.branches).toEqual(["main"]); + + const activityRun = expectDefined( + steps.find((step) => step.name === "Dispatch GitHub activity to ClawSweeper")?.run, + "ClawSweeper GitHub activity dispatch", + ); + expect(activityRun).toMatch( + /push: \(if \$event_name == "push" then \{\s+before: \.before,\s+after: \.after,\s+ref: \.ref,\s+compare: \.compare,\s+head_commit: \.head_commit\.id\s+\} else null end\)/u, + ); + }); + it("runs the PR context and evidence gate only for relevant PR changes", () => { const workflow = readRealBehaviorProofWorkflow();